You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
794 lines
25 KiB
794 lines
25 KiB
2 years ago
|
var assert = require('assert').strict,
|
||
|
fs = require('fs'),
|
||
|
path = require('path'),
|
||
|
read = require('fs').readFileSync,
|
||
|
glob = require('glob'),
|
||
|
rimraf = require('rimraf'),
|
||
|
stream = require('stream'),
|
||
|
spawn = require('cross-spawn'),
|
||
|
cli = path.join(__dirname, '..', 'bin', 'node-sass'),
|
||
|
fixture = path.join.bind(null, __dirname, 'fixtures');
|
||
|
|
||
|
describe('cli', function() {
|
||
|
// For some reason we experience random timeout failures in CI
|
||
|
// due to spawn hanging/failing silently. See #1692.
|
||
|
this.retries(4);
|
||
|
|
||
|
describe('node-sass < in.scss', function() {
|
||
|
it('should read data from stdin', function(done) {
|
||
|
var src = fs.createReadStream(fixture('simple/index.scss'));
|
||
|
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
|
||
|
var bin = spawn(cli);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), expected.replace(/\r\n/g, '\n'));
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
src.pipe(bin.stdin);
|
||
|
});
|
||
|
|
||
|
it('should compile sass using the --indented-syntax option', function(done) {
|
||
|
var src = fs.createReadStream(fixture('indent/index.sass'));
|
||
|
var expected = read(fixture('indent/expected.css'), 'utf8').trim();
|
||
|
var bin = spawn(cli, ['--indented-syntax']);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), expected.replace(/\r\n/g, '\n'));
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
src.pipe(bin.stdin);
|
||
|
});
|
||
|
|
||
|
it('should compile with the --quiet option', function(done) {
|
||
|
var src = fs.createReadStream(fixture('simple/index.scss'));
|
||
|
var expected = read(fixture('simple/expected.css'), 'utf8').trim();
|
||
|
var bin = spawn(cli, ['--quiet']);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), expected.replace(/\r\n/g, '\n'));
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
src.pipe(bin.stdin);
|
||
|
});
|
||
|
|
||
|
it('should compile with the --output-style option', function(done) {
|
||
|
var src = fs.createReadStream(fixture('compressed/index.scss'));
|
||
|
var expected = read(fixture('compressed/expected.css'), 'utf8').trim();
|
||
|
var bin = spawn(cli, ['--output-style', 'compressed']);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), expected.replace(/\r\n/g, '\n'));
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
src.pipe(bin.stdin);
|
||
|
});
|
||
|
|
||
|
it('should compile with the --source-comments option', function(done) {
|
||
|
var src = fs.createReadStream(fixture('source-comments/index.scss'));
|
||
|
var expected = read(fixture('source-comments/expected.css'), 'utf8').trim();
|
||
|
var bin = spawn(cli, ['--source-comments']);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), expected.replace(/\r\n/g, '\n'));
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
src.pipe(bin.stdin);
|
||
|
});
|
||
|
|
||
|
it('should render with indentWidth and indentType options', function(done) {
|
||
|
var src = new stream.Readable();
|
||
|
var bin = spawn(cli, ['--indent-width', 7, '--indent-type', 'tab']);
|
||
|
|
||
|
src._read = function() { };
|
||
|
src.push('div { color: transparent; }');
|
||
|
src.push(null);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }');
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
src.pipe(bin.stdin);
|
||
|
});
|
||
|
|
||
|
it('should render with linefeed option', function(done) {
|
||
|
var src = new stream.Readable();
|
||
|
var bin = spawn(cli, ['--linefeed', 'lfcr']);
|
||
|
|
||
|
src._read = function() { };
|
||
|
src.push('div { color: transparent; }');
|
||
|
src.push(null);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), 'div {\n\r color: transparent; }');
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
src.pipe(bin.stdin);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('node-sass in.scss', function() {
|
||
|
it('should compile a scss file', function(done) {
|
||
|
var src = fixture('simple/index.scss');
|
||
|
var dest = fixture('simple/index.css');
|
||
|
var bin = spawn(cli, [src, dest]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert(fs.existsSync(dest));
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile a scss file to custom destination', function(done) {
|
||
|
var src = fixture('simple/index.scss');
|
||
|
var dest = fixture('simple/index-custom.css');
|
||
|
var bin = spawn(cli, [src, dest]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert(fs.existsSync(dest));
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile with the --include-path option', function(done) {
|
||
|
var includePaths = [
|
||
|
'--include-path', fixture('include-path/functions'),
|
||
|
'--include-path', fixture('include-path/lib')
|
||
|
];
|
||
|
|
||
|
var src = fixture('include-path/index.scss');
|
||
|
var expected = read(fixture('include-path/expected.css'), 'utf8').trim();
|
||
|
var bin = spawn(cli, [src].concat(includePaths));
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), expected.replace(/\r\n/g, '\n'));
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile silently using the --quiet option', function(done) {
|
||
|
var src = fixture('simple/index.scss');
|
||
|
var dest = fixture('simple/index.css');
|
||
|
var bin = spawn(cli, [src, dest, '--quiet']);
|
||
|
var didEmit = false;
|
||
|
|
||
|
bin.stderr.once('data', function() {
|
||
|
didEmit = true;
|
||
|
});
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(didEmit, false);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should still report errors with the --quiet option', function(done) {
|
||
|
var src = fixture('invalid/index.scss');
|
||
|
var dest = fixture('invalid/index.css');
|
||
|
var bin = spawn(cli, [src, dest, '--quiet']);
|
||
|
var didEmit = false;
|
||
|
|
||
|
bin.stderr.once('data', function() {
|
||
|
didEmit = true;
|
||
|
});
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(didEmit, true);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should not exit with the --watch option', function(done) {
|
||
|
var src = fixture('simple/index.scss');
|
||
|
var bin = spawn(cli, [src, '--watch']);
|
||
|
var exited;
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
exited = true;
|
||
|
});
|
||
|
|
||
|
setTimeout(function() {
|
||
|
if (exited) {
|
||
|
throw new Error('Watch ended too early!');
|
||
|
} else {
|
||
|
bin.kill();
|
||
|
done();
|
||
|
}
|
||
|
}, 100);
|
||
|
});
|
||
|
|
||
|
it.skip('should emit `warn` on file change when using --watch option', function(done) {
|
||
|
var src = fixture('simple/tmp.scss');
|
||
|
|
||
|
fs.writeFileSync(src, '');
|
||
|
|
||
|
var bin = spawn(cli, ['--watch', src]);
|
||
|
|
||
|
bin.stderr.setEncoding('utf8');
|
||
|
bin.stderr.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), '=> changed: ' + src);
|
||
|
fs.unlinkSync(src);
|
||
|
bin.kill();
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
setTimeout(function() {
|
||
|
fs.appendFileSync(src, 'body {}');
|
||
|
}, 500);
|
||
|
});
|
||
|
|
||
|
it.skip('should emit nothing on file change when using --watch and --quiet options', function(done) {
|
||
|
var src = fixture('simple/tmp.scss');
|
||
|
var didEmit = false;
|
||
|
fs.writeFileSync(src, '');
|
||
|
|
||
|
var bin = spawn(cli, ['--watch', '--quiet', src]);
|
||
|
|
||
|
bin.stderr.setEncoding('utf8');
|
||
|
bin.stderr.once('data', function() {
|
||
|
didEmit = true;
|
||
|
});
|
||
|
|
||
|
setTimeout(function() {
|
||
|
fs.appendFileSync(src, 'body {}');
|
||
|
setTimeout(function() {
|
||
|
assert.strictEqual(didEmit, false);
|
||
|
bin.kill();
|
||
|
done();
|
||
|
fs.unlinkSync(src);
|
||
|
}, 200);
|
||
|
}, 500);
|
||
|
});
|
||
|
|
||
|
it.skip('should render all watched files', function(done) {
|
||
|
var src = fixture('simple/bar.scss');
|
||
|
|
||
|
fs.writeFileSync(src, '');
|
||
|
|
||
|
var bin = spawn(cli, [
|
||
|
'--output-style', 'compressed',
|
||
|
'--watch', src
|
||
|
]);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), 'body{background:white}');
|
||
|
fs.unlinkSync(src);
|
||
|
bin.kill();
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
setTimeout(function() {
|
||
|
fs.appendFileSync(src, 'body{background:white}');
|
||
|
}, 500);
|
||
|
});
|
||
|
|
||
|
it.skip('should watch the full scss dep tree for a single file (scss)', function(done) {
|
||
|
var src = fixture('watching/index.scss');
|
||
|
var foo = fixture('watching/white.scss');
|
||
|
|
||
|
fs.writeFileSync(foo, '');
|
||
|
|
||
|
var bin = spawn(cli, [
|
||
|
'--output-style', 'compressed',
|
||
|
'--watch', src
|
||
|
]);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), 'body{background:blue}');
|
||
|
bin.kill();
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
setTimeout(function() {
|
||
|
fs.appendFileSync(foo, 'body{background:blue}\n');
|
||
|
}, 500);
|
||
|
});
|
||
|
|
||
|
it.skip('should watch the full sass dep tree for a single file (sass)', function(done) {
|
||
|
var src = fixture('watching/index.sass');
|
||
|
var foo = fixture('watching/bar.sass');
|
||
|
|
||
|
fs.writeFileSync(foo, '');
|
||
|
|
||
|
var bin = spawn(cli, [
|
||
|
'--output-style', 'compressed',
|
||
|
'--watch', src
|
||
|
]);
|
||
|
|
||
|
bin.stdout.setEncoding('utf8');
|
||
|
bin.stdout.once('data', function(data) {
|
||
|
assert.strictEqual(data.trim(), 'body{background:red}');
|
||
|
bin.kill();
|
||
|
done();
|
||
|
});
|
||
|
|
||
|
setTimeout(function() {
|
||
|
fs.appendFileSync(foo, 'body\n\tbackground: red\n');
|
||
|
}, 500);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('node-sass --output directory', function() {
|
||
|
it.skip('should watch whole directory', function(done) {
|
||
|
var destDir = fixture('watching-css-out-01/');
|
||
|
var srcDir = fixture('watching-dir-01/');
|
||
|
var srcFile = path.join(srcDir, 'index.scss');
|
||
|
|
||
|
fs.writeFileSync(srcFile, '');
|
||
|
|
||
|
var bin = spawn(cli, [
|
||
|
'--output-style', 'compressed',
|
||
|
'--output', destDir,
|
||
|
'--watch', srcDir
|
||
|
]);
|
||
|
|
||
|
setTimeout(function() {
|
||
|
fs.appendFileSync(srcFile, 'a {color:green;}\n');
|
||
|
setTimeout(function() {
|
||
|
bin.kill();
|
||
|
var files = fs.readdirSync(destDir);
|
||
|
assert.deepStrictEqual(files, ['index.css']);
|
||
|
rimraf(destDir, done);
|
||
|
}, 200);
|
||
|
}, 500);
|
||
|
});
|
||
|
|
||
|
it.skip('should compile all changed files in watched directory', function(done) {
|
||
|
var destDir = fixture('watching-css-out-02/');
|
||
|
var srcDir = fixture('watching-dir-02/');
|
||
|
var srcFile = path.join(srcDir, 'foo.scss');
|
||
|
|
||
|
fs.writeFileSync(srcFile, '');
|
||
|
|
||
|
var bin = spawn(cli, [
|
||
|
'--output-style', 'compressed',
|
||
|
'--output', destDir,
|
||
|
'--watch', srcDir
|
||
|
]);
|
||
|
|
||
|
setTimeout(function () {
|
||
|
fs.appendFileSync(srcFile, 'body{background:white}\n');
|
||
|
setTimeout(function () {
|
||
|
bin.kill();
|
||
|
var files = fs.readdirSync(destDir);
|
||
|
assert.deepStrictEqual(files, ['foo.css', 'index.css']);
|
||
|
rimraf(destDir, done);
|
||
|
}, 200);
|
||
|
}, 500);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('node-sass in.scss --output out.css', function() {
|
||
|
it('should compile a scss file to build.css', function(done) {
|
||
|
var src = fixture('simple/index.scss');
|
||
|
var dest = fixture('simple/index.css');
|
||
|
var bin = spawn(cli, [src, '--output', path.dirname(dest)]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert(fs.existsSync(dest));
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile with the --source-map option', function(done) {
|
||
|
var src = fixture('source-map/index.scss');
|
||
|
var destCss = fixture('source-map/index.css');
|
||
|
var destMap = fixture('source-map/index.map');
|
||
|
var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
var expectedMap = read(fixture('source-map/expected.map'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
var bin = spawn(cli, [src, '--output', path.dirname(destCss), '--source-map', destMap]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(destCss, 'utf8').trim(), expectedCss);
|
||
|
assert.strictEqual(read(destMap, 'utf8').trim(), expectedMap);
|
||
|
fs.unlinkSync(destCss);
|
||
|
fs.unlinkSync(destMap);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should omit sourceMappingURL if --omit-source-map-url flag is used', function(done) {
|
||
|
var src = fixture('source-map/index.scss');
|
||
|
var dest = fixture('source-map/index.css');
|
||
|
var map = fixture('source-map/index.map');
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--source-map', map, '--omit-source-map-url'
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').indexOf('sourceMappingURL'), -1);
|
||
|
assert(fs.existsSync(map));
|
||
|
fs.unlinkSync(map);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile with the --source-root option', function(done) {
|
||
|
var src = fixture('source-map/index.scss');
|
||
|
var destCss = fixture('source-map/index.css');
|
||
|
var destMap = fixture('source-map/index.map');
|
||
|
var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
var expectedUrl = 'http://test/';
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(destCss),
|
||
|
'--source-map-root', expectedUrl,
|
||
|
'--source-map', destMap
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(destCss, 'utf8').trim(), expectedCss);
|
||
|
assert.strictEqual(JSON.parse(read(destMap, 'utf8')).sourceRoot, expectedUrl);
|
||
|
fs.unlinkSync(destCss);
|
||
|
fs.unlinkSync(destMap);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile with the --source-map-embed option and no outfile', function(done) {
|
||
|
var src = fixture('source-map-embed/index.scss');
|
||
|
var expectedCss = read(fixture('source-map-embed/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
var result = '';
|
||
|
var bin = spawn(cli, [
|
||
|
src,
|
||
|
'--source-map-embed',
|
||
|
'--source-map', 'true'
|
||
|
]);
|
||
|
|
||
|
bin.stdout.on('data', function(data) {
|
||
|
result += data;
|
||
|
});
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(result.trim().replace(/\r\n/g, '\n'), expectedCss);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('node-sass sass/ --output css/', function() {
|
||
|
it('should create the output directory', function(done) {
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var dest = fixture('input-directory/css');
|
||
|
var bin = spawn(cli, [src, '--output', dest]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert(fs.existsSync(dest));
|
||
|
rimraf.sync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile all files in the folder', function(done) {
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var dest = fixture('input-directory/css');
|
||
|
var bin = spawn(cli, [src, '--output', dest]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
var files = fs.readdirSync(dest).sort();
|
||
|
assert.deepStrictEqual(files, ['one.css', 'two.css', 'nested'].sort());
|
||
|
var nestedFiles = fs.readdirSync(path.join(dest, 'nested'));
|
||
|
assert.deepStrictEqual(nestedFiles, ['three.css']);
|
||
|
rimraf.sync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should compile with --source-map set to directory', function(done) {
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var dest = fixture('input-directory/css');
|
||
|
var destMap = fixture('input-directory/map');
|
||
|
var bin = spawn(cli, [src, '--output', dest, '--source-map', destMap]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
var map = JSON.parse(read(fixture('input-directory/map/nested/three.css.map'), 'utf8'));
|
||
|
|
||
|
assert.strictEqual(map.file, '../../css/nested/three.css');
|
||
|
rimraf.sync(dest);
|
||
|
rimraf.sync(destMap);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should skip files with an underscore', function(done) {
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var dest = fixture('input-directory/css');
|
||
|
var bin = spawn(cli, [src, '--output', dest]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
var files = fs.readdirSync(dest);
|
||
|
assert.strictEqual(files.indexOf('_skipped.css'), -1);
|
||
|
rimraf.sync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should ignore nested files if --recursive false', function(done) {
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var dest = fixture('input-directory/css');
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', dest,
|
||
|
'--recursive', false
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
var files = fs.readdirSync(dest);
|
||
|
assert.deepStrictEqual(files, ['one.css', 'two.css']);
|
||
|
rimraf.sync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should error if no output directory is provided', function(done) {
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var bin = spawn(cli, [src]);
|
||
|
|
||
|
bin.once('close', function(code) {
|
||
|
assert.notStrictEqual(code, 0);
|
||
|
assert.strictEqual(glob.sync(fixture('input-directory/**/*.css')).length, 0);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should error if output directory is not a directory', function(done) {
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var dest = fixture('input-directory/sass/one.scss');
|
||
|
var bin = spawn(cli, [src, '--output', dest]);
|
||
|
|
||
|
bin.once('close', function(code) {
|
||
|
assert.notStrictEqual(code, 0);
|
||
|
assert.strictEqual(glob.sync(fixture('input-directory/**/*.css')).length, 0);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should not error if output directory is a symlink', function(done) {
|
||
|
var outputDir = fixture('input-directory/css');
|
||
|
var src = fixture('input-directory/sass');
|
||
|
var symlink = fixture('symlinked-css');
|
||
|
fs.mkdirSync(outputDir);
|
||
|
fs.symlinkSync(outputDir, symlink);
|
||
|
var bin = spawn(cli, [src, '--output', symlink]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
var files = fs.readdirSync(outputDir).sort();
|
||
|
assert.deepStrictEqual(files, ['one.css', 'two.css', 'nested'].sort());
|
||
|
var nestedFiles = fs.readdirSync(path.join(outputDir, 'nested'));
|
||
|
assert.deepStrictEqual(nestedFiles, ['three.css']);
|
||
|
rimraf.sync(outputDir);
|
||
|
fs.unlinkSync(symlink);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('node-sass in.scss --output path/to/file/out.css', function() {
|
||
|
it('should create the output directory', function(done) {
|
||
|
var src = fixture('output-directory/index.scss');
|
||
|
var dest = fixture('output-directory/path/to/file/index.css');
|
||
|
var bin = spawn(cli, [src, '--output', path.dirname(dest)]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert(fs.existsSync(path.dirname(dest)));
|
||
|
fs.unlinkSync(dest);
|
||
|
fs.rmdirSync(path.dirname(dest));
|
||
|
dest = path.dirname(dest);
|
||
|
fs.rmdirSync(path.dirname(dest));
|
||
|
dest = path.dirname(dest);
|
||
|
fs.rmdirSync(path.dirname(dest));
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
});
|
||
|
|
||
|
describe('node-sass --follow --output output-dir input-dir', function() {
|
||
|
it('should compile with the --follow option', function(done) {
|
||
|
var src = fixture('follow/input-dir');
|
||
|
var dest = fixture('follow/output-dir');
|
||
|
|
||
|
fs.mkdirSync(src);
|
||
|
fs.symlinkSync(path.join(path.dirname(src), 'foo'), path.join(src, 'foo'), 'dir');
|
||
|
|
||
|
var bin = spawn(cli, [src, '--follow', '--output', dest]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
var expected = path.join(dest, 'foo/bar/index.css');
|
||
|
fs.unlinkSync(path.join(src, 'foo'));
|
||
|
fs.rmdirSync(src);
|
||
|
assert(fs.existsSync(expected));
|
||
|
fs.unlinkSync(expected);
|
||
|
expected = path.dirname(expected);
|
||
|
fs.rmdirSync(expected);
|
||
|
expected = path.dirname(expected);
|
||
|
fs.rmdirSync(expected);
|
||
|
fs.rmdirSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('importer', function() {
|
||
|
var dest = fixture('include-files/index.css');
|
||
|
var src = fixture('include-files/index.scss');
|
||
|
var expectedData = read(fixture('include-files/expected-data-importer.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
var expectedFile = read(fixture('include-files/expected-file-importer.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
|
||
|
it('should override imports and fire callback with file and contents', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_importer_file_and_data_cb.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expectedData);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should override imports and fire callback with file', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_importer_file_cb.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
if (fs.existsSync(dest)) {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expectedFile);
|
||
|
fs.unlinkSync(dest);
|
||
|
}
|
||
|
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should override imports and fire callback with data', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_importer_data_cb.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expectedData);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should override imports and return file and contents', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_importer_file_and_data.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expectedData);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should override imports and return file', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_importer_file.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
if (fs.existsSync(dest)) {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expectedFile);
|
||
|
fs.unlinkSync(dest);
|
||
|
}
|
||
|
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should override imports and return data', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_importer_data.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expectedData);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should accept arrays of importers and return respect the order', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_arrays_of_importers.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expectedData);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should return error for invalid importer file path', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('non/existing/path')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function(code) {
|
||
|
assert.notStrictEqual(code, 0);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should reflect user-defined Error', function(done) {
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--importer', fixture('extras/my_custom_importer_error.js')
|
||
|
]);
|
||
|
|
||
|
bin.stderr.once('data', function(code) {
|
||
|
assert.strictEqual(JSON.parse(code).message, 'doesn\'t exist!');
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('functions', function() {
|
||
|
it('should let custom functions call setter methods on wrapped sass values (number)', function(done) {
|
||
|
var dest = fixture('custom-functions/setter.css');
|
||
|
var src = fixture('custom-functions/setter.scss');
|
||
|
var expected = read(fixture('custom-functions/setter-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--functions', fixture('extras/my_custom_functions_setter.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expected);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should properly convert strings when calling custom functions', function(done) {
|
||
|
var dest = fixture('custom-functions/string-conversion.css');
|
||
|
var src = fixture('custom-functions/string-conversion.scss');
|
||
|
var expected = read(fixture('custom-functions/string-conversion-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
|
||
|
var bin = spawn(cli, [
|
||
|
src, '--output', path.dirname(dest),
|
||
|
'--functions', fixture('extras/my_custom_functions_string_conversion.js')
|
||
|
]);
|
||
|
|
||
|
bin.once('close', function() {
|
||
|
assert.strictEqual(read(dest, 'utf8').trim(), expected);
|
||
|
fs.unlinkSync(dest);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|