UNPKG

5.73 kBJavaScriptView Raw
1'use strict';
2
3/* global describe, it */
4
5var pathlib = require('path');
6var Stream = require('stream');
7var expect = require('chai').expect;
8var gulp = require('gulp');
9var run = require('../');
10
11
12// We have a lot of loggers listening on stdout
13// process.stdout.setMaxListeners(Infinity);
14
15
16describe('gulp-run', function () {
17
18 var sampleFilename = pathlib.join(__dirname, 'sample.input.txt');
19
20
21 it('includes `node_modules/.bin` on the PATH', function (done) {
22 var nodeModulesPath = pathlib.join(__dirname, '..', '..', '.bin');
23
24 run('echo $PATH', {verbosity:0}).exec()
25 .pipe(compare(new RegExp('^' + nodeModulesPath)))
26 .pipe(call(done));
27
28 });
29
30
31 it('lets you set the initial cwd of the command', function (done) {
32
33 run('pwd', {cwd:'/', verbosity:0}).exec()
34 .pipe(compare('/\n'))
35 .pipe(call(done));
36
37 });
38
39
40 it('supports verbosity levels', function (done) {
41 var colors = require('gulp-util').colors;
42
43 // Stub out stdout.write
44 var stdoutWrite = process.stdout.write;
45 var writtenOutput = '';
46 process.stdout.write = function (chunk, enc, callback) {
47 writtenOutput += chunk.toString(enc);
48 if (typeof callback === 'function') process.nextTick(callback);
49 };
50
51 var count = 0;
52 function almostDone() {
53 count += 1;
54 if (count >= 3) {
55 process.stdout.write = stdoutWrite;
56 return done();
57 }
58 }
59
60 (new run.Command('echo "testing verbosity:0"', {verbosity:0})).exec(function () {
61 expect(writtenOutput).to.match(/^$/);
62 writtenOutput = '';
63 almostDone();
64 });
65
66 (new run.Command('echo "testing verbosity:1"', {verbosity:1})).exec(function () {
67 var output = colors.stripColor(writtenOutput);
68 expect(output).to.match(/\[.*\] \$ echo "testing verbosity:1" # Silenced\n/);
69 writtenOutput = '';
70 almostDone();
71 });
72
73 (new run.Command('echo "testing verbosity:2"', {verbosity:2})).exec(function () {
74 var output = colors.stripColor(writtenOutput);
75 expect(output).to.match(/\[.*\] \$ echo "testing verbosity:2"\ntesting verbosity:2/);
76 almostDone();
77 });
78
79 });
80
81
82 describe('in a vinyl pipeline', function () {
83
84 it('works with buffers', function (done) {
85
86 gulp.src(sampleFilename, {buffer:true}) // Each line is the line number.
87 .pipe(run('awk "NR % 2 == 0"', {verbosity:0})) // Get the even lines with awk.
88 .pipe(compare('2\n4\n6\n8\n10\n12\n')) // Compare the output.
89 .pipe(call(done)); // Profit.
90
91 });
92
93
94 it('works with streams', function (done) {
95
96 gulp.src(sampleFilename, {buffer:false}) // Each line is the line number.
97 .pipe(run('awk "NR % 2 == 0"', {verbosity:0})) // Get the even lines with awk.
98 .pipe(compare('2\n4\n6\n8\n10\n12\n')) // Compare the output.
99 .pipe(call(done)); // Profit.
100
101 });
102
103
104 it('supports command templates, i.e. `echo <%= file.path %>`', function (done) {
105
106 gulp.src(sampleFilename)
107 .pipe(run('echo <%= file.path %>', {verbosity:0})) // echo the name of the file.
108 .pipe(compare(sampleFilename + '\n'))
109 .pipe(call(done));
110
111 });
112
113
114 it('emits an `error` event on a failed command', function (done) {
115
116 gulp.src(sampleFilename)
117 .pipe(run('exit 1', {verbosity:0})) // Non-zero exit code
118 .on('error', function () {
119 done();
120 });
121
122 });
123
124 });
125
126
127 describe('direct execution (`.exec`)', function () {
128
129 it('is asynchronous (this test sleeps for 1s)', function (done) {
130
131 var startTime = process.hrtime()[0]; // Current time in seconds
132
133 // Sleep for 1s, then callback
134 run('sleep 1', {verbosity:0}).exec(function () {
135 var delta = process.hrtime()[0] - startTime; // Time in seconds
136 expect(delta).to.equal(1);
137 done();
138 });
139
140 });
141
142
143 it('returns a vinyl stream wrapping stdout', function (done) {
144
145 run('echo Hello World', {verbosity:0}).exec() // Start a command with `.exec()`.
146 .pipe(compare('Hello World\n')) // stdout piped as a Vinyl file.
147 .pipe(call(done));
148
149 });
150
151
152 it('emits an `error` event on a failed command', function (done) {
153
154 run('exit 1', {verbosity:0}).exec() // Non-zero exit code
155 .on('error', function () {
156 done();
157 });
158
159 });
160
161 });
162});
163
164
165
166/// Helpers
167/// --------------------------------------------------
168
169// A stream that calls a function whenever a file is piped in.
170function call(callback1) {
171 var stream = new Stream.Transform({objectMode:true});
172 stream._transform = function (file, enc, callback2) {
173 this.push(file);
174 callback1();
175 process.nextTick(callback2);
176 };
177 return stream;
178}
179
180
181// A stream that throws if the contents of the incoming file doesn't match the argument.
182function compare(match) {
183 if (!(match instanceof RegExp)) {
184 match = new RegExp('^' + match.toString() + '$');
185 }
186 var stream = new Stream.Transform({objectMode:true});
187 stream._transform = function (file, end, callback) {
188 var contents;
189
190 if (file.isStream()) {
191 var newFile = file.clone();
192 newFile.contents = new Stream.Transform();
193 newFile.contents._transform = function (chunk, enc, callback) {
194 newFile.contents.push(chunk);
195 return callback();
196 };
197 contents = '';
198 file.contents.on('readable', function () {
199 var chunk;
200 (function loop() {
201 chunk = file.contents.read();
202 if (chunk) {
203 contents += chunk;
204 loop();
205 }
206 })();
207 });
208 file.contents.on('end', function () {
209 expect(contents).to.match(match);
210 newFile.contents.push(contents);
211 newFile.contents.end();
212 stream.push(newFile);
213 process.nextTick(callback);
214 });
215 return;
216 }
217
218 contents = (file.isBuffer()) ? file.contents.toString() : file.contents;
219 expect(contents).to.match(match);
220 stream.push(file);
221 process.nextTick(callback);
222 return;
223 };
224 return stream;
225}