diff --git a/.github/workflows/test.yml-template b/.github/workflows/test.yml-template new file mode 100644 index 0000000..bb13dfc --- /dev/null +++ b/.github/workflows/test.yml-template @@ -0,0 +1,23 @@ +name: Test + +on: + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test diff --git a/package-lock.json b/package-lock.json index 2a93237..60ddc72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "devDependencies": { "@faker-js/faker": "^8.4.1", "@mate-academy/eslint-config": "latest", - "@mate-academy/scripts": "^1.8.6", + "@mate-academy/scripts": "^2.1.3", "eslint": "^8.57.0", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-node": "^11.1.0", @@ -1484,10 +1484,11 @@ } }, "node_modules/@mate-academy/scripts": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.8.6.tgz", - "integrity": "sha512-b4om/whj4G9emyi84ORE3FRZzCRwRIesr8tJHXa8EvJdOaAPDpzcJ8A0sFfMsWH9NUOVmOwkBtOXDu5eZZ00Ig==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-2.1.3.tgz", + "integrity": "sha512-a07wHTj/1QUK2Aac5zHad+sGw4rIvcNl5lJmJpAD7OxeSbnCdyI6RXUHwXhjF5MaVo9YHrJ0xVahyERS2IIyBQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/rest": "^17.11.2", "@types/get-port": "^4.2.0", diff --git a/package.json b/package.json index f8c126f..c27ea01 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "devDependencies": { "@faker-js/faker": "^8.4.1", "@mate-academy/eslint-config": "latest", - "@mate-academy/scripts": "^1.8.6", + "@mate-academy/scripts": "^2.1.3", "eslint": "^8.57.0", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-node": "^11.1.0", diff --git a/src/app.js b/src/app.js index 0d15e7b..3805e8d 100644 --- a/src/app.js +++ b/src/app.js @@ -1 +1,66 @@ -// write code here +/* eslint-disable no-console */ +'use strict'; + +const fs = require('fs/promises'); +const path = require('path'); + +const [, , source, dest] = process.argv; + +if (!source) { + console.error('Please provide source path'); +} + +if (!dest) { + console.error('Please provide destination path'); +} + +if (source === dest) { + process.exit(0); +} + +(async () => { + try { + const srcStat = await fs.stat(source); + + if (!srcStat.isFile()) { + console.error('Source is not a file'); + } + + let target = dest; + + if (dest.endsWith('/')) { + const dirStat = await fs.stat(dest); + + if (!dirStat.isDirectory()) { + console.error('Destination directory does not exist'); + } + + target = path.join(dest, path.basename(source)); + } else { + try { + const destStat = await fs.stat(dest); + + if (destStat.isDirectory()) { + target = path.join(dest, path.basename(source)); + } + } catch { + const parentDir = path.dirname(dest); + + try { + const parentStat = await fs.stat(parentDir); + + if (!parentStat.isDirectory()) { + console.error('Destination directory does not exist'); + } + } catch { + console.error('Destination directory does not exist'); + } + } + } + + await fs.rename(source, target); + console.log(`File moved from "${source}" to "${target}"`); + } catch (err) { + console.error(err.message); + } +})(); diff --git a/tests/commercial/authentic_drafty.txt b/tests/commercial/authentic_drafty.txt new file mode 100644 index 0000000..8f609af --- /dev/null +++ b/tests/commercial/authentic_drafty.txt @@ -0,0 +1,3 @@ +Numquam universe avarus. Cariosus articulus aliquid. Terra defendo caelestis trado una cupiditas absconditus agnitio depopulo ubi. +Sophismata coniuratio bellicus comptus confido thymbra voluptatibus. Spiritus solum quo cicuta curo terga abutor cupiditas accedo. Vulnero velociter coepi coaegresco itaque atrox sursum colo thesis terra. +Bonus consequatur comptus adstringo asporto tardus. Vis xiphias argentum veritatis beatae attonbitus labore causa terror cursus. Verbera suspendo patior degusto ago articulus. \ No newline at end of file diff --git a/tests/moveFiles.test.js b/tests/moveFiles.test.js index d06c0a3..88a61b1 100644 --- a/tests/moveFiles.test.js +++ b/tests/moveFiles.test.js @@ -35,7 +35,7 @@ describe('File Move Tests', () => { }); describe('without params', () => { - test('should throw error', async() => { + test('should throw error', async () => { const { stderr } = await execAsync(basePath); expect(stderr.length).toBeGreaterThan(0); @@ -43,7 +43,7 @@ describe('File Move Tests', () => { }); describe('with one param', () => { - test('should throw error', async() => { + test('should throw error', async () => { const { stderr } = await execAsync(`${basePath} ${testFilePath}`); expect(stderr.length).toBeGreaterThan(0); @@ -51,18 +51,25 @@ describe('File Move Tests', () => { }); describe('with two params', () => { - test('if source file does not exist, should throw error', async() => { - const nonExistingFile = path.join(tempDir, faker.system.commonFileName('txt')); + test('if source file does not exist, should throw error', async () => { + const nonExistingFile = path.join( + tempDir, + faker.system.commonFileName('txt'), + ); - const { stderr } = await execAsync(`${basePath} ${nonExistingFile} ${testFilePath}`); + const { stderr } = await execAsync( + `${basePath} ${nonExistingFile} ${testFilePath}`, + ); expect(stderr.length).toBeGreaterThan(0); }); - test('should rename a file, if destination is a new filename', async() => { + test('should rename a file, if destination is a new filename', async () => { const newFilePath = path.join(tempDir, faker.lorem.word()); - const { stderr } = await execAsync(`${basePath} ${testFilePath} ${newFilePath}`); + const { stderr } = await execAsync( + `${basePath} ${testFilePath} ${newFilePath}`, + ); expect(stderr).toBeFalsy(); @@ -73,8 +80,10 @@ describe('File Move Tests', () => { expect(content).toBe(testContent); }); - test('should do nothing if source and destination are the same', async() => { - const { stderr } = await execAsync(`${basePath} ${testFilePath} ${testFilePath}`); + test('should do nothing if source and destination are the same', async () => { + const { stderr } = await execAsync( + `${basePath} ${testFilePath} ${testFilePath}`, + ); const content = fs.readFileSync(testFilePath, 'utf-8'); @@ -83,19 +92,23 @@ describe('File Move Tests', () => { expect(content).toBe(testContent); }); - test('should move file, if passed destination is a file without extension', async() => { + test('should move file, if passed destination is a file without extension', async () => { const newFilePath = path.join(tempDir, faker.lorem.word()); - const { stderr } = await execAsync(`${basePath} ${testFilePath} ${newFilePath}`); + const { stderr } = await execAsync( + `${basePath} ${testFilePath} ${newFilePath}`, + ); expect(stderr).toBeFalsy(); expect(fs.existsSync(newFilePath)).toBe(true); expect(fs.existsSync(testFilePath)).toBe(false); }); - test('should move file, if passed destination is a directory', async() => { + test('should move file, if passed destination is a directory', async () => { fs.mkdirSync(testDir); - const { stderr } = await execAsync(`${basePath} ${testFilePath} ${testDir}`); + const { stderr } = await execAsync( + `${basePath} ${testFilePath} ${testDir}`, + ); expect(stderr).toBeFalsy(); @@ -107,11 +120,15 @@ describe('File Move Tests', () => { expect(content).toBe(testContent); }); - test('should throw error if destination directory does not exist', async() => { - const nonExistingDir = path.join(tempDir, 'nonExistingDir', faker.word.noun()); + test('should throw error if destination directory does not exist', async () => { + const nonExistingDir = path.join( + tempDir, + 'nonExistingDir', + faker.word.noun(), + ); const { stderr } = await execAsync( - `${basePath} ${testFilePath} ${nonExistingDir}` + `${basePath} ${testFilePath} ${nonExistingDir}`, ); expect(stderr.length).toBeGreaterThan(0); @@ -119,11 +136,15 @@ describe('File Move Tests', () => { expect(fs.existsSync(testFilePath)).toBe(true); }); - test('should throw error if destination is non-existed directory with fileName', async() => { - const nonExistingDir = path.join(tempDir, 'nonExistingDir', faker.word.noun()); + test('should throw error if destination is non-existed directory with fileName', async () => { + const nonExistingDir = path.join( + tempDir, + 'nonExistingDir', + faker.word.noun(), + ); const { stderr } = await execAsync( - `${basePath} ${testFilePath} ${nonExistingDir}` + `${basePath} ${testFilePath} ${nonExistingDir}`, ); expect(stderr.length).toBeGreaterThan(0); @@ -131,7 +152,7 @@ describe('File Move Tests', () => { expect(fs.existsSync(testFilePath)).toBe(true); }); - test('should move file to directory path ending with "/" with the same filename', async() => { + test('should move file to directory path ending with "/" with the same filename', async () => { fs.mkdirSync(testDir); const newPath = path.join(testDir, '/');