1 | var assert = require('assert'),
|
2 | fs = require('fs'),
|
3 | path = require('path'),
|
4 | read = require('fs').readFileSync,
|
5 | glob = require('glob'),
|
6 | rimraf = require('rimraf'),
|
7 | stream = require('stream'),
|
8 | spawn = require('cross-spawn'),
|
9 | cli = path.join(__dirname, '..', 'bin', 'node-sass'),
|
10 | fixture = path.join.bind(null, __dirname, 'fixtures');
|
11 |
|
12 | describe('cli', function() {
|
13 |
|
14 |
|
15 | this.retries(4);
|
16 |
|
17 | describe('node-sass < in.scss', function() {
|
18 | it('should read data from stdin', function(done) {
|
19 | var src = fs.createReadStream(fixture('simple/index.scss'));
|
20 | var expected = read(fixture('simple/expected.css'), 'utf8').trim();
|
21 | var bin = spawn(cli);
|
22 |
|
23 | bin.stdout.setEncoding('utf8');
|
24 | bin.stdout.once('data', function(data) {
|
25 | assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
|
26 | done();
|
27 | });
|
28 |
|
29 | src.pipe(bin.stdin);
|
30 | });
|
31 |
|
32 | it('should compile sass using the --indented-syntax option', function(done) {
|
33 | var src = fs.createReadStream(fixture('indent/index.sass'));
|
34 | var expected = read(fixture('indent/expected.css'), 'utf8').trim();
|
35 | var bin = spawn(cli, ['--indented-syntax']);
|
36 |
|
37 | bin.stdout.setEncoding('utf8');
|
38 | bin.stdout.once('data', function(data) {
|
39 | assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
|
40 | done();
|
41 | });
|
42 |
|
43 | src.pipe(bin.stdin);
|
44 | });
|
45 |
|
46 | it('should compile with the --quiet option', function(done) {
|
47 | var src = fs.createReadStream(fixture('simple/index.scss'));
|
48 | var expected = read(fixture('simple/expected.css'), 'utf8').trim();
|
49 | var bin = spawn(cli, ['--quiet']);
|
50 |
|
51 | bin.stdout.setEncoding('utf8');
|
52 | bin.stdout.once('data', function(data) {
|
53 | assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
|
54 | done();
|
55 | });
|
56 |
|
57 | src.pipe(bin.stdin);
|
58 | });
|
59 |
|
60 | it('should compile with the --output-style option', function(done) {
|
61 | var src = fs.createReadStream(fixture('compressed/index.scss'));
|
62 | var expected = read(fixture('compressed/expected.css'), 'utf8').trim();
|
63 | var bin = spawn(cli, ['--output-style', 'compressed']);
|
64 |
|
65 | bin.stdout.setEncoding('utf8');
|
66 | bin.stdout.once('data', function(data) {
|
67 | assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
|
68 | done();
|
69 | });
|
70 |
|
71 | src.pipe(bin.stdin);
|
72 | });
|
73 |
|
74 | it('should compile with the --source-comments option', function(done) {
|
75 | var src = fs.createReadStream(fixture('source-comments/index.scss'));
|
76 | var expected = read(fixture('source-comments/expected.css'), 'utf8').trim();
|
77 | var bin = spawn(cli, ['--source-comments']);
|
78 |
|
79 | bin.stdout.setEncoding('utf8');
|
80 | bin.stdout.once('data', function(data) {
|
81 | assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
|
82 | done();
|
83 | });
|
84 |
|
85 | src.pipe(bin.stdin);
|
86 | });
|
87 |
|
88 | it('should render with indentWidth and indentType options', function(done) {
|
89 | var src = new stream.Readable();
|
90 | var bin = spawn(cli, ['--indent-width', 7, '--indent-type', 'tab']);
|
91 |
|
92 | src._read = function() { };
|
93 | src.push('div { color: transparent; }');
|
94 | src.push(null);
|
95 |
|
96 | bin.stdout.setEncoding('utf8');
|
97 | bin.stdout.once('data', function(data) {
|
98 | assert.equal(data.trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }');
|
99 | done();
|
100 | });
|
101 |
|
102 | src.pipe(bin.stdin);
|
103 | });
|
104 |
|
105 | it('should render with linefeed option', function(done) {
|
106 | var src = new stream.Readable();
|
107 | var bin = spawn(cli, ['--linefeed', 'lfcr']);
|
108 |
|
109 | src._read = function() { };
|
110 | src.push('div { color: transparent; }');
|
111 | src.push(null);
|
112 |
|
113 | bin.stdout.setEncoding('utf8');
|
114 | bin.stdout.once('data', function(data) {
|
115 | assert.equal(data.trim(), 'div {\n\r color: transparent; }');
|
116 | done();
|
117 | });
|
118 |
|
119 | src.pipe(bin.stdin);
|
120 | });
|
121 | });
|
122 |
|
123 | describe('node-sass in.scss', function() {
|
124 | it('should compile a scss file', function(done) {
|
125 | process.chdir(fixture('simple'));
|
126 |
|
127 | var src = fixture('simple/index.scss');
|
128 | var dest = fixture('simple/index.css');
|
129 | var bin = spawn(cli, [src, dest]);
|
130 |
|
131 | bin.once('close', function() {
|
132 | assert(fs.existsSync(dest));
|
133 | fs.unlinkSync(dest);
|
134 | process.chdir(__dirname);
|
135 | done();
|
136 | });
|
137 | });
|
138 |
|
139 | it('should compile a scss file to custom destination', function(done) {
|
140 | process.chdir(fixture('simple'));
|
141 |
|
142 | var src = fixture('simple/index.scss');
|
143 | var dest = fixture('simple/index-custom.css');
|
144 | var bin = spawn(cli, [src, dest]);
|
145 |
|
146 | bin.once('close', function() {
|
147 | assert(fs.existsSync(dest));
|
148 | fs.unlinkSync(dest);
|
149 | process.chdir(__dirname);
|
150 | done();
|
151 | });
|
152 | });
|
153 |
|
154 | it('should compile with the --include-path option', function(done) {
|
155 | var includePaths = [
|
156 | '--include-path', fixture('include-path/functions'),
|
157 | '--include-path', fixture('include-path/lib')
|
158 | ];
|
159 |
|
160 | var src = fixture('include-path/index.scss');
|
161 | var expected = read(fixture('include-path/expected.css'), 'utf8').trim();
|
162 | var bin = spawn(cli, [src].concat(includePaths));
|
163 |
|
164 | bin.stdout.setEncoding('utf8');
|
165 | bin.stdout.once('data', function(data) {
|
166 | assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
|
167 | done();
|
168 | });
|
169 | });
|
170 |
|
171 | it('should compile silently using the --quiet option', function(done) {
|
172 | process.chdir(fixture('simple'));
|
173 |
|
174 | var src = fixture('simple/index.scss');
|
175 | var dest = fixture('simple/index.css');
|
176 | var bin = spawn(cli, [src, dest, '--quiet']);
|
177 | var didEmit = false;
|
178 |
|
179 | bin.stderr.once('data', function() {
|
180 | didEmit = true;
|
181 | });
|
182 |
|
183 | bin.once('close', function() {
|
184 | assert.equal(didEmit, false);
|
185 | fs.unlinkSync(dest);
|
186 | process.chdir(__dirname);
|
187 | done();
|
188 | });
|
189 | });
|
190 |
|
191 | it('should still report errors with the --quiet option', function(done) {
|
192 | process.chdir(fixture('invalid'));
|
193 |
|
194 | var src = fixture('invalid/index.scss');
|
195 | var dest = fixture('invalid/index.css');
|
196 | var bin = spawn(cli, [src, dest, '--quiet']);
|
197 | var didEmit = false;
|
198 |
|
199 | bin.stderr.once('data', function() {
|
200 | didEmit = true;
|
201 | });
|
202 |
|
203 | bin.once('close', function() {
|
204 | assert.equal(didEmit, true);
|
205 | process.chdir(__dirname);
|
206 | done();
|
207 | });
|
208 | });
|
209 |
|
210 | it('should not exit with the --watch option', function(done) {
|
211 | var src = fixture('simple/index.scss');
|
212 | var bin = spawn(cli, [src, '--watch']);
|
213 | var exited;
|
214 |
|
215 | bin.once('close', function() {
|
216 | exited = true;
|
217 | });
|
218 |
|
219 | setTimeout(function() {
|
220 | if (exited) {
|
221 | throw new Error('Watch ended too early!');
|
222 | } else {
|
223 | bin.kill();
|
224 | done();
|
225 | }
|
226 | }, 100);
|
227 | });
|
228 |
|
229 | it.skip('should emit `warn` on file change when using --watch option', function(done) {
|
230 | var src = fixture('simple/tmp.scss');
|
231 |
|
232 | fs.writeFileSync(src, '');
|
233 |
|
234 | var bin = spawn(cli, ['--watch', src]);
|
235 |
|
236 | bin.stderr.setEncoding('utf8');
|
237 | bin.stderr.once('data', function(data) {
|
238 | assert.strictEqual(data.trim(), '=> changed: ' + src);
|
239 | fs.unlinkSync(src);
|
240 | bin.kill();
|
241 | done();
|
242 | });
|
243 |
|
244 | setTimeout(function() {
|
245 | fs.appendFileSync(src, 'body {}');
|
246 | }, 500);
|
247 | });
|
248 |
|
249 | it.skip('should emit nothing on file change when using --watch and --quiet options', function(done) {
|
250 | var src = fixture('simple/tmp.scss');
|
251 | var didEmit = false;
|
252 | fs.writeFileSync(src, '');
|
253 |
|
254 | var bin = spawn(cli, ['--watch', '--quiet', src]);
|
255 |
|
256 | bin.stderr.setEncoding('utf8');
|
257 | bin.stderr.once('data', function() {
|
258 | didEmit = true;
|
259 | });
|
260 |
|
261 | setTimeout(function() {
|
262 | fs.appendFileSync(src, 'body {}');
|
263 | setTimeout(function() {
|
264 | assert.equal(didEmit, false);
|
265 | bin.kill();
|
266 | done();
|
267 | fs.unlinkSync(src);
|
268 | }, 200);
|
269 | }, 500);
|
270 | });
|
271 |
|
272 | it.skip('should render all watched files', function(done) {
|
273 | var src = fixture('simple/bar.scss');
|
274 |
|
275 | fs.writeFileSync(src, '');
|
276 |
|
277 | var bin = spawn(cli, [
|
278 | '--output-style', 'compressed',
|
279 | '--watch', src
|
280 | ]);
|
281 |
|
282 | bin.stdout.setEncoding('utf8');
|
283 | bin.stdout.once('data', function(data) {
|
284 | assert.strictEqual(data.trim(), 'body{background:white}');
|
285 | fs.unlinkSync(src);
|
286 | bin.kill();
|
287 | done();
|
288 | });
|
289 |
|
290 | setTimeout(function() {
|
291 | fs.appendFileSync(src, 'body{background:white}');
|
292 | }, 500);
|
293 | });
|
294 |
|
295 | it.skip('should watch the full scss dep tree for a single file (scss)', function(done) {
|
296 | var src = fixture('watching/index.scss');
|
297 | var foo = fixture('watching/white.scss');
|
298 |
|
299 | fs.writeFileSync(foo, '');
|
300 |
|
301 | var bin = spawn(cli, [
|
302 | '--output-style', 'compressed',
|
303 | '--watch', src
|
304 | ]);
|
305 |
|
306 | bin.stdout.setEncoding('utf8');
|
307 | bin.stdout.once('data', function(data) {
|
308 | assert.strictEqual(data.trim(), 'body{background:blue}');
|
309 | bin.kill();
|
310 | done();
|
311 | });
|
312 |
|
313 | setTimeout(function() {
|
314 | fs.appendFileSync(foo, 'body{background:blue}\n');
|
315 | }, 500);
|
316 | });
|
317 |
|
318 | it.skip('should watch the full sass dep tree for a single file (sass)', function(done) {
|
319 | var src = fixture('watching/index.sass');
|
320 | var foo = fixture('watching/bar.sass');
|
321 |
|
322 | fs.writeFileSync(foo, '');
|
323 |
|
324 | var bin = spawn(cli, [
|
325 | '--output-style', 'compressed',
|
326 | '--watch', src
|
327 | ]);
|
328 |
|
329 | bin.stdout.setEncoding('utf8');
|
330 | bin.stdout.once('data', function(data) {
|
331 | assert.strictEqual(data.trim(), 'body{background:red}');
|
332 | bin.kill();
|
333 | done();
|
334 | });
|
335 |
|
336 | setTimeout(function() {
|
337 | fs.appendFileSync(foo, 'body\n\tbackground: red\n');
|
338 | }, 500);
|
339 | });
|
340 | });
|
341 |
|
342 | describe('node-sass --output directory', function() {
|
343 | it.skip('should watch whole directory', function(done) {
|
344 | var destDir = fixture('watching-css-out-01/');
|
345 | var srcDir = fixture('watching-dir-01/');
|
346 | var srcFile = path.join(srcDir, 'index.scss');
|
347 |
|
348 | fs.writeFileSync(srcFile, '');
|
349 |
|
350 | var bin = spawn(cli, [
|
351 | '--output-style', 'compressed',
|
352 | '--output', destDir,
|
353 | '--watch', srcDir
|
354 | ]);
|
355 |
|
356 | setTimeout(function() {
|
357 | fs.appendFileSync(srcFile, 'a {color:green;}\n');
|
358 | setTimeout(function() {
|
359 | bin.kill();
|
360 | var files = fs.readdirSync(destDir);
|
361 | assert.deepEqual(files, ['index.css']);
|
362 | rimraf(destDir, done);
|
363 | }, 200);
|
364 | }, 500);
|
365 | });
|
366 |
|
367 | it.skip('should compile all changed files in watched directory', function(done) {
|
368 | var destDir = fixture('watching-css-out-02/');
|
369 | var srcDir = fixture('watching-dir-02/');
|
370 | var srcFile = path.join(srcDir, 'foo.scss');
|
371 |
|
372 | fs.writeFileSync(srcFile, '');
|
373 |
|
374 | var bin = spawn(cli, [
|
375 | '--output-style', 'compressed',
|
376 | '--output', destDir,
|
377 | '--watch', srcDir
|
378 | ]);
|
379 |
|
380 | setTimeout(function () {
|
381 | fs.appendFileSync(srcFile, 'body{background:white}\n');
|
382 | setTimeout(function () {
|
383 | bin.kill();
|
384 | var files = fs.readdirSync(destDir);
|
385 | assert.deepEqual(files, ['foo.css', 'index.css']);
|
386 | rimraf(destDir, done);
|
387 | }, 200);
|
388 | }, 500);
|
389 | });
|
390 | });
|
391 |
|
392 | describe('node-sass in.scss --output out.css', function() {
|
393 | it('should compile a scss file to build.css', function(done) {
|
394 | var src = fixture('simple/index.scss');
|
395 | var dest = fixture('simple/index.css');
|
396 | var bin = spawn(cli, [src, '--output', path.dirname(dest)]);
|
397 |
|
398 | bin.once('close', function() {
|
399 | assert(fs.existsSync(dest));
|
400 | fs.unlinkSync(dest);
|
401 | done();
|
402 | });
|
403 | });
|
404 |
|
405 | it('should compile with the --source-map option', function(done) {
|
406 | var src = fixture('source-map/index.scss');
|
407 | var destCss = fixture('source-map/index.css');
|
408 | var destMap = fixture('source-map/index.map');
|
409 | var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
410 | var expectedMap = read(fixture('source-map/expected.map'), 'utf8').trim().replace(/\r\n/g, '\n');
|
411 | var bin = spawn(cli, [src, '--output', path.dirname(destCss), '--source-map', destMap]);
|
412 |
|
413 | bin.once('close', function() {
|
414 | assert.equal(read(destCss, 'utf8').trim(), expectedCss);
|
415 | assert.equal(read(destMap, 'utf8').trim(), expectedMap);
|
416 | fs.unlinkSync(destCss);
|
417 | fs.unlinkSync(destMap);
|
418 | done();
|
419 | });
|
420 | });
|
421 |
|
422 | it('should omit sourceMappingURL if --omit-source-map-url flag is used', function(done) {
|
423 | var src = fixture('source-map/index.scss');
|
424 | var dest = fixture('source-map/index.css');
|
425 | var map = fixture('source-map/index.map');
|
426 | var bin = spawn(cli, [
|
427 | src, '--output', path.dirname(dest),
|
428 | '--source-map', map, '--omit-source-map-url'
|
429 | ]);
|
430 |
|
431 | bin.once('close', function() {
|
432 | assert.strictEqual(read(dest, 'utf8').indexOf('sourceMappingURL'), -1);
|
433 | assert(fs.existsSync(map));
|
434 | fs.unlinkSync(map);
|
435 | fs.unlinkSync(dest);
|
436 | done();
|
437 | });
|
438 | });
|
439 |
|
440 | it('should compile with the --source-root option', function(done) {
|
441 | var src = fixture('source-map/index.scss');
|
442 | var destCss = fixture('source-map/index.css');
|
443 | var destMap = fixture('source-map/index.map');
|
444 | var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
445 | var expectedUrl = 'http://test/';
|
446 | var bin = spawn(cli, [
|
447 | src, '--output', path.dirname(destCss),
|
448 | '--source-map-root', expectedUrl,
|
449 | '--source-map', destMap
|
450 | ]);
|
451 |
|
452 | bin.once('close', function() {
|
453 | assert.equal(read(destCss, 'utf8').trim(), expectedCss);
|
454 | assert.equal(JSON.parse(read(destMap, 'utf8')).sourceRoot, expectedUrl);
|
455 | fs.unlinkSync(destCss);
|
456 | fs.unlinkSync(destMap);
|
457 | done();
|
458 | });
|
459 | });
|
460 |
|
461 | it('should compile with the --source-map-embed option and no outfile', function(done) {
|
462 | var src = fixture('source-map-embed/index.scss');
|
463 | var expectedCss = read(fixture('source-map-embed/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
464 | var result = '';
|
465 | var bin = spawn(cli, [
|
466 | src,
|
467 | '--source-map-embed',
|
468 | '--source-map', 'true'
|
469 | ]);
|
470 |
|
471 | bin.stdout.on('data', function(data) {
|
472 | result += data;
|
473 | });
|
474 |
|
475 | bin.once('close', function() {
|
476 | assert.equal(result.trim().replace(/\r\n/g, '\n'), expectedCss);
|
477 | done();
|
478 | });
|
479 | });
|
480 | });
|
481 |
|
482 | describe('node-sass sass/ --output css/', function() {
|
483 | it('should create the output directory', function(done) {
|
484 | var src = fixture('input-directory/sass');
|
485 | var dest = fixture('input-directory/css');
|
486 | var bin = spawn(cli, [src, '--output', dest]);
|
487 |
|
488 | bin.once('close', function() {
|
489 | assert(fs.existsSync(dest));
|
490 | rimraf.sync(dest);
|
491 | done();
|
492 | });
|
493 | });
|
494 |
|
495 | it('should compile all files in the folder', function(done) {
|
496 | var src = fixture('input-directory/sass');
|
497 | var dest = fixture('input-directory/css');
|
498 | var bin = spawn(cli, [src, '--output', dest]);
|
499 |
|
500 | bin.once('close', function() {
|
501 | var files = fs.readdirSync(dest).sort();
|
502 | assert.deepEqual(files, ['one.css', 'two.css', 'nested'].sort());
|
503 | var nestedFiles = fs.readdirSync(path.join(dest, 'nested'));
|
504 | assert.deepEqual(nestedFiles, ['three.css']);
|
505 | rimraf.sync(dest);
|
506 | done();
|
507 | });
|
508 | });
|
509 |
|
510 | it('should compile with --source-map set to directory', function(done) {
|
511 | var src = fixture('input-directory/sass');
|
512 | var dest = fixture('input-directory/css');
|
513 | var destMap = fixture('input-directory/map');
|
514 | var bin = spawn(cli, [src, '--output', dest, '--source-map', destMap]);
|
515 |
|
516 | bin.once('close', function() {
|
517 | var map = JSON.parse(read(fixture('input-directory/map/nested/three.css.map'), 'utf8'));
|
518 |
|
519 | assert.equal(map.file, '../../css/nested/three.css');
|
520 | rimraf.sync(dest);
|
521 | rimraf.sync(destMap);
|
522 | done();
|
523 | });
|
524 | });
|
525 |
|
526 | it('should skip files with an underscore', function(done) {
|
527 | var src = fixture('input-directory/sass');
|
528 | var dest = fixture('input-directory/css');
|
529 | var bin = spawn(cli, [src, '--output', dest]);
|
530 |
|
531 | bin.once('close', function() {
|
532 | var files = fs.readdirSync(dest);
|
533 | assert.equal(files.indexOf('_skipped.css'), -1);
|
534 | rimraf.sync(dest);
|
535 | done();
|
536 | });
|
537 | });
|
538 |
|
539 | it('should ignore nested files if --recursive false', function(done) {
|
540 | var src = fixture('input-directory/sass');
|
541 | var dest = fixture('input-directory/css');
|
542 | var bin = spawn(cli, [
|
543 | src, '--output', dest,
|
544 | '--recursive', false
|
545 | ]);
|
546 |
|
547 | bin.once('close', function() {
|
548 | var files = fs.readdirSync(dest);
|
549 | assert.deepEqual(files, ['one.css', 'two.css']);
|
550 | rimraf.sync(dest);
|
551 | done();
|
552 | });
|
553 | });
|
554 |
|
555 | it('should error if no output directory is provided', function(done) {
|
556 | var src = fixture('input-directory/sass');
|
557 | var bin = spawn(cli, [src]);
|
558 |
|
559 | bin.once('close', function(code) {
|
560 | assert.notStrictEqual(code, 0);
|
561 | assert.strictEqual(glob.sync(fixture('input-directory/**/*.css')).length, 0);
|
562 | done();
|
563 | });
|
564 | });
|
565 |
|
566 | it('should error if output directory is not a directory', function(done) {
|
567 | var src = fixture('input-directory/sass');
|
568 | var dest = fixture('input-directory/sass/one.scss');
|
569 | var bin = spawn(cli, [src, '--output', dest]);
|
570 |
|
571 | bin.once('close', function(code) {
|
572 | assert.notStrictEqual(code, 0);
|
573 | assert.equal(glob.sync(fixture('input-directory/**/*.css')).length, 0);
|
574 | done();
|
575 | });
|
576 | });
|
577 |
|
578 | it('should not error if output directory is a symlink', function(done) {
|
579 | var outputDir = fixture('input-directory/css');
|
580 | var src = fixture('input-directory/sass');
|
581 | var symlink = fixture('symlinked-css');
|
582 | fs.mkdirSync(outputDir);
|
583 | fs.symlinkSync(outputDir, symlink);
|
584 | var bin = spawn(cli, [src, '--output', symlink]);
|
585 |
|
586 | bin.once('close', function() {
|
587 | var files = fs.readdirSync(outputDir).sort();
|
588 | assert.deepEqual(files, ['one.css', 'two.css', 'nested'].sort());
|
589 | var nestedFiles = fs.readdirSync(path.join(outputDir, 'nested'));
|
590 | assert.deepEqual(nestedFiles, ['three.css']);
|
591 | rimraf.sync(outputDir);
|
592 | fs.unlinkSync(symlink);
|
593 | done();
|
594 | });
|
595 | });
|
596 | });
|
597 |
|
598 | describe('node-sass in.scss --output path/to/file/out.css', function() {
|
599 | it('should create the output directory', function(done) {
|
600 | var src = fixture('output-directory/index.scss');
|
601 | var dest = fixture('output-directory/path/to/file/index.css');
|
602 | var bin = spawn(cli, [src, '--output', path.dirname(dest)]);
|
603 |
|
604 | bin.once('close', function() {
|
605 | assert(fs.existsSync(path.dirname(dest)));
|
606 | fs.unlinkSync(dest);
|
607 | fs.rmdirSync(path.dirname(dest));
|
608 | dest = path.dirname(dest);
|
609 | fs.rmdirSync(path.dirname(dest));
|
610 | dest = path.dirname(dest);
|
611 | fs.rmdirSync(path.dirname(dest));
|
612 | done();
|
613 | });
|
614 | });
|
615 |
|
616 | });
|
617 |
|
618 | describe('node-sass --follow --output output-dir input-dir', function() {
|
619 | it('should compile with the --follow option', function(done) {
|
620 | var src = fixture('follow/input-dir');
|
621 | var dest = fixture('follow/output-dir');
|
622 |
|
623 | fs.mkdirSync(src);
|
624 | fs.symlinkSync(path.join(path.dirname(src), 'foo'), path.join(src, 'foo'), 'dir');
|
625 |
|
626 | var bin = spawn(cli, [src, '--follow', '--output', dest]);
|
627 |
|
628 | bin.once('close', function() {
|
629 | var expected = path.join(dest, 'foo/bar/index.css');
|
630 | fs.unlinkSync(path.join(src, 'foo'));
|
631 | fs.rmdirSync(src);
|
632 | assert(fs.existsSync(expected));
|
633 | fs.unlinkSync(expected);
|
634 | expected = path.dirname(expected);
|
635 | fs.rmdirSync(expected);
|
636 | expected = path.dirname(expected);
|
637 | fs.rmdirSync(expected);
|
638 | fs.rmdirSync(dest);
|
639 | done();
|
640 | });
|
641 | });
|
642 | });
|
643 |
|
644 | describe('importer', function() {
|
645 | var dest = fixture('include-files/index.css');
|
646 | var src = fixture('include-files/index.scss');
|
647 | var expected = read(fixture('include-files/expected-importer.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
648 |
|
649 | it('should override imports and fire callback with file and contents', function(done) {
|
650 | var bin = spawn(cli, [
|
651 | src, '--output', path.dirname(dest),
|
652 | '--importer', fixture('extras/my_custom_importer_file_and_data_cb.js')
|
653 | ]);
|
654 |
|
655 | bin.once('close', function() {
|
656 | assert.equal(read(dest, 'utf8').trim(), expected);
|
657 | fs.unlinkSync(dest);
|
658 | done();
|
659 | });
|
660 | });
|
661 |
|
662 | it('should override imports and fire callback with file', function(done) {
|
663 | var bin = spawn(cli, [
|
664 | src, '--output', path.dirname(dest),
|
665 | '--importer', fixture('extras/my_custom_importer_file_cb.js')
|
666 | ]);
|
667 |
|
668 | bin.once('close', function() {
|
669 | if (fs.existsSync(dest)) {
|
670 | assert.equal(read(dest, 'utf8').trim(), '');
|
671 | fs.unlinkSync(dest);
|
672 | }
|
673 |
|
674 | done();
|
675 | });
|
676 | });
|
677 |
|
678 | it('should override imports and fire callback with data', function(done) {
|
679 | var bin = spawn(cli, [
|
680 | src, '--output', path.dirname(dest),
|
681 | '--importer', fixture('extras/my_custom_importer_data_cb.js')
|
682 | ]);
|
683 |
|
684 | bin.once('close', function() {
|
685 | assert.equal(read(dest, 'utf8').trim(), expected);
|
686 | fs.unlinkSync(dest);
|
687 | done();
|
688 | });
|
689 | });
|
690 |
|
691 | it('should override imports and return file and contents', function(done) {
|
692 | var bin = spawn(cli, [
|
693 | src, '--output', path.dirname(dest),
|
694 | '--importer', fixture('extras/my_custom_importer_file_and_data.js')
|
695 | ]);
|
696 |
|
697 | bin.once('close', function() {
|
698 | assert.equal(read(dest, 'utf8').trim(), expected);
|
699 | fs.unlinkSync(dest);
|
700 | done();
|
701 | });
|
702 | });
|
703 |
|
704 | it('should override imports and return file', function(done) {
|
705 | var bin = spawn(cli, [
|
706 | src, '--output', path.dirname(dest),
|
707 | '--importer', fixture('extras/my_custom_importer_file.js')
|
708 | ]);
|
709 |
|
710 | bin.once('close', function() {
|
711 | if (fs.existsSync(dest)) {
|
712 | assert.equal(read(dest, 'utf8').trim(), '');
|
713 | fs.unlinkSync(dest);
|
714 | }
|
715 |
|
716 | done();
|
717 | });
|
718 | });
|
719 |
|
720 | it('should override imports and return data', function(done) {
|
721 | var bin = spawn(cli, [
|
722 | src, '--output', path.dirname(dest),
|
723 | '--importer', fixture('extras/my_custom_importer_data.js')
|
724 | ]);
|
725 |
|
726 | bin.once('close', function() {
|
727 | assert.equal(read(dest, 'utf8').trim(), expected);
|
728 | fs.unlinkSync(dest);
|
729 | done();
|
730 | });
|
731 | });
|
732 |
|
733 | it('should accept arrays of importers and return respect the order', function(done) {
|
734 | var bin = spawn(cli, [
|
735 | src, '--output', path.dirname(dest),
|
736 | '--importer', fixture('extras/my_custom_arrays_of_importers.js')
|
737 | ]);
|
738 |
|
739 | bin.once('close', function() {
|
740 | assert.equal(read(dest, 'utf8').trim(), expected);
|
741 | fs.unlinkSync(dest);
|
742 | done();
|
743 | });
|
744 | });
|
745 |
|
746 | it('should return error for invalid importer file path', function(done) {
|
747 | var bin = spawn(cli, [
|
748 | src, '--output', path.dirname(dest),
|
749 | '--importer', fixture('non/existing/path')
|
750 | ]);
|
751 |
|
752 | bin.once('close', function(code) {
|
753 | assert.notStrictEqual(code, 0);
|
754 | done();
|
755 | });
|
756 | });
|
757 |
|
758 | it('should reflect user-defined Error', function(done) {
|
759 | var bin = spawn(cli, [
|
760 | src, '--output', path.dirname(dest),
|
761 | '--importer', fixture('extras/my_custom_importer_error.js')
|
762 | ]);
|
763 |
|
764 | bin.stderr.once('data', function(code) {
|
765 | assert.equal(JSON.parse(code).message, 'doesn\'t exist!');
|
766 | done();
|
767 | });
|
768 | });
|
769 | });
|
770 |
|
771 | describe('functions', function() {
|
772 | it('should let custom functions call setter methods on wrapped sass values (number)', function(done) {
|
773 | var dest = fixture('custom-functions/setter.css');
|
774 | var src = fixture('custom-functions/setter.scss');
|
775 | var expected = read(fixture('custom-functions/setter-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
776 | var bin = spawn(cli, [
|
777 | src, '--output', path.dirname(dest),
|
778 | '--functions', fixture('extras/my_custom_functions_setter.js')
|
779 | ]);
|
780 |
|
781 | bin.once('close', function() {
|
782 | assert.equal(read(dest, 'utf8').trim(), expected);
|
783 | fs.unlinkSync(dest);
|
784 | done();
|
785 | });
|
786 | });
|
787 |
|
788 | it('should properly convert strings when calling custom functions', function(done) {
|
789 | var dest = fixture('custom-functions/string-conversion.css');
|
790 | var src = fixture('custom-functions/string-conversion.scss');
|
791 | var expected = read(fixture('custom-functions/string-conversion-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
792 | var bin = spawn(cli, [
|
793 | src, '--output', path.dirname(dest),
|
794 | '--functions', fixture('extras/my_custom_functions_string_conversion.js')
|
795 | ]);
|
796 |
|
797 | bin.once('close', function() {
|
798 | assert.equal(read(dest, 'utf8').trim(), expected);
|
799 | fs.unlinkSync(dest);
|
800 | done();
|
801 | });
|
802 | });
|
803 | });
|
804 | });
|