forked from nestjs/nest-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
445 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
coverage/ | ||
node_modules/ | ||
src/ | ||
scripts/ | ||
|
||
.gitignore | ||
.travis.yml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import {Clean} from './lib/clean'; | ||
|
||
console.log('Start to clean...'); | ||
Clean.execute(process.argv) | ||
.then(() => { | ||
console.log('Succeed to clean'); | ||
}) | ||
.catch(error => { | ||
console.log('Failed to clean with error\n', error); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import {Copy} from './lib/copy'; | ||
|
||
console.log('Start to copy...'); | ||
Copy.execute(process.argv) | ||
.then(() => { | ||
console.log('Succeed to copy'); | ||
}) | ||
.catch(error => { | ||
console.log('Failed to copy with error\n', error); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import {FileSystemUtils} from '../../src/core/utils/file-system.utils'; | ||
import * as os from 'os'; | ||
import * as path from 'path'; | ||
|
||
export class Clean { | ||
public static execute(args: string[]): Promise<void[]> { | ||
return this.extractFileNames(args) | ||
.then(fileNames => Promise.all(fileNames.map(filename => this.clean(filename)))); | ||
} | ||
|
||
private static extractFileNames(args: string[]): Promise<string[]> { | ||
if (os.platform() === 'win32') | ||
return this.extractWin32PlatformFiles(args); | ||
else | ||
return Promise.resolve(args.slice(2, args.length)); | ||
} | ||
|
||
private static extractWin32PlatformFiles(args: string[]): Promise<string[]> { | ||
const dirname: string = args[2].replace('*', ''); | ||
return FileSystemUtils.readdir(dirname) | ||
.then(fileNames => fileNames.map(filename => path.join(dirname, filename))); | ||
} | ||
|
||
private static clean(filename: string): Promise<void> { | ||
return FileSystemUtils.stat(filename) | ||
.then(fileStat => { | ||
if (fileStat.isFile()) | ||
return FileSystemUtils.rm(filename); | ||
else | ||
return FileSystemUtils.rmdir(filename); | ||
}) | ||
.then(() => { | ||
console.log(` ${ filename } deleted`); | ||
}) | ||
.catch(error => { | ||
console.log(` ${ filename } not be deleted`); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import * as fs from 'fs'; | ||
import {ReadStream, WriteStream} from 'fs'; | ||
import {FileSystemUtils} from '../../src/core/utils/file-system.utils'; | ||
import * as path from 'path'; | ||
|
||
export class Copy { | ||
public static execute(argv: string[]): Promise<void> { | ||
const origin: string = argv[2]; | ||
const destination: string = argv[3]; | ||
return this.copy(origin, destination); | ||
} | ||
|
||
private static copy(origin: string, destination: string) { | ||
return FileSystemUtils.stat(origin) | ||
.then(fileStat => { | ||
if (fileStat.isFile()) | ||
return this.copyFile(origin, destination); | ||
else | ||
return this.copyDirectory(origin, destination); | ||
}); | ||
} | ||
|
||
private static copyFile(origin: string, destination: string): Promise<void> { | ||
console.log(` copy ${ origin } \n to ${ destination }`); | ||
return new Promise<void>((resolve, reject) => { | ||
const reader: ReadStream = fs.createReadStream(origin); | ||
const writer: WriteStream = fs.createWriteStream(destination); | ||
reader.pipe(writer); | ||
reader.on('end', resolve); | ||
reader.on('error', reject); | ||
}); | ||
} | ||
|
||
private static copyDirectory(origin: string, destination: string): Promise<void> { | ||
return FileSystemUtils.readdir(origin) | ||
.then(files => { | ||
return FileSystemUtils.mkdir(destination) | ||
.then(() => Promise.all( | ||
files.map(file => this.copy(path.join(origin, file), path.join(destination, file))) | ||
)); | ||
}) | ||
.then(() => {}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import * as sinon from 'sinon'; | ||
import {FileSystemUtils} from '../../../src/core/utils/file-system.utils'; | ||
import {Clean} from '../clean'; | ||
import * as os from 'os'; | ||
import * as path from 'path'; | ||
|
||
describe('Clean', () => { | ||
let sandbox: sinon.SinonSandbox; | ||
beforeEach(() => sandbox = sinon.sandbox.create()); | ||
afterEach(() => sandbox.restore()); | ||
|
||
let statStub: sinon.SinonStub; | ||
let rmStub: sinon.SinonStub; | ||
let rmdirStub: sinon.SinonStub; | ||
let readdirStub: sinon.SinonStub; | ||
let platformStub: sinon.SinonStub; | ||
beforeEach(() => { | ||
statStub = sandbox.stub(FileSystemUtils, 'stat'); | ||
rmStub = sandbox.stub(FileSystemUtils, 'rm'); | ||
rmdirStub = sandbox.stub(FileSystemUtils, 'rmdir'); | ||
readdirStub = sandbox.stub(FileSystemUtils, 'readdir'); | ||
platformStub = sandbox.stub(os, 'platform'); | ||
}); | ||
|
||
describe('#execute()', () => { | ||
context('Unix platform', () => { | ||
const argv: string[] = [ 'node_process_call', 'script_call', 'filename1', 'filename2', 'filename3' ]; | ||
|
||
beforeEach(() => { | ||
platformStub.callsFake(() => 'unix'); | ||
}); | ||
|
||
it('should call stat per file', () => { | ||
statStub.callsFake(() => Promise.resolve({ | ||
isFile: () => true | ||
})); | ||
return Clean.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledThrice(statStub); | ||
sinon.assert.calledWith(statStub, 'filename1'); | ||
sinon.assert.calledWith(statStub, 'filename2'); | ||
sinon.assert.calledWith(statStub, 'filename3'); | ||
}); | ||
}); | ||
|
||
it('should call rm on files', () => { | ||
statStub.callsFake(() => Promise.resolve({ | ||
isFile: () => true | ||
})); | ||
rmStub.callsFake(() => Promise.resolve()); | ||
return Clean.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledThrice(rmStub); | ||
sinon.assert.calledWith(rmStub, 'filename1'); | ||
sinon.assert.calledWith(rmStub, 'filename2'); | ||
sinon.assert.calledWith(rmStub, 'filename3'); | ||
}); | ||
}); | ||
|
||
it('should call rmdir on directories', () => { | ||
rmdirStub.callsFake(() => Promise.resolve()); | ||
statStub.callsFake(() => Promise.resolve({ | ||
isFile: () => false | ||
})); | ||
return Clean.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledThrice(rmdirStub); | ||
sinon.assert.calledWith(rmdirStub, 'filename1'); | ||
sinon.assert.calledWith(rmdirStub, 'filename2'); | ||
sinon.assert.calledWith(rmdirStub, 'filename3'); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
context('win32 platform', () => { | ||
const argv: string[] = [ 'node_process_call', 'script_call', 'directory/*' ]; | ||
beforeEach(() => { | ||
platformStub.callsFake(() => 'win32'); | ||
rmdirStub.callsFake(() => Promise.resolve()); | ||
rmStub.callsFake(() => Promise.resolve()); | ||
readdirStub.callsFake(() => Promise.resolve([ | ||
'filename1', | ||
'filename2', | ||
'filename3' | ||
])); | ||
}); | ||
|
||
it('should extract files from directory', () => { | ||
statStub.callsFake(() => Promise.resolve({ | ||
isFile: () => false | ||
})); | ||
return Clean.execute(argv) | ||
.then(() => { | ||
sinon.assert.called(readdirStub); | ||
}); | ||
}); | ||
|
||
it('should remove * on win32 platform', () => { | ||
statStub.callsFake(() => Promise.resolve({ | ||
isFile: () => true | ||
})); | ||
|
||
return Clean.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledThrice(statStub); | ||
sinon.assert.calledWith(statStub, path.join('directory', 'filename1')); | ||
sinon.assert.calledWith(statStub, path.join('directory', 'filename2')); | ||
sinon.assert.calledWith(statStub, path.join('directory', 'filename3')); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import {Copy} from '../copy'; | ||
import * as sinon from 'sinon'; | ||
import * as fs from 'fs'; | ||
import {PassThrough} from 'stream'; | ||
import {FileSystemUtils} from '../../../src/core/utils/file-system.utils'; | ||
import * as path from 'path'; | ||
|
||
describe('Copy', () => { | ||
let sandbox: sinon.SinonSandbox; | ||
beforeEach(() => sandbox = sinon.sandbox.create()); | ||
afterEach(() => sandbox.restore()); | ||
|
||
let statStub: sinon.SinonStub; | ||
let createReadStreamStub: sinon.SinonStub; | ||
let createWriteStreamStub: sinon.SinonStub; | ||
let pipeSpy: sinon.SinonSpy; | ||
let readdirStub: sinon.SinonStub; | ||
let mkdirStub: sinon.SinonStub; | ||
beforeEach(() => { | ||
statStub = sandbox.stub(FileSystemUtils, 'stat'); | ||
createReadStreamStub = sandbox.stub(fs, 'createReadStream').callsFake(() => { | ||
const reader = new PassThrough(); | ||
reader.end(); | ||
return reader; | ||
}); | ||
createWriteStreamStub = sandbox.stub(fs, 'createWriteStream').callsFake(() => new PassThrough()); | ||
pipeSpy = sandbox.spy(PassThrough.prototype, 'pipe'); | ||
readdirStub = sandbox.stub(FileSystemUtils, 'readdir'); | ||
mkdirStub = sandbox.stub(FileSystemUtils, 'mkdir').callsFake(() => Promise.resolve()); | ||
}); | ||
|
||
describe('#execute()', () => { | ||
const argv: string[] = [ 'node_process_call', 'script_call', 'origin', 'destination' ]; | ||
|
||
it('should evaluate if origin is a file', () => { | ||
statStub.callsFake(() => Promise.resolve({ | ||
isFile: () => true | ||
})); | ||
return Copy.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledWith(statStub, 'origin'); | ||
}); | ||
}); | ||
|
||
context('origin is a file', () => { | ||
beforeEach(() => { | ||
statStub.callsFake(() => Promise.resolve({ | ||
isFile: () => true | ||
})); | ||
}); | ||
|
||
it('should open an input stream on origin file', () => { | ||
return Copy.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledWith(createReadStreamStub, 'origin'); | ||
}); | ||
}); | ||
|
||
it('should open an output stream to destination file', () => { | ||
return Copy.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledWith(createWriteStreamStub, 'destination'); | ||
}); | ||
}); | ||
|
||
it('should pipe origin to destination', () => { | ||
return Copy.execute(argv) | ||
.then(() => { | ||
sinon.assert.called(pipeSpy); | ||
}); | ||
}); | ||
}); | ||
|
||
context('origin is directory', () => { | ||
beforeEach(() => { | ||
statStub.callsFake(filename => { | ||
if (filename === 'origin') | ||
return Promise.resolve({ | ||
isFile: () => false | ||
}); | ||
else | ||
return Promise.resolve({ | ||
isFile: () => true | ||
}); | ||
}); | ||
readdirStub.callsFake(() => Promise.resolve([ | ||
'filename1', | ||
'filename2', | ||
'filename3', | ||
])); | ||
}); | ||
|
||
it('should read the directory', () => { | ||
return Copy.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledWith(readdirStub, 'origin'); | ||
}); | ||
}); | ||
|
||
it('should copy each files in the directory to the destination', () => { | ||
return Copy.execute(argv) | ||
.then(() => { | ||
sinon.assert.calledThrice(createReadStreamStub); | ||
sinon.assert.calledWith(createReadStreamStub, path.join('origin', 'filename1')); | ||
sinon.assert.calledWith(createReadStreamStub, path.join('origin', 'filename2')); | ||
sinon.assert.calledWith(createReadStreamStub, path.join('origin', 'filename3')); | ||
sinon.assert.calledThrice(createWriteStreamStub); | ||
sinon.assert.calledWith(createWriteStreamStub, path.join('destination', 'filename1')); | ||
sinon.assert.calledWith(createWriteStreamStub, path.join('destination', 'filename2')); | ||
sinon.assert.calledWith(createWriteStreamStub, path.join('destination', 'filename3')); | ||
sinon.assert.calledThrice(pipeSpy); | ||
}); | ||
}); | ||
}); | ||
|
||
context('origin contains sub directories', () => { | ||
beforeEach(() => { | ||
statStub.callsFake(filename => { | ||
if (filename === 'origin' || filename === 'origin/directory') | ||
return Promise.resolve({ | ||
isFile: () => false | ||
}); | ||
else | ||
return Promise.resolve({ | ||
isFile: () => true | ||
}); | ||
}); | ||
readdirStub.callsFake(filename => { | ||
if (filename === 'origin') | ||
return Promise.resolve([ 'directory' ]); | ||
else | ||
return Promise.resolve([ 'filename']); | ||
}); | ||
}); | ||
|
||
it('create the intermediate directory before copy file', () => { | ||
return Copy.execute(argv) | ||
.then(() => { | ||
sinon.assert.called(mkdirStub); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.