Commit 535b5249 by Kevin Martensson

Cleanup tests

parent 4c65f3ad
var assert = require('assert'),
fs = require('fs'),
path = require('path'),
read = fs.readFileSync,
sass = require('../sass'),
fixture = path.join.bind(null, __dirname, 'fixtures');
describe('api (deprecated)', function() {
describe('.render(src, fn)', function() {
it('should compile sass to css', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8');
sass.render(src, function(err, css) {
assert(!err);
assert.equal(css, expected);
done();
});
});
it('should throw error for bad input', function(done) {
sass.render('#navbar width 80%;', function(err) {
assert(err);
done();
});
});
});
describe('.renderSync(src)', function() {
it('should compile sass to css', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8');
assert.equal(sass.renderSync(src), expected);
done();
});
it('should throw error for bad input', function(done) {
assert.throws(function() {
sass.renderSync('#navbar width 80%;');
});
done();
});
});
});
describe('api', function() {
describe('.render(options)', function() {
it('should compile sass to css', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8');
sass.render({
data: src,
success: function(css) {
assert.equal(css, expected);
done();
}
});
});
it('should throw error status 1 for bad input', function(done) {
sass.render({
data: '#navbar width 80%;',
error: function(err, status) {
assert(err);
assert.equal(status, 1);
done();
}
});
});
it('should compile with include paths', function(done) {
var src = read(fixture('include-path/index.scss'), 'utf8');
var expected = read(fixture('include-path/expected.css'), 'utf8');
sass.render({
data: src,
includePaths: [
fixture('include-path/functions'),
fixture('include-path/lib')
],
success: function(css) {
assert.equal(css, expected);
done();
}
});
});
it('should compile with include paths', function(done) {
var src = read(fixture('include-path/index.scss'), 'utf8');
var expected = read(fixture('include-path/expected.css'), 'utf8');
sass.render({
data: src,
includePaths: [
fixture('include-path/functions'),
fixture('include-path/lib')
],
success: function(css) {
assert.equal(css, expected);
done();
}
});
});
it('should compile with image path', function(done) {
var src = read(fixture('image-path/index.scss'), 'utf8');
var expected = read(fixture('image-path/expected.css'), 'utf8');
sass.render({
data: src,
imagePath: '/path/to/images',
success: function(css) {
assert.equal(css, expected);
done();
}
});
});
it('should throw error with non-string image path', function(done) {
var src = read(fixture('image-path/index.scss'), 'utf8');
assert.throws(function() {
sass.render({
data: src,
imagePath: ['/path/to/images']
});
});
done();
});
it('should render with --precision option', function(done) {
var src = read(fixture('precision/index.scss'), 'utf8');
var expected = read(fixture('precision/expected.css'), 'utf8');
sass.render({
data: src,
precision: 10,
success: function(css) {
assert.equal(css, expected);
done();
}
});
});
it('should compile with stats', function(done) {
var src = fixture('precision/index.scss');
var stats = {};
sass.render({
file: src,
stats: stats,
sourceMap: true,
success: function() {
assert.equal(stats.entry, src);
done();
}
});
});
});
describe('.renderSync(options)', function() {
it('should compile with renderSync', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var expected = read(fixture('simple/expected.css'), 'utf8');
assert.equal(sass.renderSync({ data: src }), expected);
done();
});
it('should throw error for bad input', function(done) {
assert.throws(function() {
sass.renderSync({ data: '#navbar width 80%;' });
});
done();
});
});
describe('.renderFile(options)', function() {
it('should compile with renderFile', function(done) {
var src = read(fixture('simple/index.scss'), 'utf8');
var dest = fixture('simple/build.css');
var expected = read(fixture('simple/expected.css'), 'utf8');
sass.renderFile({
data: src,
outFile: dest,
success: function() {
assert.equal(read(dest, 'utf8'), expected);
done();
}
});
});
it('should save source map to default name', function(done) {
var src = fixture('source-map/index.scss');
var dest = fixture('source-map/build.css');
var name = 'build.css.map';
sass.renderFile({
file: src,
outFile: dest,
sourceMap: true,
success: function(file, map) {
assert.equal(path.basename(map), name);
assert(read(dest, 'utf8').indexOf('sourceMappingURL=' + name) !== -1);
fs.unlinkSync(map);
fs.unlinkSync(dest);
done();
}
});
});
it('should save source map to specified name', function(done) {
var src = fixture('source-map/index.scss');
var dest = fixture('source-map/build.css');
var name = 'foo.css.map';
sass.renderFile({
file: src,
outFile: dest,
sourceMap: name,
success: function(file, map) {
assert.equal(path.basename(map), name);
assert(read(dest, 'utf8').indexOf('sourceMappingURL=' + name) !== -1);
fs.unlinkSync(map);
fs.unlinkSync(dest);
done();
}
});
});
it('should save source paths relative to the source map file', function(done) {
var src = fixture('include-files/index.scss');
var dest = fixture('include-files/build.css');
var obj;
sass.renderFile({
file: src,
outFile: dest,
sourceMap: true,
success: function(file, map) {
obj = JSON.parse(read(map, 'utf8'));
assert.equal(obj.sources[0], 'index.scss');
assert.equal(obj.sources[1], 'foo.scss');
assert.equal(obj.sources[2], 'bar.scss');
fs.unlinkSync(map);
fs.unlinkSync(dest);
done();
}
});
});
});
describe('.render({ stats: {} })', function() {
var start = Date.now();
var stats = {};
before(function (done) {
sass.render({
file: fixture('include-files/index.scss'),
stats: stats,
success: function () {
done();
},
error: function (err) {
assert(!err);
done();
}
});
});
it('should provide a start timestamp', function(done) {
assert(typeof stats.start === 'number');
assert(stats.start >= start);
done();
});
it('should provide an end timestamp', function(done) {
assert(typeof stats.end === 'number');
assert(stats.end >= stats.start);
done();
});
it('should provide a duration', function(done) {
assert(typeof stats.duration === 'number');
assert.equal(stats.end - stats.start, stats.duration);
done();
});
it('should contain the given entry file', function(done) {
assert.equal(stats.entry, fixture('include-files/index.scss'));
done();
});
it('should contain an array of all included files', function(done) {
assert.equal(stats.includedFiles[0], fixture('include-files/bar.scss'));
assert.equal(stats.includedFiles[1], fixture('include-files/foo.scss'));
assert.equal(stats.includedFiles[2], fixture('include-files/index.scss'));
done();
});
it('should contain array with the entry if there are no import statements', function(done) {
sass.render({
file: fixture('simple/index.scss'),
stats: stats,
success: function () {
assert.deepEqual(stats.includedFiles, [fixture('simple/index.scss')]);
done();
}
});
});
it('should state `data` as entry file', function(done) {
sass.render({
data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats,
success: function () {
assert.equal(stats.entry, 'data');
done();
}
});
});
it('should contain an empty array as includedFiles', function(done) {
sass.render({
data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats,
success: function () {
assert.deepEqual(stats.includedFiles, []);
done();
}
});
});
});
describe('.renderSync({ stats: {} })', function() {
var start = Date.now();
var stats = {};
before(function () {
sass.renderSync({
file: fixture('include-files/index.scss'),
stats: stats
});
});
it('should provide a start timestamp', function(done) {
assert(typeof stats.start === 'number');
assert(stats.start >= start);
done();
});
it('should provide an end timestamp', function(done) {
assert(typeof stats.end === 'number');
assert(stats.end >= stats.start);
done();
});
it('should provide a duration', function(done) {
assert(typeof stats.duration === 'number');
assert.equal(stats.end - stats.start, stats.duration);
done();
});
it('should contain the given entry file', function(done) {
assert.equal(stats.entry, fixture('include-files/index.scss'));
done();
});
it('should contain an array of all included files', function(done) {
assert.equal(stats.includedFiles[0], fixture('include-files/bar.scss'));
assert.equal(stats.includedFiles[1], fixture('include-files/foo.scss'));
assert.equal(stats.includedFiles[2], fixture('include-files/index.scss'));
done();
});
it('should contain array with the entry if there are no import statements', function(done) {
sass.renderSync({
file: fixture('simple/index.scss'),
stats: stats
});
assert.deepEqual(stats.includedFiles, [fixture('simple/index.scss')]);
done();
});
it('should state `data` as entry file', function(done) {
sass.renderSync({
data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats
});
assert.equal(stats.entry, 'data');
done();
});
it('should contain an empty array as includedFiles', function(done) {
sass.renderSync({
data: read(fixture('simple/index.scss'), 'utf8'),
stats: stats
});
assert.deepEqual(stats.includedFiles, []);
done();
});
});
});
var path = require('path'), var assert = require('assert'),
assert = require('assert'), fs = require('fs'),
fs = require('fs'), path = require('path'),
exec = require('child_process').exec, read = require('fs').readFileSync,
spawn = require('cross-spawn'), spawn = require('child_process').spawn,
assign = require('object-assign'), cli = path.join(__dirname, '..', 'bin', 'node-sass'),
cli = process.env.NODESASS_COVERAGE ? require('../lib-coverage/cli') : require('../lib/cli'), fixture = path.join.bind(null, __dirname, 'fixtures');
cliPath = path.resolve(__dirname, '../bin/node-sass'),
sampleFilename = path.resolve(__dirname, 'sample.scss');
var expectedSampleCompressed = '#navbar{width:80%;height:23px}\
#navbar ul{list-style-type:none}\
#navbar li{float:left}\
#navbar li a{font-weight:bold}';
var expectedSampleNoComments = '#navbar {\n\
width: 80%;\n\
height: 23px; }\n\
\n\
#navbar ul {\n\
list-style-type: none; }\n\
\n\
#navbar li {\n\
float: left; }\n\
#navbar li a {\n\
font-weight: bold; }\n';
var sampleFilenameFwdSlashes = sampleFilename.replace(/\\/g, '/');
var expectedSampleComments = '/* line 1, ' + sampleFilenameFwdSlashes + ' */\n\
#navbar {\n\
width: 80%;\n\
height: 23px; }\n\
\n\
/* line 5, ' + sampleFilenameFwdSlashes + ' */\n\
#navbar ul {\n\
list-style-type: none; }\n\
\n\
/* line 8, ' + sampleFilenameFwdSlashes + ' */\n\
#navbar li {\n\
float: left; }\n\
/* line 10, ' + sampleFilenameFwdSlashes + ' */\n\
#navbar li a {\n\
font-weight: bold; }\n';
var expectedSampleCustomImagePath = 'body {\n\
background-image: url("/path/to/images/image.png"); }\n';
var sampleScssPath = path.join(__dirname, 'sample.scss');
var sampleCssOutputPath = path.join(__dirname, '../sample.css');
var sampleCssMapOutputPath = path.join(__dirname, '../sample.css.map');
describe('cli', function() { describe('cli', function() {
it('should read data from stdin', function(done) { describe('node-sass < in.scss', function() {
this.timeout(6000); it('should read data from stdin', function(done) {
var src = fs.createReadStream(sampleScssPath); var src = fs.createReadStream(fixture('simple/index.scss'));
var emitter = spawn(cliPath, ['--stdout']); var expected = fixture('simple/expected.css');
var bin = spawn(cli, ['--stdout']);
emitter.stdout.on('data', function(data) {
data = data.toString().trim(); bin.stdout.setEncoding('utf8');
assert.equal(data, expectedSampleNoComments.trim()); bin.stdout.once('data', function(data) {
done(); assert.equal(data.trim(), read(expected, 'utf8').trim());
}); done();
});
src.pipe(emitter.stdin);
});
it('should write to disk when using --output', function(done) { src.pipe(bin.stdin);
this.timeout(6000);
var src = fs.createReadStream(sampleScssPath);
var emitter = spawn(cliPath, ['--output', sampleCssOutputPath], {
stdio: [null, 'ignore', null]
}); });
emitter.on('close', function() { it('should write to disk when using --output', function(done) {
fs.exists(sampleCssOutputPath, function(exists) { var src = fs.createReadStream(fixture('simple/index.scss'));
assert(exists); var dest = fixture('simple/build.css');
fs.unlink(sampleCssOutputPath, done); var bin = spawn(cli, ['--output', dest]);
bin.on('close', function() {
assert(fs.existsSync(dest));
fs.unlinkSync(dest);
done();
}); });
});
src.pipe(emitter.stdin); src.pipe(bin.stdin);
}); });
it('should treat data as indented code (.sass) if --indented-syntax flag is used', function(done) { it('should compile sass using the --indented-syntax option', function(done) {
this.timeout(6000); var src = fs.createReadStream(fixture('indent/index.sass'));
var src = fs.createReadStream(path.join(__dirname, 'indented.sass')); var expected = fixture('indent/expected.css');
var emitter = spawn(cliPath, ['--stdout', '--indented-syntax']); var bin = spawn(cli, ['--stdout', '--indented-syntax']);
// when hit the callback in the following, bin.stdout.setEncoding('utf8');
// it means that data is recieved, so we are ok to go. bin.stdout.once('data', function(data) {
emitter.stdout.on('data', function() { done(); }); assert.equal(data.trim(), read(expected, 'utf8').trim());
src.pipe(emitter.stdin); done();
}); });
it('should print usage when run with no arguments', function(done) { src.pipe(bin.stdin);
var env = assign(process.env, { isTTY: true });
exec('node ' + cliPath, {
env: env
}, function(err, stdout, stderr) {
done(assert(stderr.trim().indexOf('Provide a sass file to render') === 0));
}); });
});
it('should compile sample.scss as sample.css', function(done) { it('should compile with the --output-style option', function(done) {
this.timeout(6000); var src = fs.createReadStream(fixture('compressed/index.scss'));
var env = assign(process.env, { isTTY: true }); var expected = fixture('compressed/expected.css');
var resultPath = path.join(__dirname, 'sample.css'); var bin = spawn(cli, ['--stdout', '--output-style', 'compressed']);
exec('node ' + cliPath + ' ' + sampleFilename, { bin.stdout.setEncoding('utf8');
cwd: __dirname, bin.stdout.once('data', function(data) {
env: env assert.equal(data.trim(), read(expected, 'utf8').trim());
}, function(err) { done();
assert.equal(err, null);
fs.exists(resultPath, function(exists) {
assert(exists);
fs.unlink(resultPath, done);
}); });
});
});
it('should compile sample.scss as sample.css without isTTY', function(done) { src.pipe(bin.stdin);
this.timeout(6000); });
var env = assign(process.env, { isTTY: '' });
var resultPath = path.join(__dirname, 'sample.css');
exec('node ' + cliPath + ' ' + sampleFilename, { it('should compile with the --source-comments option', function(done) {
cwd: __dirname, var src = fs.createReadStream(fixture('source-comments/index.scss'));
env: env var expected = fixture('source-comments/expected.css');
}, function(err) { var bin = spawn(cli, ['--stdout', '--source-comments']);
assert.equal(err, null);
fs.exists(resultPath, function(exists) { bin.stdout.setEncoding('utf8');
assert(exists); bin.stdout.once('data', function(data) {
fs.unlink(resultPath, done); assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
}); });
});
});
it('should compile sample.scss to ../out.css', function(done) { src.pipe(bin.stdin);
this.timeout(6000); });
var env = assign(process.env, { isTTY: true });
var resultPath = path.resolve(__dirname, '../out.css');
exec('node ' + cliPath + ' ' + sampleFilename + ' ../out.css', { it('should compile with the --image-path option', function(done) {
cwd: __dirname, var src = fs.createReadStream(fixture('image-path/index.scss'));
env: env var expected = fixture('image-path/expected.css');
}, function(err) { var bin = spawn(cli, ['--stdout', '--image-path', '/path/to/images']);
assert.equal(err, null);
fs.exists(resultPath, function(exists) { bin.stdout.setEncoding('utf8');
assert(exists); bin.stdout.once('data', function(data) {
fs.unlink(resultPath, done); assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
}); });
});
});
it('should compile with --include-path option', function(done) {
var emitter = cli([
'--include-path', path.join(__dirname, 'lib'),
'--include-path', path.join(__dirname, 'functions'),
path.join(__dirname, 'include_path.scss')
]);
emitter.on('error', done);
emitter.on('write', function(err, file, css) {
assert.equal(css.trim(), 'body {\n background: red;\n color: #0000fe; }');
fs.unlink(file, done);
});
});
it('should compile with the --output-style', function(done) { src.pipe(bin.stdin);
var emitter = cli(['--output-style', 'compressed', sampleScssPath]);
emitter.on('error', done);
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleCompressed);
fs.unlink(file, done);
}); });
}); });
it('should compile with the --source-comments option', function(done) { describe('node-sass in.scss', function() {
var emitter = cli(['--source-comments', sampleScssPath]); it('should compile a scss file', function(done) {
emitter.on('error', done); process.chdir(fixture('simple'));
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleComments);
fs.unlink(file, done);
});
});
it('should compile with the --image-path option', function(done) { var src = fixture('simple/index.scss');
var emitter = cli(['--image-path', '/path/to/images', path.join(__dirname, 'image_path.scss')]); var dest = fixture('simple/index.css');
emitter.on('error', done); var bin = spawn(cli, [src]);
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleCustomImagePath);
fs.unlink(file, done);
});
});
it('should write the output to the file specified with the --output option', function(done) { bin.on('close', function() {
var resultPath = path.join(__dirname, '../output.css'); assert(fs.existsSync(dest));
var emitter = cli(['--output', resultPath, sampleScssPath]); fs.unlinkSync(dest);
emitter.on('error', done); process.chdir(__dirname);
emitter.on('write', function() { done();
fs.exists(resultPath, function(exists) {
assert(exists);
fs.unlink(resultPath, done);
}); });
}); });
});
it('should write to stdout with the --stdout option', function(done) { it('should compile with the --include-path option', function(done) {
var emitter = cli(['--stdout', sampleScssPath]); var includePaths = [
emitter.on('error', done); '--include-path', fixture('include-path/functions'),
emitter.on('log', function(css) { '--include-path', fixture('include-path/lib')
assert.equal(css, expectedSampleNoComments); ];
done();
}); var src = fixture('include-path/index.scss');
}); var expected = fixture('include-path/expected.css');
var bin = spawn(cli, [src, '--stdout'].concat(includePaths));
it('should not write to disk with the --stdout option', function(done) { bin.stdout.setEncoding('utf8');
var emitter = cli(['--stdout', sampleScssPath]); bin.stdout.once('data', function(data) {
emitter.on('error', done); assert.equal(data.trim(), read(expected, 'utf8').trim());
emitter.on('done', function() {
fs.exists(sampleCssOutputPath, function(exists) {
if (exists) {fs.unlinkSync(sampleCssOutputPath);}
assert(!exists);
done(); done();
}); });
}); });
});
it('should write to stdout with the --stdout option without isTTY', function(done) { it('should not exit with the --watch option', function(done) {
this.timeout(6000); var src = fixture('simple/index.scss');
var env = assign(process.env, { isTTY: '' }); var bin = spawn(cli, ['--stdout', '--watch', src]);
var exited;
exec('node ' + cliPath + ' --stdout ' + sampleScssPath, {
cwd: __dirname, bin.on('close', function () {
env: env exited = true;
}, function(err, stdout) { });
if (err) {
done(err);
} else {
assert.equal(stdout.replace(/[\n\r]$/, ''), expectedSampleNoComments);
done();
}
});
});
it('should not write to disk with the --stdout option without isTTY', function(done) { setTimeout(function() {
this.timeout(6000); if (exited) {
var env = assign(process.env, { isTTY: '' }); throw new Error('Watch ended too early!');
} else {
exec('node ' + cliPath + ' --stdout ' + sampleScssPath, { bin.kill();
cwd: __dirname,
env: env
}, function(err) {
if (err) {
done(err);
} else {
fs.exists(sampleCssOutputPath, function(exists) {
if (exists) {fs.unlinkSync(sampleCssOutputPath);}
assert(!exists);
done(); done();
}); }
} }, 100);
}); });
}); });
it('should not exit with the --watch option', function(done) { describe('node-sass in.scss --output out.css', function() {
var command = cliPath + ' --watch ' + sampleScssPath; it('should compile a scss file to build.css', function(done) {
var env = assign(process.env, { isTTY: true }); var src = fixture('simple/index.scss');
var child = exec('node ' + command, { var dest = fixture('simple/build.css');
env: env var bin = spawn(cli, [src, '--output', dest]);
});
var exited = false;
child.on('exit', function() {
exited = true;
});
setTimeout(function() { bin.on('close', function() {
if (exited){ assert(fs.existsSync(dest));
throw new Error('Watch ended too early!'); fs.unlinkSync(dest);
} else {
child.kill();
done(); done();
}
}, 100);
});
it('should compile with the --source-map option', function(done) {
var emitter = cli([sampleScssPath, '--source-map']);
emitter.on('error', done);
emitter.on('write-source-map', function(err, file) {
assert.equal(file, sampleCssMapOutputPath);
fs.exists(file, function(exists) {
assert(exists);
}); });
}); });
emitter.on('done', function() { it('should compile with the --source-map option', function(done) {
fs.unlink(sampleCssMapOutputPath, function() { var src = fixture('source-map/index.scss');
fs.unlink(sampleCssOutputPath, function() { var dest = fixture('source-map/build.css');
done(); var expected = fixture('source-map/expected.css');
}); var map = fixture('source-map/index.map');
}); var bin = spawn(cli, [src, '--output', dest, '--source-map', map]);
});
});
it('should compile with the --source-map option with specific filename', function(done){ bin.on('close', function () {
var emitter = cli([sampleScssPath, '--source-map', path.join(__dirname, '../sample.map')]); assert.equal(read(dest, 'utf8').trim(), read(expected, 'utf8').trim());
emitter.on('error', done); assert(fs.existsSync(map));
emitter.on('write-source-map', function(err, file) { fs.unlinkSync(map);
assert.equal(file, path.join(__dirname, '../sample.map')); fs.unlinkSync(dest);
fs.exists(file, function(exists) { done();
assert(exists);
});
});
emitter.on('done', function() {
fs.unlink(path.join(__dirname, '../sample.map'), function() {
fs.unlink(sampleCssOutputPath, function() {
done();
});
}); });
}); });
});
it('should not compile a sourceMap if --source-map option is excluded', function(done) { it('should omit sourceMappingURL if --omit-source-map-url flag is used', function(done) {
var emitter = cli([sampleScssPath, '--source-comments']); var src = fixture('source-map/index.scss');
emitter.on('error', done); var dest = fixture('source-map/build.css');
emitter.on('write-source-map', function(err, file) { var map = fixture('source-map/index.map');
assert.equal(file, sampleCssMapOutputPath); var bin = spawn(cli, [src, '--output', dest, '--source-map', map, '--omit-source-map-url']);
fs.exists(file, function(exists) {
assert(exists);
});
});
emitter.on('done', function() {
fs.unlink(sampleCssMapOutputPath, function() {
fs.unlink(sampleCssOutputPath, function() {
done();
});
});
});
});
it('should omit a sourceMappingURL from CSS if --omit-source-map-url flag is used', function(done) { bin.on('close', function () {
var emitter = cli([sampleScssPath, '--source-map', path.join(__dirname, '../sample.map'), '--omit-source-map-url']); assert(read(dest, 'utf8').indexOf('sourceMappingURL') === -1);
emitter.on('error', done); assert(fs.existsSync(map));
emitter.on('done', function() { fs.unlinkSync(map);
fs.exists(sampleCssOutputPath, function(exists) { fs.unlinkSync(dest);
assert.ok(fs.readFileSync(sampleCssOutputPath, 'utf8').indexOf('sourceMappingURL=') === -1);
if (exists) {fs.unlinkSync(sampleCssOutputPath);}
done(); done();
}); });
}); });
......
#navbar{width:80%;height:23px}#navbar ul{list-style-type:none}#navbar li{float:left}#navbar li a{font-weight:bold}
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
width: 80%; width: 80%;
height: 23px; height: 23px;
} }
#navbar ul { #navbar ul {
list-style-type: none; list-style-type: none;
} }
#navbar li { #navbar li {
float: left; float: left;
a { a {
font-weight: bold; font-weight: bold;
} }
......
body {
background-image: url("/path/to/images/image.png"); }
body { body {
background-image: image-url('image.png'); background-image: image-url('image.png');
} }
@import 'foo';
@import 'bar';
body {
background: red;
color: #0000fe; }
@import 'vars';
@import 'colorBlue';
body {
background: $color;
color: colorBlue();
}
foo + bar {
color: red; }
.foo {
margin: 1.23456789 px; }
.foo {
margin: 1.23456789 px;
}
#navbar {
width: 80%;
height: 23px; }
#navbar ul {
list-style-type: none; }
#navbar li {
float: left; }
#navbar li a {
font-weight: bold; }
#navbar {
width: 80%;
height: 23px;
}
#navbar ul {
list-style-type: none;
}
#navbar li {
float: left;
a {
font-weight: bold;
}
}
/* line 1, stdin */
#navbar {
width: 80%;
height: 23px; }
/* line 6, stdin */
#navbar ul {
list-style-type: none; }
/* line 10, stdin */
#navbar li {
float: left; }
/* line 13, stdin */
#navbar li a {
font-weight: bold; }
#navbar {
width: 80%;
height: 23px;
}
#navbar ul {
list-style-type: none;
}
#navbar li {
float: left;
a {
font-weight: bold;
}
}
#navbar {
width: 80%;
height: 23px; }
#navbar ul {
list-style-type: none; }
#navbar li {
float: left; }
#navbar li a {
font-weight: bold; }
/*# sourceMappingURL=index.map */
#navbar {
width: 80%;
height: 23px;
}
#navbar ul {
list-style-type: none;
}
#navbar li {
float: left;
a {
font-weight: bold;
}
}
@import "vars";
@import "colorBlue";
body { background: $color; color: colorBlue(); }
@import "sample.scss";
@import "image_path.scss";
This source diff could not be displayed because it is too large. You can view the blob instead.
// var util = require('util');
// var sass = require('../sass');
// var fs = require('fs');
//
// var bigScssStr = fs.readFileSync(require('path').resolve(__dirname,'large_test.scss'));
// var numTestCases = 1000;
// var numCompiled = 0;
// console.log(util.inspect(process.memoryUsage()));
// for (var i = 0; i < numTestCases; i++) {
// sass.render({
// data: bigScssStr,
// success: function() {
// numCompiled++;
// if (numCompiled === numTestCases) {
// console.log(util.inspect(process.memoryUsage()));
// }
// }
// });
// }
// var util = require('util');
// var sass = require('../sass');
// var fs = require('fs');
//
// var bigScssStr = fs.readFileSync(require('path').resolve(__dirname,'./large_test.scss'));
// var numTestCases = 1000;
// var numCompiled = 0;
// console.log(util.inspect(process.memoryUsage()));
// for (var i = 0; i < numTestCases; i++) {
// sass.renderSync({data: bigScssStr});
// }
// console.log(util.inspect(process.memoryUsage()));
exports.input = '#navbar {\
width: 80%;\
height: 23px; }\
#navbar ul {\
list-style-type: none; }\
#navbar li {\
float: left;\
a {\
font-weight: bold; }}\
@mixin keyAnimation($name, $attr, $value) {\
@-webkit-keyframes #{$name} {\
0% { #{$attr}: $value; }\
}\
}';
// Note that the bad
exports.badInput = '#navbar \n\
width: 80%';
exports.expectedRender = '#navbar {\n\
width: 80%;\n\
height: 23px; }\n\
\n\
#navbar ul {\n\
list-style-type: none; }\n\
\n\
#navbar li {\n\
float: left; }\n\
#navbar li a {\n\
font-weight: bold; }\n';
\ No newline at end of file
var assert = require('assert'),
fs = require('fs'),
path = require('path'),
sass = require('../sass');
var normalize = function(text) {
return text.replace(/\s+/g, '').replace('{', '{\n').replace(';', ';\n');
};
describe('sass-spec', function() {
var sassSpecPath = path.join(__dirname, 'sass-spec'),
sassSpecDirExists = fs.existsSync(sassSpecPath);
describe('spec directory', function() {
it('should be a cloned into place', function() {
try {
assert.ok(sassSpecDirExists);
} catch (e) {
console.log([
'test/sass-spec directory missing. Please clone it into place by',
'executing `git submodule update --init --recursive test/sass-spec`',
'from the project\'s root directory.'
].join(' '));
throw e;
}
});
});
if (sassSpecDirExists) {
var suitesPath = path.join(sassSpecPath, 'spec');
var suites = fs.readdirSync(suitesPath);
var ignoreSuites = ['libsass-todo-issues', 'libsass-todo-tests'];
suites.forEach(function(suite) {
if (ignoreSuites.indexOf(suite) !== -1) {
return;
}
describe(suite, function() {
var suitePath = path.join(suitesPath, suite);
var tests = fs.readdirSync(suitePath);
tests.forEach(function(test) {
var testPath = path.join(suitePath, test);
var inputFilePath = path.join(testPath, 'input.scss');
if (fs.existsSync(inputFilePath)) {
it(test, function(done) {
sass.render({
file: inputFilePath,
includePaths: [testPath, path.join(testPath, 'sub')],
success: function(css) {
var expected = fs.readFileSync(path.join(testPath, 'expected_output.css'), 'utf-8');
assert.equal(normalize(css), normalize(expected));
done();
},
error: function(error) {
done(new Error(error));
}
});
});
} else {
it(test);
}
});
});
});
}
});
var sass = require('../sass');
var assert = require('assert');
var sampleFilename = require('path').resolve(__dirname, 'sample.scss').replace(/\\/g, '/');
var expectedCommentsScssStr = '/* line 1, ' + sampleFilename + ' */\n\
#navbar {\n\
width: 80%;\n\
height: 23px; }\n\
\n\
/* line 5, ' + sampleFilename + ' */\n\
#navbar ul {\n\
list-style-type: none; }\n\
\n\
/* line 8, ' + sampleFilename + ' */\n\
#navbar li {\n\
float: left; }\n\
/* line 10, ' + sampleFilename + ' */\n\
#navbar li a {\n\
font-weight: bold; }\n';
describe('compile file with source comments', function() {
it('should compile with render and comment outputs', function(done) {
sass.render({
file: sampleFilename,
source_comments: 'map',
success: function (css) {
done(assert.equal(css, expectedCommentsScssStr));
},
error: function (error) {
done(error);
}
});
});
});
var sass = require('../sass');
var assert = require('assert');
var sampleFilename = require('path').resolve(__dirname, 'sample.scss');
describe('compile source maps', function() {
it('should compile file with source map URL', function(done) {
var mapFileName = 'sample.css.map';
sass.render({
file: sampleFilename,
sourceComments: 'map',
sourceMap: mapFileName,
success: function (css, map) {
assert.ok(css.indexOf('sourceMappingURL=' + mapFileName) !== -1);
assert.ok(map.indexOf('sample.scss') !== -1);
done();
},
error: function (error) {
done(error);
}
});
});
});
var assert = require('assert'),
fs = require('fs'),
exists = fs.existsSync,
path = require('path'),
read = fs.readFileSync,
sass = require('../sass'),
util = require('./util');
describe('spec', function () {
var suites = util.getSuites();
describe('test/sass-spec directory', function() {
it('should be a cloned into place', function(done) {
fs.exists(path.join(__dirname, 'sass-spec'), function (exists) {
if (!exists) {
throw new Error([
'test/sass-spec directory missing. Please clone it into place by',
'executing `git submodule update --init --recursive test/sass-spec`',
'from the project\'s root directory.'
].join(' '));
}
assert(exists);
done();
});
});
});
Object.keys(suites).forEach(function(suite) {
var tests = Object.keys(suites[suite]);
describe(suite, function () {
tests.forEach(function(test) {
var t = suites[suite][test];
if (exists(t.src)) {
it(test, function(done) {
var expected = util.normalize(read(t.expected, 'utf8'));
sass.render({
file: t.src,
includePaths: t.paths,
success: function(css) {
assert.equal(util.normalize(css), expected);
done();
},
error: function(err) {
assert(!err);
done();
}
});
});
}
});
});
});
});
'use strict';
var path = require('path');
var assert = require('assert');
var sass = process.env.NODESASS_COVERAGE ? require('../sass-coverage') : require('../sass');
var includedFilesFile = path.resolve(__dirname, 'included_files.scss').replace(/\\/g, '/');
var sampleFile = path.resolve(__dirname, 'sample.scss').replace(/\\/g, '/');
var imagePathFile = path.resolve(__dirname, 'image_path.scss').replace(/\\/g, '/');
var sample = require('./sample.js');
describe('stats', function() {
var start = Date.now();
var stats;
function checkTimingStats() {
it('should provide a start timestamp', function() {
assert.ok(typeof stats.start === 'number');
assert.ok(stats.start >= start);
});
it('should provide an end timestamp', function() {
assert.ok(typeof stats.end === 'number');
assert.ok(stats.end >= stats.start);
});
it('should provide a duration', function() {
assert.ok(typeof stats.duration === 'number');
assert.equal(stats.end - stats.start, stats.duration);
});
}
describe('using renderSync()', function() {
describe('and file-context', function() {
before(function() {
sass.renderSync({
file: includedFilesFile,
stats: stats = {}
});
});
checkTimingStats();
it('should contain the given entry file', function() {
assert.equal(stats.entry, includedFilesFile);
});
it('should contain an array of all included files', function() {
// the included_files aren't sorted by libsass in any way
assert.deepEqual(
stats.includedFiles.sort(),
[includedFilesFile, sampleFile, imagePathFile].sort()
);
});
it('should contain an array with the entry-file if the there are no import statements', function () {
sass.renderSync({
file: sampleFile,
stats: stats = {}
});
assert.deepEqual(stats.includedFiles, [sampleFile]);
});
});
describe('and data-context', function() {
before(function() {
sass.renderSync({
data: sample.input,
stats: stats = {}
});
});
checkTimingStats();
it('should state "data" as entry file', function() {
assert.equal(stats.entry, 'data');
});
it('should contain an empty array as includedFiles in the data-context', function() {
assert.deepEqual(stats.includedFiles, []);
});
});
});
describe('using render()', function () {
describe('and file-context', function() {
before(function(done) {
sass.render({
file: includedFilesFile,
stats: stats = {},
success: function() {
done();
},
error: done
});
});
checkTimingStats();
it('should contain the given entry file', function() {
assert.equal(stats.entry, includedFilesFile);
});
it('should contain an array of all included files', function() {
// the included_files aren't sorted by libsass in any way
assert.deepEqual(
stats.includedFiles.sort(),
[includedFilesFile, sampleFile, imagePathFile].sort()
);
});
it('should contain an array with the entry-file if the there are no import statements', function(done) {
sass.render({
file: sampleFile,
stats: stats = {},
success: function() {
assert.deepEqual(stats.includedFiles, [sampleFile]);
done();
},
error: done
});
});
});
describe('and data-context', function() {
before(function(done) {
sass.render({
data: sample.input,
stats: stats = {},
success: function() {
done();
},
error: done
});
});
checkTimingStats();
it('should state "data" as entry file', function() {
assert.equal(stats.entry, 'data');
});
it('should contain an empty array as includedFiles in the data-context', function() {
assert.deepEqual(stats.includedFiles, []);
});
});
});
});
var sass = process.env.NODESASS_COVERAGE ? require('../sass-coverage') : require('../sass');
var assert = require('assert');
var path = require('path');
var fs = require('fs');
var sinon = require('sinon');
var badSampleFilename = 'sample.scss';
var sampleFilename = path.resolve(__dirname, 'sample.scss');
var sample = require('./sample.js');
describe('DEPRECATED: compile scss', function() {
it('should compile with render', function(done) {
sass.render(sample.input, function(err) {
done(err);
});
});
it('should compile with renderSync', function(done) {
done(assert.ok(sass.renderSync(sample.input)));
});
it('should match compiled string with render', function(done) {
sass.render(sample.input, function(err, css) {
if (!err) {
done(assert.equal(css, sample.expectedRender));
} else {
done(err);
}
});
});
it('should match compiled string with renderSync', function(done) {
done(assert.equal(sass.renderSync(sample.input), sample.expectedRender));
});
it('should throw an exception for bad input', function(done) {
done(assert.throws(function() {
sass.renderSync(sample.badInput);
}));
});
});
describe('compile scss', function() {
it('should compile with render', function(done) {
sass.render({
data: sample.input,
success: function(css) {
done(assert.ok(css));
}
});
});
it('should compile with renderSync', function(done) {
done(assert.ok(sass.renderSync({data: sample.input})));
});
it('should match compiled string with render', function(done) {
sass.render({
data: sample.input,
success: function(css) {
done(assert.equal(css, sample.expectedRender));
},
error: function(error) {
done(error);
}
});
});
it('should have a error status of 1 for bad css', function(done) {
sass.render({
data: '{zzz}',
success: function(css) {
console.log(css);
},
error: function(error, status) {
assert.equal(status, 1);
done();
}
});
});
it('should match compiled string with renderSync', function(done) {
done(assert.equal(sass.renderSync({data: sample.input}), sample.expectedRender));
});
it('should throw an exception for bad input', function(done) {
done(assert.throws(function() {
sass.renderSync({data: sample.badInput});
}));
});
});
describe('compile file with include paths', function(){
it('should compile with render', function(done) {
sass.render({
file: path.resolve(__dirname, 'include_path.scss'),
includePaths: [path.resolve(__dirname, 'lib'), path.resolve(__dirname, 'functions')],
success: function (css) {
done(assert.equal(css, 'body {\n background: red;\n color: #0000fe; }\n'));
},
error: function (error) {
done(error);
}
});
});
it('should compile with renderFile', function(done) {
var testFile = path.resolve(__dirname, 'tmp-include-path.css');
sass.renderFile({
file: path.resolve(__dirname, 'include_path.scss'),
outFile: testFile,
includePaths: [path.resolve(__dirname, 'lib'), path.resolve(__dirname, 'functions')],
success: function () {
done(assert.equal(fs.readFileSync(testFile, 'utf8'), 'body {\n background: red;\n color: #0000fe; }\n'));
fs.unlinkSync(testFile);
},
error: function (error) {
done(error);
}
});
});
});
describe('compile file with image path', function(){
it('should compile with render', function(done) {
sass.render({
file: path.resolve(__dirname, 'image_path.scss'),
imagePath: '/path/to/images',
success: function (css) {
done(assert.equal(css, 'body {\n background-image: url("/path/to/images/image.png"); }\n'));
},
error: function (error) {
done(error);
}
});
});
it('should throw on non-string path', function(done) {
try {
sass.render({
file: path.resolve(__dirname, 'image_path.scss'),
imagePath: ['/path/to/images'],
success: function () {},
error: function () {}
});
} catch(err) {
assert(err);
return done();
}
done(new Error('did not throw'));
});
});
describe('compile file', function() {
it('should compile with render', function(done) {
sass.render({
file: sampleFilename,
success: function (css) {
done(assert.equal(css, sample.expectedRender));
},
error: function (error) {
done(error);
}
});
});
it('should compile with renderSync', function(done) {
done(assert.ok(sass.renderSync({file: sampleFilename})));
});
it('should match compiled string with render', function(done) {
sass.render({
file: sampleFilename,
success: function(css) {
done(assert.equal(css, sample.expectedRender));
},
error: function(error) {
done(error);
}
});
});
it('should match compiled string with renderSync', function(done) {
done(assert.equal(sass.renderSync({file: sampleFilename}), sample.expectedRender));
});
it('should throw an exception for bad input', function(done) {
done(assert.throws(function() {
sass.renderSync({file: badSampleFilename});
}));
});
});
describe('render to file', function() {
var outFile = path.resolve(__dirname, 'out.css'),
filesWritten;
beforeEach(function() {
filesWritten = {};
sinon.stub(fs, 'writeFile', function(path, contents, cb) {
filesWritten[path] = contents;
cb();
});
});
afterEach(function() {
fs.writeFile.restore();
});
it('should compile with renderFile', function(done) {
sass.renderFile({
file: sampleFilename,
outFile: outFile,
success: function () {
var contents = filesWritten[outFile];
done(assert.equal(contents, sample.expectedRender));
},
error: function (error) {
done(error);
}
});
});
it('should raise an error for bad input', function(done) {
sass.renderFile({
file: badSampleFilename,
outFile: outFile,
success: function() {
assert(false, 'success() should not be called');
done();
},
error: function() {
assert(true, 'error() called');
done();
}
});
});
it('should save the sourceMap to the default file name', function(done) {
sass.renderFile({
file: sampleFilename,
outFile: outFile,
sourceMap: true,
success: function (cssFile, sourceMapFile) {
var css = filesWritten[cssFile];
var map = filesWritten[sourceMapFile];
var mapFileName = 'out.css.map';
assert.equal(path.basename(sourceMapFile), mapFileName);
assert.ok(css.indexOf('sourceMappingURL=' + mapFileName) !== -1);
assert.ok(map.indexOf('sample.scss') !== -1);
done();
},
error: function (error) {
done(error);
}
});
});
it('should save the sourceMap to a specified file name', function(done) {
var mapFileName = 'foo.css.map';
sass.renderFile({
file: sampleFilename,
outFile: outFile,
sourceMap: mapFileName,
success: function (cssFile, sourceMapFile) {
var css = filesWritten[cssFile];
var map = filesWritten[sourceMapFile];
assert.equal(path.basename(sourceMapFile), mapFileName);
assert.ok(css.indexOf('sourceMappingURL=' + mapFileName) !== -1);
assert.ok(map.indexOf('sample.scss') !== -1);
done();
},
error: function (error) {
done(error);
}
});
});
it('should save source paths relative to the sourceMap file', function(done) {
var includedFilesFile = path.resolve(__dirname, 'included_files.scss');
var relativeOutFile = path.resolve(__dirname, 'some_path/out.scss');
sass.renderFile({
file: includedFilesFile,
outFile: relativeOutFile,
sourceMap: true,
success: function (cssFile, sourceMapFile) {
var mapObject = JSON.parse(filesWritten[sourceMapFile]);
assert.ok(mapObject.sources.indexOf('../included_files.scss') > -1);
assert.ok(mapObject.sources.indexOf('../sample.scss') > -1);
assert.ok(mapObject.sources.indexOf('../image_path.scss') > -1);
done();
},
error: function (error) {
done(error);
}
});
});
});
describe('precision support', function() {
it('should render when precision is specified', function(done) {
sass.render({
data: '.test { margin: 1.23456789 px; }',
precision: 10,
success: function(css) {
done(assert.equal(css, '.test {\n margin: 1.23456789 px; }\n'));
},
error: function(error) {
done(error);
}
});
});
});
describe('compile with stats', function() {
it('should report correct sourceMap in stats with renderSync', function(done) {
var stats = {};
sass.renderSync({
file: sampleFilename,
stats: stats,
sourceMap: true
});
done(assert.ok(stats.sourceMap.indexOf('sample.scss') !== -1));
});
});
var fs = require('fs'),
join = require('path').join,
spec = join(__dirname, '..', 'sass-spec', 'spec');
/**
* Normalize CSS
*
* @param {String} css
* @api public
*/
module.exports.normalize = function(str) {
return str.replace(/\s+/g, '').replace('{', '{\n').replace(';', ';\n');
};
/**
* Get test suites
*
* @api public
*/
module.exports.getSuites = function() {
var ret = {};
var suites = fs.readdirSync(spec);
var ignoreSuites = [
'libsass-todo-issues',
'libsass-todo-tests'
];
suites.forEach(function(suite) {
if (ignoreSuites.indexOf(suite) !== -1) {
return;
}
var suitePath = join(spec, suite);
var tests = fs.readdirSync(suitePath);
ret[suite] = {};
tests.forEach(function(test) {
var testPath = join(suitePath, test);
ret[suite][test] = {};
ret[suite][test].src = join(testPath, 'input.scss');
ret[suite][test].expected = join(testPath, 'expected_output.css');
ret[suite][test].paths = [
testPath,
join(testPath, 'sub')
];
});
});
return ret;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment