Merge pull request #32402 from TeamworkGuy2/master

[vinyl-fs] Add v0.3 and v1.0, remove watch() to match v2.4
This commit is contained in:
Benjamin Lichtman
2019-01-29 09:34:26 -08:00
committed by GitHub
13 changed files with 2111 additions and 182 deletions
-3
View File
@@ -1,3 +0,0 @@
[*.ts]
indent_style = space
indent_size = 3
+130 -156
View File
@@ -2,16 +2,17 @@
// Project: https://github.com/wearefractal/vinyl-fs
// Definitions by: vvakame <https://github.com/vvakame>
// remisery <https://github.com/remisery>
// TeamworkGuy2 <https://github.com/TeamworkGuy2>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="node" />
declare global {
namespace NodeJS {
interface WritableStream {
write(buffer: any/* Vinyl.File */, cb?: (err?: Error | null) => void): boolean;
}
}
namespace NodeJS {
interface WritableStream {
write(buffer: any/* Vinyl.File */, cb?: (err?: Error | null) => void): boolean;
}
}
}
import * as _events from 'events';
@@ -19,128 +20,128 @@ import * as File from 'vinyl';
import * as globStream from 'glob-stream';
export interface SrcOptions extends globStream.Options {
/** Prevents stream from emitting an error when file not found. */
allowEmpty?: boolean;
/** Prevents stream from emitting an error when file not found. */
allowEmpty?: boolean;
/** Specifies the working directory the folder is relative to */
cwd?: string;
/** Specifies the working directory the folder is relative to */
cwd?: string;
/**
* Specifies the folder relative to the cwd
* This is used to determine the file names when saving in .dest()
* Default: where the glob begins
*/
base?: string;
/**
* Specifies the folder relative to the cwd
* This is used to determine the file names when saving in .dest()
* Default: where the glob begins
*/
base?: string;
/**
* Setting this to false will make file.contents a paused stream
* If true it will buffer the file contents
* Default: true
*/
buffer?: boolean;
/**
* Setting this to false will make file.contents a paused stream
* If true it will buffer the file contents
* Default: true
*/
buffer?: boolean;
/**
* The mode the directory should be created with.
* Default: the process mode
*/
dirMode?: number;
/**
* The mode the directory should be created with.
* Default: the process mode
*/
dirMode?: number;
/**
* Whether or not you want globs to match on dot files or not
* (e.g., `.gitignore`).
*/
dot?: boolean;
/**
* Whether or not you want globs to match on dot files or not
* (e.g., `.gitignore`).
*/
dot?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets.
* Setting to `false` to preserve them as symlinks and make `file.symlink`
* equal the original symlink's target path.
* Default: true
*/
followSymlinks?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets.
* Setting to `false` to preserve them as symlinks and make `file.symlink`
* equal the original symlink's target path.
* Default: true
*/
followSymlinks?: boolean;
/**
* Setting this to false will ignore the contents of the file and disable
* writing to disk to speed up operations
* Default: true
*/
read?: boolean;
/**
* Setting this to false will ignore the contents of the file and disable
* writing to disk to speed up operations
* Default: true
*/
read?: boolean;
/**
* Whether or not the symlink should be relative or absolute.
* Default: false
*/
relative?: boolean;
/**
* Whether or not the symlink should be relative or absolute.
* Default: false
*/
relative?: boolean;
/** Only find files that have been modified since the time specified */
since?: Date|number;
/** Only find files that have been modified since the time specified */
since?: Date | number;
/**
* Causes the BOM to be stripped on UTF-8 encoded files. Set to `false`
* if you need the BOM for some reason.
*/
stripBOM?: boolean;
/**
* Causes the BOM to be stripped on UTF-8 encoded files. Set to `false`
* if you need the BOM for some reason.
*/
stripBOM?: boolean;
/**
* Setting this to true will create a duplex stream, one that passes
* through items and emits globbed files.
* Default: false
*/
passthrough?: boolean;
/**
* Setting this to true will create a duplex stream, one that passes
* through items and emits globbed files.
* Default: false
*/
passthrough?: boolean;
/**
* Setting this to true will enable sourcemaps.
* Default: false
*/
sourcemaps?: boolean;
/**
* Setting this to true will enable sourcemaps.
* Default: false
*/
sourcemaps?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets. Setting to false to
* preserve them as symlinks and make file.symlink equal the original symlink's target path.
* Default: false
*/
resolveSymlinks?: boolean;
/**
* Causes the BOM to be removed on UTF-8 encoded files. Set to false if you need the BOM for some reason.
* Default: true
*/
removeBOM?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets. Setting to false to
* preserve them as symlinks and make file.symlink equal the original symlink's target path.
* Default: false
*/
resolveSymlinks?: boolean;
/**
* Causes the BOM to be removed on UTF-8 encoded files. Set to false if you need the BOM for some reason.
* Default: true
*/
removeBOM?: boolean;
}
export interface DestOptions {
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/**
* Specify the mode the files should be created with
* Default is the mode of the input file (file.stat.mode)
* or the process mode if the input file has no mode property
*/
mode?: number|string;
/**
* Specify the mode the files should be created with
* Default is the mode of the input file (file.stat.mode)
* or the process mode if the input file has no mode property
*/
mode?: number | string;
/** Specify the mode the directory should be created with. Default is the process mode */
dirMode?: number|string;
/** Specify the mode the directory should be created with. Default is the process mode */
dirMode?: number | string;
/** Specify if existing files with the same path should be overwritten or not. Default is true, to always overwrite existing files */
overwrite?: boolean;
/** Specify if existing files with the same path should be overwritten or not. Default is true, to always overwrite existing files */
overwrite?: boolean;
/**
* Enables sourcemap support on files passed through the stream. Will write inline soucemaps if
* specified as true. Specifying a string path will write external sourcemaps at the given path.
*/
sourcemaps?: true | string;
/**
* Enables sourcemap support on files passed through the stream. Will write inline soucemaps if
* specified as true. Specifying a string path will write external sourcemaps at the given path.
*/
sourcemaps?: true | string;
/**
* When creating a symlink, whether or not the created symlink should be relative. If false,
* the symlink will be absolute. Note: This option will be ignored if a junction is being created.
*/
relativeSymlinks?: boolean;
/**
* When creating a symlink, whether or not the created symlink should be relative. If false,
* the symlink will be absolute. Note: This option will be ignored if a junction is being created.
*/
relativeSymlinks?: boolean;
/* When creating a symlink, whether or not a directory symlink should be created as a junction. */
useJunctions?: boolean;
/* When creating a symlink, whether or not a directory symlink should be created as a junction. */
useJunctions?: boolean;
}
/**
@@ -152,32 +153,6 @@ export interface DestOptions {
*/
export function src(globs: string|string[], opt?: SrcOptions): NodeJS.ReadWriteStream;
/**
* This is just a glob-watcher
*
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
*/
export function watch(globs: string|string[], cb?: (outEvt: { type: any; path: any; old: any; }) => void): _events.EventEmitter;
/**
* This is just a glob-watcher
*
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
*/
export function watch(
globs: string|string[],
opt?: {
interval?: number;
debounceDelay?: number;
cwd?: string;
maxListeners?(): number;
},
cb?: (outEvt: { type: any; path: any; old: any; }) => void): _events.EventEmitter;
/**
* On write the stream will save the vinyl File to disk at the folder/cwd specified.
* After writing the file to disk, it will be emitted from the stream so you can keep piping these around.
@@ -207,20 +182,20 @@ export function dest(getFolderPath: (file: File) => string): NodeJS.ReadWriteStr
* cwd, base, and path will be overwritten to match the folder
*/
export function symlink(folder: string, opts?: {
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/** Specify the mode the directory should be created with. Default is the process mode */
mode?: number|string;
/** Specify the mode the directory should be created with. Default is the process mode */
mode?: number | string;
/**
* Specify the mode the directory should be created with
* Default is the process mode
*/
dirMode?: number
/**
* Specify the mode the directory should be created with
* Default is the process mode
*/
dirMode?: number
}): NodeJS.ReadWriteStream;
/**
@@ -229,17 +204,16 @@ export function symlink(folder: string, opts?: {
* The file will be modified after being written to this stream:
* cwd, base, and path will be overwritten to match the folder
*/
export function symlink(getFolderPath: (File: File) => string, opts?:
{
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
export function symlink(getFolderPath: (File: File) => string, opts?: {
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/**
* Specify the mode the directory should be created with
* Default is the process mode
*/
dirMode?: number
}): NodeJS.ReadWriteStream;
/**
* Specify the mode the directory should be created with
* Default is the process mode
*/
dirMode?: number
}): NodeJS.ReadWriteStream;
+2 -2
View File
@@ -5,8 +5,8 @@
"es6"
],
"noImplicitAny": true,
"noImplicitThis": false,
"strictNullChecks": false,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
+1 -4
View File
@@ -1,6 +1,3 @@
{
"extends": "dtslint/dt.json",
"rules": {
"no-object-literal-type-assertion": false
}
"extends": "dtslint/dt.json"
}
+201
View File
@@ -0,0 +1,201 @@
// Type definitions for vinyl-fs 0.3
// Project: https://github.com/wearefractal/vinyl-fs
// Definitions by: vvakame <https://github.com/vvakame>
// remisery <https://github.com/remisery>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="node" />
declare global {
namespace NodeJS {
interface WritableStream {
write(buffer: any/* Vinyl.File */, cb?: (err?: Error | null) => void): boolean;
}
}
}
import * as _events from 'events';
import * as File from 'vinyl';
import * as globStream from 'glob-stream';
export interface SrcOptions extends globStream.Options {
/** Prevents stream from emitting an error when file not found. */
allowEmpty?: boolean;
/** Specifies the working directory the folder is relative to */
cwd?: string;
/**
* Specifies the folder relative to the cwd
* This is used to determine the file names when saving in .dest()
* Default: where the glob begins
*/
base?: string;
/**
* Setting this to false will make file.contents a paused stream
* If true it will buffer the file contents
* Default: true
*/
buffer?: boolean;
/**
* The mode the directory should be created with.
* Default: the process mode
*/
dirMode?: number;
/**
* Whether or not you want globs to match on dot files or not
* (e.g., `.gitignore`).
*/
dot?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets.
* Setting to `false` to preserve them as symlinks and make `file.symlink`
* equal the original symlink's target path.
* Default: true
*/
followSymlinks?: boolean;
/**
* Setting this to false will ignore the contents of the file and disable
* writing to disk to speed up operations
* Default: true
*/
read?: boolean;
/**
* Whether or not the symlink should be relative or absolute.
* Default: false
*/
relative?: boolean;
/** Only find files that have been modified since the time specified */
since?: Date|number;
/**
* Causes the BOM to be stripped on UTF-8 encoded files. Set to `false`
* if you need the BOM for some reason.
*/
stripBOM?: boolean;
/**
* Setting this to true will create a duplex stream, one that passes
* through items and emits globbed files.
* Default: false
*/
passthrough?: boolean;
/**
* Setting this to true will enable sourcemaps.
* Default: false
*/
sourcemaps?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets. Setting to false to
* preserve them as symlinks and make file.symlink equal the original symlink's target path.
* Default: false
*/
resolveSymlinks?: boolean;
/**
* Causes the BOM to be removed on UTF-8 encoded files. Set to false if you need the BOM for some reason.
* Default: true
*/
removeBOM?: boolean;
}
export interface DestOptions {
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/**
* Specify the mode the files should be created with
* Default is the mode of the input file (file.stat.mode)
* or the process mode if the input file has no mode property
*/
mode?: number|string;
/** Specify the mode the directory should be created with. Default is the process mode */
dirMode?: number|string;
/** Specify if existing files with the same path should be overwritten or not. Default is true, to always overwrite existing files */
overwrite?: boolean;
/**
* Enables sourcemap support on files passed through the stream. Will write inline soucemaps if
* specified as true. Specifying a string path will write external sourcemaps at the given path.
*/
sourcemaps?: true | string;
/**
* When creating a symlink, whether or not the created symlink should be relative. If false,
* the symlink will be absolute. Note: This option will be ignored if a junction is being created.
*/
relativeSymlinks?: boolean;
/* When creating a symlink, whether or not a directory symlink should be created as a junction. */
useJunctions?: boolean;
}
/**
* Gets files that match the glob and converts them into the vinyl format
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
* @param opt Options Vinyl source options, changes the way the files are read, found, or stored in the vinyl stream
*/
export function src(globs: string|string[], opt?: SrcOptions): NodeJS.ReadWriteStream;
/**
* This is just a glob-watcher
*
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
*/
export function watch(globs: string|string[], cb?: (outEvt: { type: any; path: any; old: any; }) => void): _events.EventEmitter;
/**
* This is just a glob-watcher
*
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
*/
export function watch(
globs: string|string[],
opt?: {
interval?: number;
debounceDelay?: number;
cwd?: string;
maxListeners?(): number;
},
cb?: (outEvt: { type: any; path: any; old: any; }) => void): _events.EventEmitter;
/**
* On write the stream will save the vinyl File to disk at the folder/cwd specified.
* After writing the file to disk, it will be emitted from the stream so you can keep piping these around.
* The file will be modified after being written to this stream:
* cwd, base, and path will be overwritten to match the folder
* stat.mode will be overwritten if you used a mode parameter
* contents will have it's position reset to the beginning if it is a stream
* @param folder destination folder
*/
export function dest(folder: string, opt?: DestOptions): NodeJS.ReadWriteStream;
/**
* On write the stream will save the vinyl File to disk at the folder/cwd specified.
* After writing the file to disk, it will be emitted from the stream so you can keep piping these around.
* The file will be modified after being written to this stream:
* cwd, base, and path will be overwritten to match the folder
* stat.mode will be overwritten if you used a mode parameter
* contents will have it's position reset to the beginning if it is a stream
* @param getFolderPath function that takes in a file and returns a folder path
*/
export function dest(getFolderPath: (file: File) => string): NodeJS.ReadWriteStream;
+28
View File
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": false,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../../",
"typeRoots": [
"../../"
],
"paths": {
"vinyl-fs": [
"vinyl-fs/v0"
]
},
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"vinyl-fs-tests.ts"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "dtslint/dt.json"
}
+534
View File
@@ -0,0 +1,534 @@
// from src
import * as vfs from 'vinyl-fs';
import * as path from 'path';
import * as fs from 'fs'; // require('graceful-fs');
// import bufEqual = require('buffer-equal');
declare const bufEqual: any;
// import through = require('through2');
declare const through: any;
import File = require('vinyl');
// const spies = require('./spy');
declare const spies: any;
// Stub mocha functions
const {describe, it, before, after, beforeEach, afterEach} = null as any as {
[s: string]: ((s: string, cb: (done: any) => void) => void) & ((cb: (done: any) => void) => void) & {only: any, skip: any};
};
// TODO: These aren't useful as types tests since they take `any`.
declare const should: ShouldStatic;
interface ShouldStatic {
exist(obj: any, desc?: string): void;
not: this;
}
declare global {
interface Object {
should: { equal(obj: any): void; };
}
}
declare const gulp: any;
let bufferStream: any;
let dataWrap = (fn: any) => {
return (data: any, enc: any, cb: any) => {
fn(data);
cb();
};
};
describe('source stream', () => {
it('should explode on invalid glob (empty)', done => {
let stream: any;
try {
stream = gulp.src();
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should explode on invalid glob (number)', done => {
let stream: any;
try {
stream = gulp.src(123);
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should explode on invalid glob (empty array)', done => {
let stream: any;
try {
stream = gulp.src([]);
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should pass through writes', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: expectedPath,
contents: expectedContent
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
bufEqual(buffered[0].contents, expectedContent).should.equal(true);
done();
};
const stream = vfs.src("./fixtures/nothing.coffee");
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should glob a file with default settings', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
should.exist(buffered[0].stat);
buffered[0].path.should.equal(expectedPath);
buffered[0].isBuffer().should.equal(true);
bufEqual(buffered[0].contents, expectedContent).should.equal(true);
done();
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a file with default settings and relative cwd', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
should.exist(buffered[0].stat);
buffered[0].path.should.equal(expectedPath);
buffered[0].isBuffer().should.equal(true);
bufEqual(buffered[0].contents, expectedContent).should.equal(true);
done();
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: path.relative(process.cwd(), __dirname) });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a directory with default settings', done => {
const expectedPath = path.join(__dirname, "./fixtures/wow");
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].path.should.equal(expectedPath);
buffered[0].isNull().should.equal(true);
buffered[0].isDirectory().should.equal(true);
done();
};
const stream = vfs.src("./fixtures/wow/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a file with with no contents', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].path.should.equal(expectedPath);
buffered[0].isNull().should.equal(true);
should.not.exist(buffered[0].contents);
done();
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: __dirname, read: false });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a file with streaming contents', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
should.exist(buffered[0].stat);
buffered[0].path.should.equal(expectedPath);
buffered[0].isStream().should.equal(true);
let contentBuffer = new Buffer([]);
const contentBufferStream = through(dataWrap((data: any) => {
contentBuffer = Buffer.concat([contentBuffer, data]);
}));
buffered[0].contents.pipe(contentBufferStream);
buffered[0].contents.once('end', () => {
bufEqual(contentBuffer, expectedContent);
done();
});
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: __dirname, buffer: false });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
});
// from dest
// const vfs = require('../');
// const path = require('path');
// const fs = require('graceful-fs');
import rimraf = require('rimraf');
// const bufEqual = require('buffer-equal');
// const through = require('through2');
// const File = require('vinyl');
// const should = require('should');
// require('mocha');
const wipeOut = (cb: any) => {
rimraf(path.join(__dirname, "./out-fixtures/"), cb);
};
dataWrap = (fn: any) => {
return (data: any, enc: any, cb: any) => {
fn(data);
cb();
};
};
const realMode = (n: any) => {
return n & parseInt("07777", 8);
};
describe('dest stream', () => {
beforeEach(wipeOut);
afterEach(wipeOut);
it('should explode on invalid folder', done => {
let stream: any;
try {
stream = gulp.dest();
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should pass through writes with cwd', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should pass through writes with default cwd', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
const stream = vfs.dest(path.join(__dirname, "./out-fixtures/"));
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should not write null files', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(false);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder with relative cwd', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedContents = fs.readFileSync(inputPath);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: path.relative(process.cwd(), __dirname) });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedContents = fs.readFileSync(inputPath);
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedMode = parseInt("0655", 8);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: <any> {
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write streaming files to the right folder', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedContents = fs.readFileSync(inputPath);
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedMode = parseInt("0655", 8);
const contentStream = through.obj();
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: contentStream,
stat: <any> {
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
setTimeout(() => {
contentStream.write(expectedContents);
contentStream.end();
}, 100);
stream.end();
});
it('should write directories to the right folder', done => {
const inputPath = path.join(__dirname, "./fixtures/test");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test");
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedMode = parseInt("0655", 8);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: null,
stat: <any> {
isDirectory: () => true,
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
fs.lstatSync(expectedPath).isDirectory().should.equal(true);
realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should allow piping multiple dests in streaming mode', done => {
const inputPath1 = path.join(__dirname, "./out-fixtures/multiple-first");
const inputPath2 = path.join(__dirname, "./out-fixtures/multiple-second");
const inputBase = path.join(__dirname, "./out-fixtures/");
const srcPath = path.join(__dirname, "./fixtures/test.coffee");
const stream1 = vfs.dest('./out-fixtures/', { cwd: __dirname });
const stream2 = vfs.dest('./out-fixtures/', { cwd: __dirname });
const content = fs.readFileSync(srcPath);
const rename = through.obj((file: any, _: any, next: any) => {
file.path = inputPath2;
this.push(file);
next();
});
stream1.on('data', (file: any) => {
file.path.should.equal(inputPath1);
});
stream1.pipe(rename).pipe(stream2);
stream2.on('data', (file: any) => {
file.path.should.equal(inputPath2);
}).once('end', () => {
fs.readFileSync(inputPath1, 'utf8').should.equal(content.toString());
fs.readFileSync(inputPath2, 'utf8').should.equal(content.toString());
done();
});
const file = new File({
base: inputBase,
path: inputPath1,
cwd: __dirname,
contents: content
});
stream1.write(file);
stream1.end();
});
});
+245
View File
@@ -0,0 +1,245 @@
// Type definitions for vinyl-fs 1.0
// Project: https://github.com/wearefractal/vinyl-fs
// Definitions by: vvakame <https://github.com/vvakame>
// remisery <https://github.com/remisery>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="node" />
declare global {
namespace NodeJS {
interface WritableStream {
write(buffer: any/* Vinyl.File */, cb?: (err?: Error | null) => void): boolean;
}
}
}
import * as _events from 'events';
import * as File from 'vinyl';
import * as globStream from 'glob-stream';
export interface SrcOptions extends globStream.Options {
/** Prevents stream from emitting an error when file not found. */
allowEmpty?: boolean;
/** Specifies the working directory the folder is relative to */
cwd?: string;
/**
* Specifies the folder relative to the cwd
* This is used to determine the file names when saving in .dest()
* Default: where the glob begins
*/
base?: string;
/**
* Setting this to false will make file.contents a paused stream
* If true it will buffer the file contents
* Default: true
*/
buffer?: boolean;
/**
* The mode the directory should be created with.
* Default: the process mode
*/
dirMode?: number;
/**
* Whether or not you want globs to match on dot files or not
* (e.g., `.gitignore`).
*/
dot?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets.
* Setting to `false` to preserve them as symlinks and make `file.symlink`
* equal the original symlink's target path.
* Default: true
*/
followSymlinks?: boolean;
/**
* Setting this to false will ignore the contents of the file and disable
* writing to disk to speed up operations
* Default: true
*/
read?: boolean;
/**
* Whether or not the symlink should be relative or absolute.
* Default: false
*/
relative?: boolean;
/** Only find files that have been modified since the time specified */
since?: Date|number;
/**
* Causes the BOM to be stripped on UTF-8 encoded files. Set to `false`
* if you need the BOM for some reason.
*/
stripBOM?: boolean;
/**
* Setting this to true will create a duplex stream, one that passes
* through items and emits globbed files.
* Default: false
*/
passthrough?: boolean;
/**
* Setting this to true will enable sourcemaps.
* Default: false
*/
sourcemaps?: boolean;
/**
* Whether or not to recursively resolve symlinks to their targets. Setting to false to
* preserve them as symlinks and make file.symlink equal the original symlink's target path.
* Default: false
*/
resolveSymlinks?: boolean;
/**
* Causes the BOM to be removed on UTF-8 encoded files. Set to false if you need the BOM for some reason.
* Default: true
*/
removeBOM?: boolean;
}
export interface DestOptions {
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/**
* Specify the mode the files should be created with
* Default is the mode of the input file (file.stat.mode)
* or the process mode if the input file has no mode property
*/
mode?: number|string;
/** Specify the mode the directory should be created with. Default is the process mode */
dirMode?: number|string;
/** Specify if existing files with the same path should be overwritten or not. Default is true, to always overwrite existing files */
overwrite?: boolean;
/**
* Enables sourcemap support on files passed through the stream. Will write inline soucemaps if
* specified as true. Specifying a string path will write external sourcemaps at the given path.
*/
sourcemaps?: true | string;
/**
* When creating a symlink, whether or not the created symlink should be relative. If false,
* the symlink will be absolute. Note: This option will be ignored if a junction is being created.
*/
relativeSymlinks?: boolean;
/* When creating a symlink, whether or not a directory symlink should be created as a junction. */
useJunctions?: boolean;
}
/**
* Gets files that match the glob and converts them into the vinyl format
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
* @param opt Options Vinyl source options, changes the way the files are read, found, or stored in the vinyl stream
*/
export function src(globs: string|string[], opt?: SrcOptions): NodeJS.ReadWriteStream;
/**
* This is just a glob-watcher
*
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
*/
export function watch(globs: string|string[], cb?: (outEvt: { type: any; path: any; old: any; }) => void): _events.EventEmitter;
/**
* This is just a glob-watcher
*
* @param globs Takes a glob string or an array of glob strings as the first argument
* Globs are executed in order, so negations should follow positive globs
* fs.src(['!b*.js', '*.js']) would not exclude any files, but this would: fs.src(['*.js', '!b*.js'])
*/
export function watch(
globs: string|string[],
opt?: {
interval?: number;
debounceDelay?: number;
cwd?: string;
maxListeners?(): number;
},
cb?: (outEvt: { type: any; path: any; old: any; }) => void): _events.EventEmitter;
/**
* On write the stream will save the vinyl File to disk at the folder/cwd specified.
* After writing the file to disk, it will be emitted from the stream so you can keep piping these around.
* The file will be modified after being written to this stream:
* cwd, base, and path will be overwritten to match the folder
* stat.mode will be overwritten if you used a mode parameter
* contents will have it's position reset to the beginning if it is a stream
* @param folder destination folder
*/
export function dest(folder: string, opt?: DestOptions): NodeJS.ReadWriteStream;
/**
* On write the stream will save the vinyl File to disk at the folder/cwd specified.
* After writing the file to disk, it will be emitted from the stream so you can keep piping these around.
* The file will be modified after being written to this stream:
* cwd, base, and path will be overwritten to match the folder
* stat.mode will be overwritten if you used a mode parameter
* contents will have it's position reset to the beginning if it is a stream
* @param getFolderPath function that takes in a file and returns a folder path
*/
export function dest(getFolderPath: (file: File) => string): NodeJS.ReadWriteStream;
/**
* On write the stream will create a symbolic link (i.e. symlink) on disk at the folder/cwd specified.
* After creating the symbolic link, it will be emitted from the stream so you can keep piping these around.
* The file will be modified after being written to this stream:
* cwd, base, and path will be overwritten to match the folder
*/
export function symlink(folder: string, opts?: {
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/** Specify the mode the directory should be created with. Default is the process mode */
mode?: number|string;
/**
* Specify the mode the directory should be created with
* Default is the process mode
*/
dirMode?: number
}): NodeJS.ReadWriteStream;
/**
* On write the stream will create a symbolic link (i.e. symlink) on disk at the folder/cwd generated from getFolderPath.
* After creating the symbolic link, it will be emitted from the stream so you can keep piping these around.
* The file will be modified after being written to this stream:
* cwd, base, and path will be overwritten to match the folder
*/
export function symlink(getFolderPath: (File: File) => string, opts?:
{
/**
* Specify the working directory the folder is relative to
* Default is process.cwd()
*/
cwd?: string;
/**
* Specify the mode the directory should be created with
* Default is the process mode
*/
dirMode?: number
}): NodeJS.ReadWriteStream;
+28
View File
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": false,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../../",
"typeRoots": [
"../../"
],
"paths": {
"vinyl-fs": [
"vinyl-fs/v1"
]
},
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"vinyl-fs-tests.ts"
]
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "dtslint/dt.json"
}
+919
View File
@@ -0,0 +1,919 @@
// from src
import * as vfs from 'vinyl-fs';
import * as path from 'path';
import * as fs from 'fs'; // require('graceful-fs');
// import bufEqual = require('buffer-equal');
declare const bufEqual: any;
// import through = require('through2');
declare const through: any;
import File = require('vinyl');
// const spies = require('./spy');
declare const spies: any;
// Stub mocha functions
const {describe, it, before, after, beforeEach, afterEach} = null as any as {
[s: string]: ((s: string, cb: (done: any) => void) => void) & ((cb: (done: any) => void) => void) & {only: any, skip: any};
};
// TODO: These aren't useful as types tests since they take `any`.
declare const should: ShouldStatic;
interface ShouldStatic {
exist(obj: any, desc?: string): void;
not: this;
}
declare global {
interface Object {
should: { equal(obj: any): void; };
}
}
declare const gulp: any;
let bufferStream: any;
let dataWrap = (fn: any) => {
return (data: any, enc: any, cb: any) => {
fn(data);
cb();
};
};
describe('source stream', () => {
it('should explode on invalid glob (empty)', done => {
let stream: any;
try {
stream = gulp.src();
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should explode on invalid glob (number)', done => {
let stream: any;
try {
stream = gulp.src(123);
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should explode on invalid glob (empty array)', done => {
let stream: any;
try {
stream = gulp.src([]);
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should pass through writes', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: expectedPath,
contents: expectedContent
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
bufEqual(buffered[0].contents, expectedContent).should.equal(true);
done();
};
const stream = vfs.src("./fixtures/nothing.coffee");
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should glob a file with default settings', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
should.exist(buffered[0].stat);
buffered[0].path.should.equal(expectedPath);
buffered[0].isBuffer().should.equal(true);
bufEqual(buffered[0].contents, expectedContent).should.equal(true);
done();
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a file with default settings and relative cwd', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
should.exist(buffered[0].stat);
buffered[0].path.should.equal(expectedPath);
buffered[0].isBuffer().should.equal(true);
bufEqual(buffered[0].contents, expectedContent).should.equal(true);
done();
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: path.relative(process.cwd(), __dirname) });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a directory with default settings', done => {
const expectedPath = path.join(__dirname, "./fixtures/wow");
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].path.should.equal(expectedPath);
buffered[0].isNull().should.equal(true);
buffered[0].isDirectory().should.equal(true);
done();
};
const stream = vfs.src("./fixtures/wow/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a file with with no contents', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].path.should.equal(expectedPath);
buffered[0].isNull().should.equal(true);
should.not.exist(buffered[0].contents);
done();
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: __dirname, read: false });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
it('should glob a file with streaming contents', done => {
const expectedPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedContent = fs.readFileSync(expectedPath);
const onEnd = () => {
buffered.length.should.equal(1);
should.exist(buffered[0].stat);
buffered[0].path.should.equal(expectedPath);
buffered[0].isStream().should.equal(true);
let contentBuffer = new Buffer([]);
const contentBufferStream = through(dataWrap((data: any) => {
contentBuffer = Buffer.concat([contentBuffer, data]);
}));
buffered[0].contents.pipe(contentBufferStream);
buffered[0].contents.once('end', () => {
bufEqual(contentBuffer, expectedContent);
done();
});
};
const stream = vfs.src("./fixtures/*.coffee", { cwd: __dirname, buffer: false });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
});
});
// from dest
// const vfs = require('../');
// const path = require('path');
// const fs = require('graceful-fs');
import rimraf = require('rimraf');
// const bufEqual = require('buffer-equal');
// const through = require('through2');
// const File = require('vinyl');
// const should = require('should');
// require('mocha');
let wipeOut = (cb: any) => {
rimraf(path.join(__dirname, "./out-fixtures/"), cb);
};
dataWrap = (fn: any) => {
return (data: any, enc: any, cb: any) => {
fn(data);
cb();
};
};
let realMode = (n: any) => {
return n & parseInt("07777", 8);
};
describe('dest stream', () => {
beforeEach(wipeOut);
afterEach(wipeOut);
it('should explode on invalid folder', done => {
let stream: any;
try {
stream = gulp.dest();
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should pass through writes with cwd', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should pass through writes with default cwd', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
const stream = vfs.dest(path.join(__dirname, "./out-fixtures/"));
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should not write null files', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(false);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder with relative cwd', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedContents = fs.readFileSync(inputPath);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: path.relative(process.cwd(), __dirname) });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedContents = fs.readFileSync(inputPath);
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedMode = parseInt("0655", 8);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: <any> {
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write streaming files to the right folder', done => {
const inputPath = path.join(__dirname, "./fixtures/test.coffee");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test.coffee");
const expectedContents = fs.readFileSync(inputPath);
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedMode = parseInt("0655", 8);
const contentStream = through.obj();
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: contentStream,
stat: <any> {
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
setTimeout(() => {
contentStream.write(expectedContents);
contentStream.end();
}, 100);
stream.end();
});
it('should write directories to the right folder', done => {
const inputPath = path.join(__dirname, "./fixtures/test");
const inputBase = path.join(__dirname, "./fixtures/");
const expectedPath = path.join(__dirname, "./out-fixtures/test");
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, "./out-fixtures");
const expectedMode = parseInt("0655", 8);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: null,
stat: <any> {
isDirectory: () => true,
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(expectedCwd, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
fs.lstatSync(expectedPath).isDirectory().should.equal(true);
realMode(fs.lstatSync(expectedPath).mode).should.equal(expectedMode);
done();
};
const stream = vfs.dest("./out-fixtures/", { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should allow piping multiple dests in streaming mode', done => {
const inputPath1 = path.join(__dirname, "./out-fixtures/multiple-first");
const inputPath2 = path.join(__dirname, "./out-fixtures/multiple-second");
const inputBase = path.join(__dirname, "./out-fixtures/");
const srcPath = path.join(__dirname, "./fixtures/test.coffee");
const stream1 = vfs.dest('./out-fixtures/', { cwd: __dirname });
const stream2 = vfs.dest('./out-fixtures/', { cwd: __dirname });
const content = fs.readFileSync(srcPath);
const rename = through.obj((file: any, _: any, next: any) => {
file.path = inputPath2;
this.push(file);
next();
});
stream1.on('data', (file: any) => {
file.path.should.equal(inputPath1);
});
stream1.pipe(rename).pipe(stream2);
stream2.on('data', (file: any) => {
file.path.should.equal(inputPath2);
}).once('end', () => {
fs.readFileSync(inputPath1, 'utf8').should.equal(content.toString());
fs.readFileSync(inputPath2, 'utf8').should.equal(content.toString());
done();
});
const file = new File({
base: inputBase,
path: inputPath1,
cwd: __dirname,
contents: content
});
stream1.write(file);
stream1.end();
});
});
// This test is from
const chmodSpy = spies.chmodSpy;
const statSpy = spies.statSpy;
wipeOut = (cb: any) => {
rimraf(path.join(__dirname, './out-fixtures/'), cb);
spies.setError('false');
statSpy.reset();
chmodSpy.reset();
};
dataWrap = (fn: any) => {
return (data: any, enc: any, cb: any) => {
fn(data);
cb();
};
};
realMode = (n: any) => {
return n & parseInt("07777", 8);
};
describe('symlink stream', () => {
beforeEach(wipeOut);
afterEach(wipeOut);
it('should explode on invalid folder', (done: any) => {
let stream: any;
try {
stream = gulp.symlink();
} catch (err) {
should.exist(err);
should.not.exist(stream);
done();
}
});
it('should pass through writes with cwd', done => {
const inputPath = path.join(__dirname, './fixtures/test.coffee');
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
const stream = vfs.symlink('./out-fixtures/', { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should pass through writes with default cwd', done => {
const inputPath = path.join(__dirname, './fixtures/test.coffee');
const expectedFile = new File({
base: __dirname,
cwd: __dirname,
path: inputPath,
contents: null
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
done();
};
const stream = vfs.symlink(path.join(__dirname, './out-fixtures/'));
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should make link to the right folder with relative cwd', done => {
const inputPath = path.join(__dirname, './fixtures/test.coffee');
const inputBase = path.join(__dirname, './fixtures/');
const expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, './out-fixtures');
const expectedContents = fs.readFileSync(inputPath);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
const stream = vfs.symlink('./out-fixtures/', { cwd: path.relative(process.cwd(), __dirname) });
const buffered: any = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder with function and relative cwd', done => {
const inputPath = path.join(__dirname, './fixtures/test.coffee');
const inputBase = path.join(__dirname, './fixtures/');
const expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, './out-fixtures');
const expectedContents = fs.readFileSync(inputPath);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
const stream = vfs.symlink(file => {
should.exist(file);
file.should.equal(expectedFile);
return './out-fixtures';
}, { cwd: path.relative(process.cwd(), __dirname) });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write buffer files to the right folder', done => {
const inputPath = path.join(__dirname, './fixtures/test.coffee');
const inputBase = path.join(__dirname, './fixtures/');
const expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
const expectedContents = fs.readFileSync(inputPath);
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, './out-fixtures');
const expectedMode = parseInt("0655", 8);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: <any> {
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
const stream = vfs.symlink('./out-fixtures/', { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should write streaming files to the right folder', done => {
const inputPath = path.join(__dirname, './fixtures/test.coffee');
const inputBase = path.join(__dirname, './fixtures/');
const expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
const expectedContents = fs.readFileSync(inputPath);
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, './out-fixtures');
const expectedMode = parseInt("0655", 8);
const contentStream = through.obj();
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: contentStream,
stat: <any> {
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.existsSync(expectedPath).should.equal(true);
bufEqual(fs.readFileSync(expectedPath), expectedContents).should.equal(true);
fs.readlinkSync(expectedPath).should.equal(inputPath);
done();
};
const stream = vfs.symlink('./out-fixtures/', { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
setTimeout(() => {
contentStream.write(expectedContents);
contentStream.end();
}, 100);
stream.end();
});
it('should write directories to the right folder', done => {
const inputPath = path.join(__dirname, './fixtures/wow');
const inputBase = path.join(__dirname, './fixtures/');
const expectedPath = path.join(__dirname, './out-fixtures/wow');
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, './out-fixtures');
const expectedMode = parseInt("0655", 8);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: null,
stat: <any> {
isDirectory: () => true,
mode: expectedMode
} as fs.Stats
});
const onEnd = () => {
buffered.length.should.equal(1);
buffered[0].should.equal(expectedFile);
buffered[0].cwd.should.equal(__dirname, 'cwd should have changed');
buffered[0].base.should.equal(expectedBase, 'base should have changed');
buffered[0].path.should.equal(expectedPath, 'path should have changed');
fs.readlinkSync(expectedPath).should.equal(inputPath);
fs.lstatSync(expectedPath).isDirectory().should.equal(false);
fs.statSync(expectedPath).isDirectory().should.equal(true);
done();
};
const stream = vfs.symlink('./out-fixtures/', { cwd: __dirname });
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(expectedFile);
stream.end();
});
it('should use different modes for files and directories', done => {
const inputBase = path.join(__dirname, './fixtures');
const inputPath = path.join(__dirname, './fixtures/wow/suchempty');
const expectedBase = path.join(__dirname, './out-fixtures/wow');
const expectedDirMode = parseInt("0755", 8);
const expectedFileMode = parseInt("0655", 8);
const firstFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
stat: fs.statSync(inputPath)
});
const onEnd = () => {
realMode(fs.lstatSync(expectedBase).mode).should.equal(expectedDirMode);
realMode(buffered[0].stat.mode).should.equal(expectedFileMode);
done();
};
const stream = vfs.symlink('./out-fixtures/', {
cwd: __dirname,
mode: expectedFileMode,
dirMode: expectedDirMode
});
const buffered: any[] = [];
bufferStream = through.obj(dataWrap(buffered.push.bind(buffered)), onEnd);
stream.pipe(bufferStream);
stream.write(firstFile);
stream.end();
});
it('should report IO errors', done => {
const inputPath = path.join(__dirname, './fixtures/test.coffee');
const inputBase = path.join(__dirname, './fixtures/');
const expectedPath = path.join(__dirname, './out-fixtures/test.coffee');
const expectedContents = fs.readFileSync(inputPath);
const expectedCwd = __dirname;
const expectedBase = path.join(__dirname, './out-fixtures');
const expectedMode = parseInt("0722", 8);
const expectedFile = new File({
base: inputBase,
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: <any> {
mode: expectedMode
} as fs.Stats
});
fs.mkdirSync(expectedBase);
fs.chmodSync(expectedBase, 0);
const stream = vfs.symlink('./out-fixtures/', { cwd: __dirname });
stream.on('error', (err: any) => {
err.code.should.equal('EACCES');
done();
});
stream.write(expectedFile);
});
['end', 'finish'].forEach(eventName => {
it(`should emit ${eventName} event`, done => {
const srcPath = path.join(__dirname, './fixtures/test.coffee');
const stream = vfs.symlink('./out-fixtures/', { cwd: __dirname });
stream.on(eventName, () => {
done();
});
const file = new File({
path: srcPath,
cwd: __dirname,
contents: new Buffer("1234567890")
});
stream.write(file);
stream.end();
});
});
it('should check if it"s a vinyl file', () => {
const srcPath = path.join(__dirname, './fixtures/test.coffee');
const options = {
path: srcPath,
cwd: __dirname,
contents: new Buffer("1234567890")
};
const file = new File(options);
File.isVinyl(file).should.equal(true);
File.isVinyl(options).should.equal(false);
});
});
+17 -17
View File
@@ -3,13 +3,14 @@
import * as vfs from 'vinyl-fs';
import * as path from 'path';
import * as fs from 'fs'; // require('graceful-fs');
import * as fs from 'fs';
import * as stream from 'stream';
// import bufEqual = require('buffer-equal');
declare const bufEqual: any;
// import through = require('through2');
declare const through: any;
import gulp = require('gulp');
import File = require('vinyl');
import through = require('through2');
// const spies = require('./spy');
declare const spies: any;
@@ -30,8 +31,7 @@ declare global {
}
}
declare const gulp: any;
let bufferStream: any;
let bufferStream: stream.Transform;
let dataWrap = (fn: any) => {
return (data: any, enc: any, cb: any) => {
@@ -44,7 +44,7 @@ describe('source stream', () => {
it('should explode on invalid glob (empty)', done => {
let stream: any;
try {
stream = gulp.src();
stream = (<any> gulp).src();
} catch (err) {
should.exist(err);
should.not.exist(stream);
@@ -55,7 +55,7 @@ describe('source stream', () => {
it('should explode on invalid glob (number)', done => {
let stream: any;
try {
stream = gulp.src(123);
stream = gulp.src(<any> 123);
} catch (err) {
should.exist(err);
should.not.exist(stream);
@@ -243,7 +243,7 @@ describe('dest stream', () => {
it('should explode on invalid folder', done => {
let stream: any;
try {
stream = gulp.dest();
stream = (<any> gulp).dest();
} catch (err) {
should.exist(err);
should.not.exist(stream);
@@ -383,7 +383,7 @@ describe('dest stream', () => {
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: {
stat: <any> {
mode: expectedMode
} as fs.Stats
});
@@ -424,7 +424,7 @@ describe('dest stream', () => {
cwd: __dirname,
path: inputPath,
contents: contentStream,
stat: {
stat: <any> {
mode: expectedMode
} as fs.Stats
});
@@ -467,7 +467,7 @@ describe('dest stream', () => {
cwd: __dirname,
path: inputPath,
contents: null,
stat: {
stat: <any> {
isDirectory: () => true,
mode: expectedMode
} as fs.Stats
@@ -502,7 +502,7 @@ describe('dest stream', () => {
const stream1 = vfs.dest('./out-fixtures/', { cwd: __dirname });
const stream2 = vfs.dest('./out-fixtures/', { cwd: __dirname });
const content = fs.readFileSync(srcPath);
const rename = through.obj((file: any, _: any, next: any) => {
const rename = through.obj(function t(this: stream.Transform, file: any, _: any, next: any) {
file.path = inputPath2;
this.push(file);
next();
@@ -563,7 +563,7 @@ describe('symlink stream', () => {
it('should explode on invalid folder', (done: any) => {
let stream: any;
try {
stream = gulp.symlink();
stream = (<any> gulp).symlink();
} catch (err) {
should.exist(err);
should.not.exist(stream);
@@ -711,7 +711,7 @@ describe('symlink stream', () => {
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: {
stat: <any> {
mode: expectedMode
} as fs.Stats
});
@@ -752,7 +752,7 @@ describe('symlink stream', () => {
cwd: __dirname,
path: inputPath,
contents: contentStream,
stat: {
stat: <any> {
mode: expectedMode
} as fs.Stats
});
@@ -795,7 +795,7 @@ describe('symlink stream', () => {
cwd: __dirname,
path: inputPath,
contents: null,
stat: {
stat: <any> {
isDirectory: () => true,
mode: expectedMode
} as fs.Stats
@@ -870,7 +870,7 @@ describe('symlink stream', () => {
cwd: __dirname,
path: inputPath,
contents: expectedContents,
stat: {
stat: <any> {
mode: expectedMode
} as fs.Stats
});