From 6eec0355b06e6cc4f9134533075ddacfff04b8a4 Mon Sep 17 00:00:00 2001 From: Marcel Greter Date: Fri, 31 Oct 2014 16:57:52 +0100 Subject: [PATCH] Adds more unit tests --- index.css | 11 ++ test/functions/colorBlue.scss | 3 + test/image_path.scss | 3 + test/include_path.scss | 4 + test/included_files.scss | 2 + test/index.css | 11 ++ test/lib/vars.scss | 1 + test/sample.js | 30 ++++ test/sample.scss | 13 ++ test/test.js | 326 ++++++++++++++++++++++++++++++++++ 10 files changed, 404 insertions(+) create mode 100644 index.css create mode 100644 test/functions/colorBlue.scss create mode 100644 test/image_path.scss create mode 100644 test/include_path.scss create mode 100644 test/included_files.scss create mode 100644 test/index.css create mode 100644 test/lib/vars.scss create mode 100644 test/sample.js create mode 100644 test/sample.scss create mode 100644 test/test.js diff --git a/index.css b/index.css new file mode 100644 index 000000000..402ae50dd --- /dev/null +++ b/index.css @@ -0,0 +1,11 @@ +#navbar { + width: 80%; + height: 23px; } + +#navbar ul { + list-style-type: none; } + +#navbar li { + float: left; } + #navbar li a { + font-weight: bold; } diff --git a/test/functions/colorBlue.scss b/test/functions/colorBlue.scss new file mode 100644 index 000000000..4fa618cb1 --- /dev/null +++ b/test/functions/colorBlue.scss @@ -0,0 +1,3 @@ +@function colorBlue() { + @return #0000fe; +} diff --git a/test/image_path.scss b/test/image_path.scss new file mode 100644 index 000000000..c955e8b69 --- /dev/null +++ b/test/image_path.scss @@ -0,0 +1,3 @@ +body { + background-image: image-url('image.png'); +} diff --git a/test/include_path.scss b/test/include_path.scss new file mode 100644 index 000000000..8ee2b7fec --- /dev/null +++ b/test/include_path.scss @@ -0,0 +1,4 @@ +@import "vars"; +@import "colorBlue"; + +body { background: $color; color: colorBlue(); } diff --git a/test/included_files.scss b/test/included_files.scss new file mode 100644 index 000000000..c26d51ef8 --- /dev/null +++ b/test/included_files.scss @@ -0,0 +1,2 @@ +@import "sample.scss"; +@import "image_path.scss"; diff --git a/test/index.css b/test/index.css new file mode 100644 index 000000000..402ae50dd --- /dev/null +++ b/test/index.css @@ -0,0 +1,11 @@ +#navbar { + width: 80%; + height: 23px; } + +#navbar ul { + list-style-type: none; } + +#navbar li { + float: left; } + #navbar li a { + font-weight: bold; } diff --git a/test/lib/vars.scss b/test/lib/vars.scss new file mode 100644 index 000000000..a625dd9c4 --- /dev/null +++ b/test/lib/vars.scss @@ -0,0 +1 @@ +$color: red; \ No newline at end of file diff --git a/test/sample.js b/test/sample.js new file mode 100644 index 000000000..73e9d1fba --- /dev/null +++ b/test/sample.js @@ -0,0 +1,30 @@ +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 diff --git a/test/sample.scss b/test/sample.scss new file mode 100644 index 000000000..75086c309 --- /dev/null +++ b/test/sample.scss @@ -0,0 +1,13 @@ +#navbar { + width: 80%; + height: 23px; +} +#navbar ul { + list-style-type: none; +} +#navbar li { + float: left; + a { + font-weight: bold; + } +} diff --git a/test/test.js b/test/test.js new file mode 100644 index 000000000..17e35f887 --- /dev/null +++ b/test/test.js @@ -0,0 +1,326 @@ +var sass = require('../lib'); +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: 'test.map' + }); + + done(assert.ok(stats.sourceMap.indexOf('sample.scss') !== -1)); + }); +});