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'),
assert = require('assert'),
var assert = require('assert'),
fs = require('fs'),
exec = require('child_process').exec,
spawn = require('cross-spawn'),
assign = require('object-assign'),
cli = process.env.NODESASS_COVERAGE ? require('../lib-coverage/cli') : require('../lib/cli'),
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');
path = require('path'),
read = require('fs').readFileSync,
spawn = require('child_process').spawn,
cli = path.join(__dirname, '..', 'bin', 'node-sass'),
fixture = path.join.bind(null, __dirname, 'fixtures');
describe('cli', function() {
describe('node-sass < in.scss', function() {
it('should read data from stdin', function(done) {
this.timeout(6000);
var src = fs.createReadStream(sampleScssPath);
var emitter = spawn(cliPath, ['--stdout']);
var src = fs.createReadStream(fixture('simple/index.scss'));
var expected = fixture('simple/expected.css');
var bin = spawn(cli, ['--stdout']);
emitter.stdout.on('data', function(data) {
data = data.toString().trim();
assert.equal(data, expectedSampleNoComments.trim());
bin.stdout.setEncoding('utf8');
bin.stdout.once('data', function(data) {
assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
});
src.pipe(emitter.stdin);
src.pipe(bin.stdin);
});
it('should write to disk when using --output', function(done) {
this.timeout(6000);
var src = fs.createReadStream(sampleScssPath);
var emitter = spawn(cliPath, ['--output', sampleCssOutputPath], {
stdio: [null, 'ignore', null]
});
var src = fs.createReadStream(fixture('simple/index.scss'));
var dest = fixture('simple/build.css');
var bin = spawn(cli, ['--output', dest]);
emitter.on('close', function() {
fs.exists(sampleCssOutputPath, function(exists) {
assert(exists);
fs.unlink(sampleCssOutputPath, done);
});
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) {
this.timeout(6000);
var src = fs.createReadStream(path.join(__dirname, 'indented.sass'));
var emitter = spawn(cliPath, ['--stdout', '--indented-syntax']);
it('should compile sass using the --indented-syntax option', function(done) {
var src = fs.createReadStream(fixture('indent/index.sass'));
var expected = fixture('indent/expected.css');
var bin = spawn(cli, ['--stdout', '--indented-syntax']);
// when hit the callback in the following,
// it means that data is recieved, so we are ok to go.
emitter.stdout.on('data', function() { done(); });
src.pipe(emitter.stdin);
bin.stdout.setEncoding('utf8');
bin.stdout.once('data', function(data) {
assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
});
it('should print usage when run with no arguments', function(done) {
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));
src.pipe(bin.stdin);
});
});
it('should compile sample.scss as sample.css', function(done) {
this.timeout(6000);
var env = assign(process.env, { isTTY: true });
var resultPath = path.join(__dirname, 'sample.css');
exec('node ' + cliPath + ' ' + sampleFilename, {
cwd: __dirname,
env: env
}, function(err) {
assert.equal(err, null);
it('should compile with the --output-style option', function(done) {
var src = fs.createReadStream(fixture('compressed/index.scss'));
var expected = fixture('compressed/expected.css');
var bin = spawn(cli, ['--stdout', '--output-style', 'compressed']);
fs.exists(resultPath, function(exists) {
assert(exists);
fs.unlink(resultPath, done);
});
});
bin.stdout.setEncoding('utf8');
bin.stdout.once('data', function(data) {
assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
});
it('should compile sample.scss as sample.css without isTTY', function(done) {
this.timeout(6000);
var env = assign(process.env, { isTTY: '' });
var resultPath = path.join(__dirname, 'sample.css');
exec('node ' + cliPath + ' ' + sampleFilename, {
cwd: __dirname,
env: env
}, function(err) {
assert.equal(err, null);
fs.exists(resultPath, function(exists) {
assert(exists);
fs.unlink(resultPath, done);
});
src.pipe(bin.stdin);
});
});
it('should compile sample.scss to ../out.css', function(done) {
this.timeout(6000);
var env = assign(process.env, { isTTY: true });
var resultPath = path.resolve(__dirname, '../out.css');
exec('node ' + cliPath + ' ' + sampleFilename + ' ../out.css', {
cwd: __dirname,
env: env
}, function(err) {
assert.equal(err, null);
fs.exists(resultPath, function(exists) {
assert(exists);
fs.unlink(resultPath, done);
});
});
});
it('should compile with the --source-comments option', function(done) {
var src = fs.createReadStream(fixture('source-comments/index.scss'));
var expected = fixture('source-comments/expected.css');
var bin = spawn(cli, ['--stdout', '--source-comments']);
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);
});
bin.stdout.setEncoding('utf8');
bin.stdout.once('data', function(data) {
assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
});
it('should compile with the --output-style', function(done) {
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) {
var emitter = cli(['--source-comments', sampleScssPath]);
emitter.on('error', done);
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleComments);
fs.unlink(file, done);
});
src.pipe(bin.stdin);
});
it('should compile with the --image-path option', function(done) {
var emitter = cli(['--image-path', '/path/to/images', path.join(__dirname, 'image_path.scss')]);
emitter.on('error', done);
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleCustomImagePath);
fs.unlink(file, done);
});
});
var src = fs.createReadStream(fixture('image-path/index.scss'));
var expected = fixture('image-path/expected.css');
var bin = spawn(cli, ['--stdout', '--image-path', '/path/to/images']);
it('should write the output to the file specified with the --output option', function(done) {
var resultPath = path.join(__dirname, '../output.css');
var emitter = cli(['--output', resultPath, sampleScssPath]);
emitter.on('error', done);
emitter.on('write', function() {
fs.exists(resultPath, function(exists) {
assert(exists);
fs.unlink(resultPath, done);
});
});
});
it('should write to stdout with the --stdout option', function(done) {
var emitter = cli(['--stdout', sampleScssPath]);
emitter.on('error', done);
emitter.on('log', function(css) {
assert.equal(css, expectedSampleNoComments);
bin.stdout.setEncoding('utf8');
bin.stdout.once('data', function(data) {
assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
});
});
it('should not write to disk with the --stdout option', function(done) {
var emitter = cli(['--stdout', sampleScssPath]);
emitter.on('error', done);
emitter.on('done', function() {
fs.exists(sampleCssOutputPath, function(exists) {
if (exists) {fs.unlinkSync(sampleCssOutputPath);}
assert(!exists);
done();
});
src.pipe(bin.stdin);
});
});
it('should write to stdout with the --stdout option without isTTY', function(done) {
this.timeout(6000);
var env = assign(process.env, { isTTY: '' });
describe('node-sass in.scss', function() {
it('should compile a scss file', function(done) {
process.chdir(fixture('simple'));
exec('node ' + cliPath + ' --stdout ' + sampleScssPath, {
cwd: __dirname,
env: env
}, function(err, stdout) {
if (err) {
done(err);
} else {
assert.equal(stdout.replace(/[\n\r]$/, ''), expectedSampleNoComments);
var src = fixture('simple/index.scss');
var dest = fixture('simple/index.css');
var bin = spawn(cli, [src]);
bin.on('close', function() {
assert(fs.existsSync(dest));
fs.unlinkSync(dest);
process.chdir(__dirname);
done();
}
});
});
it('should not write to disk with the --stdout option without isTTY', function(done) {
this.timeout(6000);
var env = assign(process.env, { isTTY: '' });
it('should compile with the --include-path option', function(done) {
var includePaths = [
'--include-path', fixture('include-path/functions'),
'--include-path', fixture('include-path/lib')
];
exec('node ' + cliPath + ' --stdout ' + sampleScssPath, {
cwd: __dirname,
env: env
}, function(err) {
if (err) {
done(err);
} else {
fs.exists(sampleCssOutputPath, function(exists) {
if (exists) {fs.unlinkSync(sampleCssOutputPath);}
assert(!exists);
var src = fixture('include-path/index.scss');
var expected = fixture('include-path/expected.css');
var bin = spawn(cli, [src, '--stdout'].concat(includePaths));
bin.stdout.setEncoding('utf8');
bin.stdout.once('data', function(data) {
assert.equal(data.trim(), read(expected, 'utf8').trim());
done();
});
}
});
});
it('should not exit with the --watch option', function(done) {
var command = cliPath + ' --watch ' + sampleScssPath;
var env = assign(process.env, { isTTY: true });
var child = exec('node ' + command, {
env: env
});
var exited = false;
var src = fixture('simple/index.scss');
var bin = spawn(cli, ['--stdout', '--watch', src]);
var exited;
child.on('exit', function() {
bin.on('close', function () {
exited = true;
});
setTimeout(function() {
if (exited){
if (exited) {
throw new Error('Watch ended too early!');
} else {
child.kill();
bin.kill();
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() {
fs.unlink(sampleCssMapOutputPath, function() {
fs.unlink(sampleCssOutputPath, function() {
done();
});
});
});
});
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/build.css');
var bin = spawn(cli, [src, '--output', dest]);
it('should compile with the --source-map option with specific filename', function(done){
var emitter = cli([sampleScssPath, '--source-map', path.join(__dirname, '../sample.map')]);
emitter.on('error', done);
emitter.on('write-source-map', function(err, file) {
assert.equal(file, path.join(__dirname, '../sample.map'));
fs.exists(file, function(exists) {
assert(exists);
});
});
emitter.on('done', function() {
fs.unlink(path.join(__dirname, '../sample.map'), function() {
fs.unlink(sampleCssOutputPath, function() {
bin.on('close', function() {
assert(fs.existsSync(dest));
fs.unlinkSync(dest);
done();
});
});
});
});
it('should not compile a sourceMap if --source-map option is excluded', function(done) {
var emitter = cli([sampleScssPath, '--source-comments']);
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() {
fs.unlink(sampleCssMapOutputPath, function() {
fs.unlink(sampleCssOutputPath, function() {
it('should compile with the --source-map option', function(done) {
var src = fixture('source-map/index.scss');
var dest = fixture('source-map/build.css');
var expected = fixture('source-map/expected.css');
var map = fixture('source-map/index.map');
var bin = spawn(cli, [src, '--output', dest, '--source-map', map]);
bin.on('close', function () {
assert.equal(read(dest, 'utf8').trim(), read(expected, 'utf8').trim());
assert(fs.existsSync(map));
fs.unlinkSync(map);
fs.unlinkSync(dest);
done();
});
});
});
});
it('should omit a sourceMappingURL from CSS if --omit-source-map-url flag is used', function(done) {
var emitter = cli([sampleScssPath, '--source-map', path.join(__dirname, '../sample.map'), '--omit-source-map-url']);
emitter.on('error', done);
emitter.on('done', function() {
fs.exists(sampleCssOutputPath, function(exists) {
assert.ok(fs.readFileSync(sampleCssOutputPath, 'utf8').indexOf('sourceMappingURL=') === -1);
if (exists) {fs.unlinkSync(sampleCssOutputPath);}
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/build.css');
var map = fixture('source-map/index.map');
var bin = spawn(cli, [src, '--output', dest, '--source-map', map, '--omit-source-map-url']);
bin.on('close', function () {
assert(read(dest, 'utf8').indexOf('sourceMappingURL') === -1);
assert(fs.existsSync(map));
fs.unlinkSync(map);
fs.unlinkSync(dest);
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 @@
width: 80%;
height: 23px;
}
#navbar ul {
list-style-type: none;
}
#navbar li {
float: left;
a {
font-weight: bold;
}
......
body {
background-image: url("/path/to/images/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