summaryrefslogtreecommitdiffstats
path: root/node_modules/node-sass/test
diff options
context:
space:
mode:
authorGravatar Piotr Russ <mail@pruss.it> 2020-11-16 00:10:28 +0100
committerGravatar Piotr Russ <mail@pruss.it> 2020-11-16 00:10:28 +0100
commite06ec920f7a5d784e674c4c4b4e6d1da3dc7391d (patch)
tree55713f725f77b44ebfec86e4eec3ce33e71458ca /node_modules/node-sass/test
downloadwebsite_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.gz
website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.bz2
website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.zip
api, login, auth
Diffstat (limited to 'node_modules/node-sass/test')
-rw-r--r--node_modules/node-sass/test/.eslintrc5
-rw-r--r--node_modules/node-sass/test/api.js2035
-rw-r--r--node_modules/node-sass/test/binding.js129
-rw-r--r--node_modules/node-sass/test/cli.js804
-rw-r--r--node_modules/node-sass/test/downloadoptions.js74
-rw-r--r--node_modules/node-sass/test/errors.js53
-rw-r--r--node_modules/node-sass/test/fixtures/compressed/expected.css1
-rw-r--r--node_modules/node-sass/test/fixtures/compressed/index.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css3
-rw-r--r--node_modules/node-sass/test/fixtures/custom-functions/setter.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css2
-rw-r--r--node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/cwd-include-path/expected.css2
-rw-r--r--node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/_common.scss6
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/_struct.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/_vars.scss5
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/a.scss7
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/a1.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/b.scss5
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/b1.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/expected.css32
-rw-r--r--node_modules/node-sass/test/fixtures/depth-first/index.scss8
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js12
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js10
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js8
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js5
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js5
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js3
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js7
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js6
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js6
-rw-r--r--node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js7
-rw-r--r--node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/include-files/bar.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/include-files/expected-importer.css5
-rw-r--r--node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/include-files/foo.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/include-files/index.scss2
-rw-r--r--node_modules/node-sass/test/fixtures/include-path/expected.css3
-rw-r--r--node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/include-path/index.scss7
-rw-r--r--node_modules/node-sass/test/fixtures/include-path/lib/vars.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/indent/expected.css2
-rw-r--r--node_modules/node-sass/test/fixtures/indent/index.sass3
-rw-r--r--node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/input-directory/sass/one.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/input-directory/sass/two.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/invalid/index.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/output-directory/index.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/precision/expected.css2
-rw-r--r--node_modules/node-sass/test/fixtures/precision/index.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/sass-path/expected-orange.css3
-rw-r--r--node_modules/node-sass/test/fixtures/sass-path/expected-red.css3
-rw-r--r--node_modules/node-sass/test/fixtures/sass-path/index.scss6
-rw-r--r--node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/sass-path/red/colors.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/simple/expected.css11
-rw-r--r--node_modules/node-sass/test/fixtures/simple/index.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/source-comments/expected.css15
-rw-r--r--node_modules/node-sass/test/fixtures/source-comments/index.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/source-map-embed/expected.css13
-rw-r--r--node_modules/node-sass/test/fixtures/source-map-embed/index.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/source-map/expected.css13
-rw-r--r--node_modules/node-sass/test/fixtures/source-map/expected.map9
-rw-r--r--node_modules/node-sass/test/fixtures/source-map/index.scss16
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/main/one.scss5
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/main/partials/_one.scss5
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/main/partials/_three.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/main/partials/_two.scss5
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/main/three.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/main/two.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/sibling/partials/_three.scss3
-rw-r--r--node_modules/node-sass/test/fixtures/watcher/sibling/three.scss5
-rw-r--r--node_modules/node-sass/test/fixtures/watching-dir-01/index.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/watching-dir-02/index.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/watching/bar.sass2
-rw-r--r--node_modules/node-sass/test/fixtures/watching/index.sass1
-rw-r--r--node_modules/node-sass/test/fixtures/watching/index.scss1
-rw-r--r--node_modules/node-sass/test/fixtures/watching/white.scss1
-rw-r--r--node_modules/node-sass/test/lowlevel.js243
-rw-r--r--node_modules/node-sass/test/runtime.js185
-rw-r--r--node_modules/node-sass/test/scripts/util/proxy.js76
-rw-r--r--node_modules/node-sass/test/spec.js192
-rw-r--r--node_modules/node-sass/test/types.js643
-rw-r--r--node_modules/node-sass/test/useragent.js15
-rw-r--r--node_modules/node-sass/test/watcher.js503
92 files changed, 5444 insertions, 0 deletions
diff --git a/node_modules/node-sass/test/.eslintrc b/node_modules/node-sass/test/.eslintrc
new file mode 100644
index 0000000..7eeefc3
--- /dev/null
+++ b/node_modules/node-sass/test/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "env": {
+ "mocha": true
+ }
+}
diff --git a/node_modules/node-sass/test/api.js b/node_modules/node-sass/test/api.js
new file mode 100644
index 0000000..5db3113
--- /dev/null
+++ b/node_modules/node-sass/test/api.js
@@ -0,0 +1,2035 @@
+/*eslint new-cap: ["error", {"capIsNewExceptions": ["Color"]}]*/
+
+var assert = require('assert'),
+ fs = require('fs'),
+ path = require('path'),
+ read = fs.readFileSync,
+ sassPath = process.env.NODESASS_COV
+ ? require.resolve('../lib-cov')
+ : require.resolve('../lib'),
+ sass = require(sassPath),
+ fixture = path.join.bind(null, __dirname, 'fixtures'),
+ resolveFixture = path.resolve.bind(null, __dirname, 'fixtures');
+
+describe('api', function() {
+
+ describe('.render(options, callback)', function() {
+
+ beforeEach(function() {
+ delete process.env.SASS_PATH;
+ });
+
+ it('should compile sass to css with file', function(done) {
+ var expected = read(fixture('simple/expected.css'), 'utf8').trim();
+
+ sass.render({
+ file: fixture('simple/index.scss')
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+ });
+
+ it('should compile sass to css with outFile set to absolute url', function(done) {
+ sass.render({
+ file: fixture('simple/index.scss'),
+ sourceMap: true,
+ outFile: fixture('simple/index-test.css')
+ }, function(error, result) {
+ assert.equal(JSON.parse(result.map).file, 'index-test.css');
+ done();
+ });
+ });
+
+ it('should compile sass to css with outFile set to relative url', function(done) {
+ sass.render({
+ file: fixture('simple/index.scss'),
+ sourceMap: true,
+ outFile: './index-test.css'
+ }, function(error, result) {
+ assert.equal(JSON.parse(result.map).file, 'index-test.css');
+ done();
+ });
+ });
+
+ it('should compile sass to css with outFile and sourceMap set to relative url', function(done) {
+ sass.render({
+ file: fixture('simple/index.scss'),
+ sourceMap: './deep/nested/index.map',
+ outFile: './index-test.css'
+ }, function(error, result) {
+ assert.equal(JSON.parse(result.map).file, '../../index-test.css');
+ done();
+ });
+ });
+
+ it('should not generate source map when not requested', function(done) {
+ sass.render({
+ file: fixture('simple/index.scss'),
+ sourceMap: false
+ }, function(error, result) {
+ assert.strictEqual(result.hasOwnProperty('map'), false, 'result has a map property');
+ done();
+ });
+ });
+
+ it('should not generate source map without outFile and no explicit path given', function(done) {
+ sass.render({
+ file: fixture('simple/index.scss'),
+ sourceMap: true
+ }, function(error, result) {
+ assert.strictEqual(result.hasOwnProperty('map'), false, 'result has a map property');
+ done();
+ });
+ });
+
+ it('should compile generate map with sourceMapRoot pass-through option', function(done) {
+ sass.render({
+ file: fixture('simple/index.scss'),
+ sourceMap: './deep/nested/index.map',
+ sourceMapRoot: 'http://test.com/',
+ outFile: './index-test.css'
+ }, function(error, result) {
+ assert.equal(JSON.parse(result.map).sourceRoot, 'http://test.com/');
+ done();
+ });
+ });
+
+ it('should compile sass to css with data', function(done) {
+ var src = read(fixture('simple/index.scss'), 'utf8');
+ var expected = read(fixture('simple/expected.css'), 'utf8').trim();
+
+ sass.render({
+ data: src
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+ });
+
+ it('should compile sass to css using indented syntax', function(done) {
+ var src = read(fixture('indent/index.sass'), 'utf8');
+ var expected = read(fixture('indent/expected.css'), 'utf8').trim();
+
+ sass.render({
+ data: src,
+ indentedSyntax: true
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+ });
+
+ it('should NOT compile empty data string', function(done) {
+ sass.render({
+ data: ''
+ }, function(error) {
+ assert.equal(error.message, 'No input specified: provide a file name or a source string to process');
+ done();
+ });
+ });
+
+ it('should NOT compile without any input', function(done) {
+ sass.render({ }, function(error) {
+ assert.equal(error.message, 'No input specified: provide a file name or a source string to process');
+ done();
+ });
+ });
+
+ it('should returnn error status 1 for bad input', function(done) {
+ sass.render({
+ data: '#navbar width 80%;'
+ }, function(error) {
+ assert(error.message);
+ assert.equal(error.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').trim();
+
+ sass.render({
+ data: src,
+ includePaths: [
+ fixture('include-path/functions'),
+ fixture('include-path/lib')
+ ]
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+ });
+
+ it('should add cwd to the front on include paths', function(done) {
+ var src = fixture('cwd-include-path/root/index.scss');
+ var expected = read(fixture('cwd-include-path/expected.css'), 'utf8').trim();
+ var cwd = process.cwd();
+
+ process.chdir(fixture('cwd-include-path'));
+ sass.render({
+ file: src,
+ includePaths: []
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+
+ process.chdir(cwd);
+ done();
+ });
+ });
+
+ it('should check SASS_PATH in the specified order', function(done) {
+ var src = read(fixture('sass-path/index.scss'), 'utf8');
+ var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim();
+ var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim();
+
+ var envIncludes = [
+ fixture('sass-path/red'),
+ fixture('sass-path/orange')
+ ];
+
+ process.env.SASS_PATH = envIncludes.join(path.delimiter);
+ sass.render({
+ data: src,
+ includePaths: []
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n'));
+ });
+
+ process.env.SASS_PATH = envIncludes.reverse().join(path.delimiter);
+ sass.render({
+ data: src,
+ includePaths: []
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n'));
+ done();
+ });
+ });
+
+ it('should prefer include path over SASS_PATH', function(done) {
+ var src = read(fixture('sass-path/index.scss'), 'utf8');
+ var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim();
+ var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim();
+
+ var envIncludes = [
+ fixture('sass-path/red')
+ ];
+ process.env.SASS_PATH = envIncludes.join(path.delimiter);
+
+ sass.render({
+ data: src,
+ includePaths: []
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n'));
+ });
+ sass.render({
+ data: src,
+ includePaths: [fixture('sass-path/orange')]
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n'));
+ 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').trim();
+
+ sass.render({
+ data: src,
+ precision: 10
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+ });
+
+ it('should contain all included files in stats when data is passed', function(done) {
+ var src = read(fixture('include-files/index.scss'), 'utf8');
+ var expected = [
+ fixture('include-files/bar.scss').replace(/\\/g, '/'),
+ fixture('include-files/foo.scss').replace(/\\/g, '/')
+ ];
+
+ sass.render({
+ data: src,
+ includePaths: [fixture('include-files')]
+ }, function(error, result) {
+ assert.deepEqual(result.stats.includedFiles, expected);
+ done();
+ });
+ });
+
+ it('should render with indentWidth and indentType options', function(done) {
+ sass.render({
+ data: 'div { color: transparent; }',
+ indentWidth: 7,
+ indentType: 'tab'
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }');
+ done();
+ });
+ });
+
+ it('should render with linefeed option', function(done) {
+ sass.render({
+ data: 'div { color: transparent; }',
+ linefeed: 'lfcr'
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n\r color: transparent; }');
+ done();
+ });
+ });
+ });
+
+ describe('.render(importer)', function() {
+ var src = read(fixture('include-files/index.scss'), 'utf8');
+
+ it('should respect the order of chained imports when using custom importers and one file is custom imported and the other is not.', function(done) {
+ sass.render({
+ file: fixture('include-files/chained-imports-with-custom-importer.scss'),
+ importer: function(url, prev, done) {
+ // NOTE: to see that this test failure is only due to the stated
+ // issue do each of the following and see that the tests pass.
+ //
+ // a) add `return sass.NULL;` as the first line in this function to
+ // cause non-custom importers to always be used.
+ // b) comment out the conditional below to force our custom
+ // importer to always be used.
+ //
+ // You will notice that the tests pass when either all native, or
+ // all custom importers are used, but not when a native + custom
+ // import chain is used.
+ if (url !== 'file-processed-by-loader') {
+ return sass.NULL;
+ }
+ done({
+ file: fixture('include-files/' + url + '.scss')
+ });
+ }
+ }, function(err, data) {
+ assert.equal(err, null);
+
+ assert.equal(
+ data.css.toString().trim(),
+ 'body {\n color: "red"; }'
+ );
+
+ done();
+ });
+ });
+
+ it('should still call the next importer with the resolved prev path when the previous importer returned both a file and contents property - issue #1219', function(done) {
+ sass.render({
+ data: '@import "a";',
+ importer: function(url, prev, done) {
+ if (url === 'a') {
+ done({
+ file: '/Users/me/sass/lib/a.scss',
+ contents: '@import "b"'
+ });
+ } else {
+ assert.equal(prev, '/Users/me/sass/lib/a.scss');
+ done({
+ file: '/Users/me/sass/lib/b.scss',
+ contents: 'div {color: yellow;}'
+ });
+ }
+ }
+ }, function() {
+ done();
+ });
+ });
+
+ it('should override imports with "data" as input and fires callback with file and contents', function(done) {
+ sass.render({
+ data: src,
+ importer: function(url, prev, done) {
+ done({
+ file: '/some/other/path.scss',
+ contents: 'div {color: yellow;}'
+ });
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should should resolve imports depth first', function (done) {
+ var actualImportOrder = [];
+ var expectedImportOrder = [
+ 'a', '_common', 'vars', 'struct', 'a1', 'common', 'vars', 'struct', 'b', 'b1'
+ ];
+ var expected = read(fixture('depth-first/expected.css'));
+
+ sass.render({
+ file: fixture('depth-first/index.scss'),
+ importer: function (url, prev, done) {
+ actualImportOrder.push(url);
+ done();
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), expected);
+ assert.deepEqual(actualImportOrder, expectedImportOrder);
+ done();
+ });
+ });
+
+ it('should override imports with "file" as input and fires callback with file and contents', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev, done) {
+ done({
+ file: '/some/other/path.scss',
+ contents: 'div {color: yellow;}'
+ });
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should override imports with "data" as input and returns file and contents', function(done) {
+ sass.render({
+ data: src,
+ importer: function(url, prev) {
+ return {
+ file: prev + url,
+ contents: 'div {color: yellow;}'
+ };
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should override imports with "file" as input and returns file and contents', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev) {
+ return {
+ file: prev + url,
+ contents: 'div {color: yellow;}'
+ };
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should override imports with "data" as input and fires callback with file', function(done) {
+ sass.render({
+ data: src,
+ importer: function(url, /* jshint unused:false */ prev, done) {
+ done({
+ file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss'))
+ });
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should override imports with "file" as input and fires callback with file', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev, done) {
+ done({
+ file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss'))
+ });
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should override imports with "data" as input and returns file', function(done) {
+ sass.render({
+ data: src,
+ importer: function(url) {
+ return {
+ file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss'))
+ };
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should override imports with "file" as input and returns file', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev) {
+ return {
+ file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss'))
+ };
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should fallback to default import behaviour if importer returns sass.NULL', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev, done) {
+ done(sass.NULL);
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should fallback to default import behaviour if importer returns null for backwards compatibility', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev, done) {
+ done(null);
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should fallback to default import behaviour if importer returns undefined for backwards compatibility', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev, done) {
+ done(undefined);
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should fallback to default import behaviour if importer returns false for backwards compatibility', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev, done) {
+ done(false);
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+ });
+
+ it('should override imports with "data" as input and fires callback with contents', function(done) {
+ sass.render({
+ data: src,
+ importer: function(url, prev, done) {
+ done({
+ contents: 'div {color: yellow;}'
+ });
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should override imports with "file" as input and fires callback with contents', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev, done) {
+ done({
+ contents: 'div {color: yellow;}'
+ });
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should override imports with "data" as input and returns contents', function(done) {
+ sass.render({
+ data: src,
+ importer: function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should override imports with "file" as input and returns contents', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should accept arrays of importers and return respect the order', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss'),
+ importer: [
+ function() {
+ return sass.NULL;
+ },
+ function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ ]
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+ });
+
+ it('should be able to see its options in this.options', function(done) {
+ var fxt = fixture('include-files/index.scss');
+ sass.render({
+ file: fxt,
+ importer: function() {
+ assert.equal(fxt, this.options.file);
+ return {};
+ }
+ }, function() {
+ assert.equal(fxt, this.options.file);
+ done();
+ });
+ });
+
+ it('should be able to access a persistent options object', function(done) {
+ sass.render({
+ data: src,
+ importer: function() {
+ this.state = this.state || 0;
+ this.state++;
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ }, function() {
+ assert.equal(this.state, 2);
+ done();
+ });
+ });
+
+ it('should wrap importer options', function(done) {
+ var options;
+ options = {
+ data: src,
+ importer: function() {
+ assert.notStrictEqual(this.options.importer, options.importer);
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ };
+ sass.render(options, function() {
+ done();
+ });
+ });
+
+ it('should reflect user-defined error when returned as callback', function(done) {
+ sass.render({
+ data: src,
+ importer: function(url, prev, done) {
+ done(new Error('doesn\'t exist!'));
+ }
+ }, function(error) {
+ assert(/doesn\'t exist!/.test(error.message));
+ done();
+ });
+ });
+
+ it('should reflect user-defined error with return', function(done) {
+ sass.render({
+ data: src,
+ importer: function() {
+ return new Error('doesn\'t exist!');
+ }
+ }, function(error) {
+ assert(/doesn\'t exist!/.test(error.message));
+ done();
+ });
+ });
+
+ it('should throw exception when importer returns an invalid value', function(done) {
+ sass.render({
+ data: src,
+ importer: function() {
+ return { contents: new Buffer('i am not a string!') };
+ }
+ }, function(error) {
+ assert(/returned value of `contents` must be a string/.test(error.message));
+ done();
+ });
+ });
+ });
+
+ describe('.render(functions)', function() {
+ it('should call custom defined nullary function', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return new sass.types.Number(42, 'px');
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: 42px; }');
+ done();
+ });
+ });
+
+ it('should call custom function with multiple args', function(done) {
+ sass.render({
+ data: 'div { color: foo(3, 42px); }',
+ functions: {
+ 'foo($a, $b)': function(factor, size) {
+ return new sass.types.Number(factor.getValue() * size.getValue(), size.getUnit());
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: 126px; }');
+ done();
+ });
+ });
+
+ it('should work with custom functions that return data asynchronously', function(done) {
+ sass.render({
+ data: 'div { color: foo(42px); }',
+ functions: {
+ 'foo($a)': function(size, done) {
+ setTimeout(function() {
+ done(new sass.types.Number(66, 'em'));
+ }, 50);
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: 66em; }');
+ done();
+ });
+ });
+
+ it('should let custom functions call setter methods on wrapped sass values (number)', function(done) {
+ sass.render({
+ data: 'div { width: foo(42px); height: bar(42px); }',
+ functions: {
+ 'foo($a)': function(size) {
+ size.setUnit('rem');
+ return size;
+ },
+ 'bar($a)': function(size) {
+ size.setValue(size.getValue() * 2);
+ return size;
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n width: 42rem;\n height: 84px; }');
+ done();
+ });
+ });
+
+ it('should properly convert strings when calling custom functions', function(done) {
+ sass.render({
+ data: 'div { color: foo("bar"); }',
+ functions: {
+ 'foo($a)': function(str) {
+ str = str.getValue().replace(/['"]/g, '');
+ return new sass.types.String('"' + str + str + '"');
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: "barbar"; }');
+ done();
+ });
+ });
+
+ it('should let custom functions call setter methods on wrapped sass values (string)', function(done) {
+ sass.render({
+ data: 'div { width: foo("bar"); }',
+ functions: {
+ 'foo($a)': function(str) {
+ var unquoted = str.getValue().replace(/['"]/g, '');
+ str.setValue('"' + unquoted + unquoted + '"');
+ return str;
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n width: "barbar"; }');
+ done();
+ });
+ });
+
+ it('should properly convert colors when calling custom functions', function(done) {
+ sass.render({
+ data: 'div { color: foo(#f00); background-color: bar(); border-color: baz(); }',
+ functions: {
+ 'foo($a)': function(color) {
+ assert.equal(color.getR(), 255);
+ assert.equal(color.getG(), 0);
+ assert.equal(color.getB(), 0);
+ assert.equal(color.getA(), 1.0);
+
+ return new sass.types.Color(255, 255, 0, 0.5);
+ },
+ 'bar()': function() {
+ return new sass.types.Color(0x33ff00ff);
+ },
+ 'baz()': function() {
+ return new sass.types.Color(0xffff0000);
+ }
+ }
+ }, function(error, result) {
+ assert.equal(
+ result.css.toString().trim(),
+ 'div {\n color: rgba(255, 255, 0, 0.5);' +
+ '\n background-color: rgba(255, 0, 255, 0.2);' +
+ '\n border-color: red; }'
+ );
+ done();
+ });
+ });
+
+ it('should properly convert boolean when calling custom functions', function(done) {
+ sass.render({
+ data: 'div { color: if(foo(true, false), #fff, #000);' +
+ '\n background-color: if(foo(true, true), #fff, #000); }',
+ functions: {
+ 'foo($a, $b)': function(a, b) {
+ return sass.types.Boolean(a.getValue() && b.getValue());
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: #000;\n background-color: #fff; }');
+ done();
+ });
+ });
+
+ it('should let custom functions call setter methods on wrapped sass values (boolean)', function(done) {
+ sass.render({
+ data: 'div { color: if(foo(false), #fff, #000); background-color: if(foo(true), #fff, #000); }',
+ functions: {
+ 'foo($a)': function(a) {
+ return a.getValue() ? sass.types.Boolean.FALSE : sass.types.Boolean.TRUE;
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: #fff;\n background-color: #000; }');
+ done();
+ });
+ });
+
+ it('should properly convert lists when calling custom functions', function(done) {
+ sass.render({
+ data: '$test-list: (bar, #f00, 123em); @each $item in foo($test-list) { .#{$item} { color: #fff; } }',
+ functions: {
+ 'foo($l)': function(list) {
+ assert.equal(list.getLength(), 3);
+ assert.ok(list.getValue(0) instanceof sass.types.String);
+ assert.equal(list.getValue(0).getValue(), 'bar');
+ assert.ok(list.getValue(1) instanceof sass.types.Color);
+ assert.equal(list.getValue(1).getR(), 0xff);
+ assert.equal(list.getValue(1).getG(), 0);
+ assert.equal(list.getValue(1).getB(), 0);
+ assert.ok(list.getValue(2) instanceof sass.types.Number);
+ assert.equal(list.getValue(2).getValue(), 123);
+ assert.equal(list.getValue(2).getUnit(), 'em');
+
+ var out = new sass.types.List(3);
+ out.setValue(0, new sass.types.String('foo'));
+ out.setValue(1, new sass.types.String('bar'));
+ out.setValue(2, new sass.types.String('baz'));
+ return out;
+ }
+ }
+ }, function(error, result) {
+ assert.equal(
+ result.css.toString().trim(),
+ '.foo {\n color: #fff; }\n\n.bar {\n color: #fff; }\n\n.baz {\n color: #fff; }'
+ );
+ done();
+ });
+ });
+
+ it('should properly convert maps when calling custom functions', function(done) {
+ sass.render({
+ data: '$test-map: foo((abc: 123, #def: true)); div { color: if(map-has-key($test-map, hello), #fff, #000); }' +
+ 'span { color: map-get($test-map, baz); }',
+ functions: {
+ 'foo($m)': function(map) {
+ assert.equal(map.getLength(), 2);
+ assert.ok(map.getKey(0) instanceof sass.types.String);
+ assert.ok(map.getKey(1) instanceof sass.types.Color);
+ assert.ok(map.getValue(0) instanceof sass.types.Number);
+ assert.ok(map.getValue(1) instanceof sass.types.Boolean);
+ assert.equal(map.getKey(0).getValue(), 'abc');
+ assert.equal(map.getValue(0).getValue(), 123);
+ assert.equal(map.getKey(1).getR(), 0xdd);
+ assert.equal(map.getValue(1).getValue(), true);
+
+ var out = new sass.types.Map(3);
+ out.setKey(0, new sass.types.String('hello'));
+ out.setValue(0, new sass.types.String('world'));
+ out.setKey(1, new sass.types.String('foo'));
+ out.setValue(1, new sass.types.String('bar'));
+ out.setKey(2, new sass.types.String('baz'));
+ out.setValue(2, new sass.types.String('qux'));
+ return out;
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: #fff; }\n\nspan {\n color: qux; }');
+ done();
+ });
+ });
+
+ it('should properly convert null when calling custom functions', function(done) {
+ sass.render({
+ data: 'div { color: if(foo("bar"), #fff, #000); } ' +
+ 'span { color: if(foo(null), #fff, #000); }' +
+ 'table { color: if(bar() == null, #fff, #000); }',
+ functions: {
+ 'foo($a)': function(a) {
+ return sass.types.Boolean(a instanceof sass.types.Null);
+ },
+ 'bar()': function() {
+ return sass.NULL;
+ }
+ }
+ }, function(error, result) {
+ assert.equal(
+ result.css.toString().trim(),
+ 'div {\n color: #000; }\n\nspan {\n color: #fff; }\n\ntable {\n color: #fff; }'
+ );
+ done();
+ });
+ });
+
+ it('should be possible to carry sass values across different renders', function(done) {
+ var persistentMap;
+
+ sass.render({
+ data: 'div { color: foo((abc: #112233, #ddeeff: true)); }',
+ functions: {
+ foo: function(m) {
+ persistentMap = m;
+ return sass.types.Color(0, 0, 0);
+ }
+ }
+ }, function() {
+ sass.render({
+ data: 'div { color: map-get(bar(), abc); background-color: baz(); }',
+ functions: {
+ bar: function() {
+ return persistentMap;
+ },
+ baz: function() {
+ return persistentMap.getKey(1);
+ }
+ }
+ }, function(errror, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: #112233;\n background-color: #ddeeff; }');
+ done();
+ });
+ });
+ });
+
+ it('should let us register custom functions without signatures', function(done) {
+ sass.render({
+ data: 'div { color: foo(20, 22); }',
+ functions: {
+ foo: function(a, b) {
+ return new sass.types.Number(a.getValue() + b.getValue(), 'em');
+ }
+ }
+ }, function(error, result) {
+ assert.equal(result.css.toString().trim(), 'div {\n color: 42em; }');
+ done();
+ });
+ });
+
+ it('should fail when returning anything other than a sass value from a custom function', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return {};
+ }
+ }
+ }, function(error) {
+ assert.ok(/A SassValue object was expected/.test(error.message));
+ done();
+ });
+ });
+
+ it('should properly bubble up standard JS errors thrown by custom functions', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ throw new RangeError('This is a test error');
+ }
+ }
+ }, function(error) {
+ assert.ok(/This is a test error/.test(error.message));
+ done();
+ });
+ });
+
+ it('should properly bubble up unknown errors thrown by custom functions', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ throw {};
+ }
+ }
+ }, function(error) {
+ assert.ok(/unexpected error/.test(error.message));
+ done();
+ });
+ });
+
+ it('should call custom functions with correct context', function(done) {
+ function assertExpected(result) {
+ assert.equal(result.css.toString().trim(), 'div {\n foo1: 1;\n foo2: 2; }');
+ }
+ var options = {
+ data: 'div { foo1: foo(); foo2: foo(); }',
+ functions: {
+ // foo() is stateful and will persist an incrementing counter
+ 'foo()': function() {
+ assert(this);
+ this.fooCounter = (this.fooCounter || 0) + 1;
+ return new sass.types.Number(this.fooCounter);
+ }
+ }
+ };
+
+ sass.render(options, function(error, result) {
+ assertExpected(result);
+ done();
+ });
+ });
+
+ describe('should properly bubble up errors from sass color constructor', function() {
+ it('four booleans', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return new sass.types.Color(false, false, false, false);
+ }
+ }
+ }, function(error) {
+ assert.ok(/Constructor arguments should be numbers exclusively/.test(error.message));
+ done();
+ });
+ });
+
+ it('two arguments', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return sass.types.Color(2,3);
+ }
+ }
+ }, function(error) {
+ assert.ok(/Constructor should be invoked with either 0, 1, 3 or 4 arguments/.test(error.message));
+ done();
+ });
+ });
+
+ it('single string argument', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return sass.types.Color('foo');
+ }
+ }
+ }, function(error) {
+ assert.ok(/Only argument should be an integer/.test(error.message));
+ done();
+ });
+ });
+ });
+
+ it('should properly bubble up errors from sass value constructors', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return sass.types.Boolean('foo');
+ }
+ }
+ }, function(error) {
+ assert.ok(/Expected one boolean argument/.test(error.message));
+ done();
+ });
+ });
+
+ it('should properly bubble up errors from sass value setters', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ var ret = new sass.types.Number(42);
+ ret.setUnit(123);
+ return ret;
+ }
+ }
+ }, function(error) {
+ assert.ok(/Supplied value should be a string/.test(error.message));
+ done();
+ });
+ });
+
+ it('should fail when trying to set a bare number as the List item', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ var out = new sass.types.List(1);
+ out.setValue(0, 2);
+ return out;
+ }
+ }
+ }, function(error) {
+ assert.ok(/Supplied value should be a SassValue object/.test(error.message));
+ done();
+ });
+ });
+
+ it('should fail when trying to set a bare Object as the List item', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ var out = new sass.types.List(1);
+ out.setValue(0, {});
+ return out;
+ }
+ }
+ }, function(error) {
+ assert.ok(/A SassValue is expected as the list item/.test(error.message));
+ done();
+ });
+ });
+
+ it('should fail when trying to set a bare Object as the Map key', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ var out = new sass.types.Map(1);
+ out.setKey(0, {});
+ out.setValue(0, new sass.types.String('aaa'));
+ return out;
+ }
+ }
+ }, function(error) {
+ assert.ok(/A SassValue is expected as a map key/.test(error.message));
+ done();
+ });
+ });
+
+ it('should fail when trying to set a bare Object as the Map value', function(done) {
+ sass.render({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ var out = new sass.types.Map(1);
+ out.setKey(0, new sass.types.String('aaa'));
+ out.setValue(0, {});
+ return out;
+ }
+ }
+ }, function(error) {
+ assert.ok(/A SassValue is expected as a map value/.test(error.message));
+ done();
+ });
+ });
+
+ it('should always map null, true and false to the same (immutable) object', function(done) {
+ var counter = 0;
+
+ sass.render({
+ data: 'div { color: foo(bar(null)); background-color: baz("foo" == "bar"); }',
+ functions: {
+ foo: function(a) {
+ assert.strictEqual(a, sass.TRUE,
+ 'Supplied value should be the same instance as sass.TRUE'
+ );
+
+ assert.strictEqual(
+ sass.types.Boolean(true), sass.types.Boolean(true),
+ 'sass.types.Boolean(true) should return a singleton');
+
+ assert.strictEqual(
+ sass.types.Boolean(true), sass.TRUE,
+ 'sass.types.Boolean(true) should be the same instance as sass.TRUE');
+
+ counter++;
+
+ return sass.types.String('foo');
+ },
+ bar: function(a) {
+ assert.strictEqual(a, sass.NULL,
+ 'Supplied value should be the same instance as sass.NULL');
+
+ assert.throws(function() {
+ return new sass.types.Null();
+ }, /Cannot instantiate SassNull/);
+
+ counter++;
+
+ return sass.TRUE;
+ },
+ baz: function(a) {
+ assert.strictEqual(a, sass.FALSE,
+ 'Supplied value should be the same instance as sass.FALSE');
+
+ assert.throws(function() {
+ return new sass.types.Boolean(false);
+ }, /Cannot instantiate SassBoolean/);
+
+ assert.strictEqual(
+ sass.types.Boolean(false), sass.types.Boolean(false),
+ 'sass.types.Boolean(false) should return a singleton');
+
+ assert.strictEqual(
+ sass.types.Boolean(false), sass.FALSE,
+ 'sass.types.Boolean(false) should return singleton identical to sass.FALSE');
+
+ counter++;
+
+ return sass.types.String('baz');
+ }
+ }
+ }, function() {
+ assert.strictEqual(counter, 3);
+ done();
+ });
+ });
+ });
+
+ describe('.render({stats: {}})', function() {
+ var start = Date.now();
+
+ it('should provide a start timestamp', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss')
+ }, function(error, result) {
+ assert(!error);
+ assert.strictEqual(typeof result.stats.start, 'number');
+ assert(result.stats.start >= start);
+ done();
+ });
+ });
+
+ it('should provide an end timestamp', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss')
+ }, function(error, result) {
+ assert(!error);
+ assert.strictEqual(typeof result.stats.end, 'number');
+ assert(result.stats.end >= result.stats.start);
+ done();
+ });
+ });
+
+ it('should provide a duration', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss')
+ }, function(error, result) {
+ assert(!error);
+ assert.strictEqual(typeof result.stats.duration, 'number');
+ assert.equal(result.stats.end - result.stats.start, result.stats.duration);
+ done();
+ });
+ });
+
+ it('should contain the given entry file', function(done) {
+ sass.render({
+ file: fixture('include-files/index.scss')
+ }, function(error, result) {
+ assert(!error);
+ assert.equal(result.stats.entry, fixture('include-files/index.scss'));
+ done();
+ });
+ });
+
+ it('should contain an array of all included files', function(done) {
+ var expected = [
+ fixture('include-files/bar.scss').replace(/\\/g, '/'),
+ fixture('include-files/foo.scss').replace(/\\/g, '/'),
+ fixture('include-files/index.scss').replace(/\\/g, '/')
+ ];
+
+ sass.render({
+ file: fixture('include-files/index.scss')
+ }, function(error, result) {
+ assert(!error);
+ assert.deepEqual(result.stats.includedFiles.sort(), expected.sort());
+ done();
+ });
+ });
+
+ it('should contain array with the entry if there are no import statements', function(done) {
+ var expected = fixture('simple/index.scss').replace(/\\/g, '/');
+
+ sass.render({
+ file: fixture('simple/index.scss')
+ }, function(error, result) {
+ assert.deepEqual(result.stats.includedFiles, [expected]);
+ done();
+ });
+ });
+
+ it('should state `data` as entry file', function(done) {
+ sass.render({
+ data: read(fixture('simple/index.scss'), 'utf8')
+ }, function(error, result) {
+ assert.equal(result.stats.entry, 'data');
+ done();
+ });
+ });
+
+ it('should contain an empty array as includedFiles', function(done) {
+ sass.render({
+ data: read(fixture('simple/index.scss'), 'utf8')
+ }, function(error, result) {
+ assert.deepEqual(result.stats.includedFiles, []);
+ done();
+ });
+ });
+ });
+
+ describe('.renderSync(options)', function() {
+ it('should compile sass to css with file', function(done) {
+ var expected = read(fixture('simple/expected.css'), 'utf8').trim();
+ var result = sass.renderSync({ file: fixture('simple/index.scss') });
+
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ it('should compile sass to css with outFile set to absolute url', function(done) {
+ var result = sass.renderSync({
+ file: fixture('simple/index.scss'),
+ sourceMap: true,
+ outFile: fixture('simple/index-test.css')
+ });
+
+ assert.equal(JSON.parse(result.map).file, 'index-test.css');
+ done();
+ });
+
+ it('should compile sass to css with outFile set to relative url', function(done) {
+ var result = sass.renderSync({
+ file: fixture('simple/index.scss'),
+ sourceMap: true,
+ outFile: './index-test.css'
+ });
+
+ assert.equal(JSON.parse(result.map).file, 'index-test.css');
+ done();
+ });
+
+ it('should compile sass to css with outFile and sourceMap set to relative url', function(done) {
+ var result = sass.renderSync({
+ file: fixture('simple/index.scss'),
+ sourceMap: './deep/nested/index.map',
+ outFile: './index-test.css'
+ });
+
+ assert.equal(JSON.parse(result.map).file, '../../index-test.css');
+ done();
+ });
+
+ it('should not generate source map when not requested', function(done) {
+ var result = sass.renderSync({
+ file: fixture('simple/index.scss'),
+ sourceMap: false
+ });
+
+ assert.strictEqual(result.hasOwnProperty('map'), false, 'result has a map property');
+ done();
+ });
+
+ it('should not generate source map without outFile and no explicit path given', function(done) {
+ var result = sass.renderSync({
+ file: fixture('simple/index.scss'),
+ sourceMap: true
+ });
+
+ assert.strictEqual(result.hasOwnProperty('map'), false, 'result has a map property');
+ done();
+ });
+
+ it('should compile generate map with sourceMapRoot pass-through option', function(done) {
+ var result = sass.renderSync({
+ file: fixture('simple/index.scss'),
+ sourceMap: './deep/nested/index.map',
+ sourceMapRoot: 'http://test.com/',
+ outFile: './index-test.css'
+ });
+
+ assert.equal(JSON.parse(result.map).sourceRoot, 'http://test.com/');
+ done();
+ });
+
+ it('should compile sass to css with data', function(done) {
+ var src = read(fixture('simple/index.scss'), 'utf8');
+ var expected = read(fixture('simple/expected.css'), 'utf8').trim();
+ var result = sass.renderSync({ data: src });
+
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ it('should compile sass to css using indented syntax', function(done) {
+ var src = read(fixture('indent/index.sass'), 'utf8');
+ var expected = read(fixture('indent/expected.css'), 'utf8').trim();
+ var result = sass.renderSync({
+ data: src,
+ indentedSyntax: true
+ });
+
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ it('should NOT compile empty data string', function(done) {
+ assert.throws(function() {
+ sass.renderSync({ data: '' });
+ }, /No input specified: provide a file name or a source string to process/ );
+ done();
+ });
+
+ it('should NOT compile without any input', function(done) {
+ assert.throws(function() {
+ sass.renderSync({});
+ }, /No input specified: provide a file name or a source string to process/);
+ done();
+ });
+
+ it('should throw error for bad input', function(done) {
+ assert.throws(function() {
+ sass.renderSync('somestring');
+ });
+ assert.throws(function() {
+ sass.renderSync({ data: '#navbar width 80%;' });
+ });
+
+ 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').trim();
+ var result = sass.renderSync({
+ data: src,
+ includePaths: [
+ fixture('include-path/functions'),
+ fixture('include-path/lib')
+ ]
+ });
+
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ it('should add cwd to the front on include paths', function(done) {
+ var src = fixture('cwd-include-path/root/index.scss');
+ var expected = read(fixture('cwd-include-path/expected.css'), 'utf8').trim();
+ var cwd = process.cwd();
+
+ process.chdir(fixture('cwd-include-path'));
+ var result = sass.renderSync({
+ file: src,
+ includePaths: [
+ fixture('include-path/functions'),
+ fixture('include-path/lib')
+ ]
+ });
+ process.chdir(cwd);
+
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ it('should check SASS_PATH in the specified order', function(done) {
+ var src = read(fixture('sass-path/index.scss'), 'utf8');
+ var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim();
+ var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim();
+
+ var envIncludes = [
+ fixture('sass-path/red'),
+ fixture('sass-path/orange')
+ ];
+
+ process.env.SASS_PATH = envIncludes.join(path.delimiter);
+ var result = sass.renderSync({
+ data: src,
+ includePaths: []
+ });
+
+ assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n'));
+
+ process.env.SASS_PATH = envIncludes.reverse().join(path.delimiter);
+ result = sass.renderSync({
+ data: src,
+ includePaths: []
+ });
+
+ assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ it('should prefer include path over SASS_PATH', function(done) {
+ var src = read(fixture('sass-path/index.scss'), 'utf8');
+ var expectedRed = read(fixture('sass-path/expected-red.css'), 'utf8').trim();
+ var expectedOrange = read(fixture('sass-path/expected-orange.css'), 'utf8').trim();
+
+ var envIncludes = [
+ fixture('sass-path/red')
+ ];
+ process.env.SASS_PATH = envIncludes.join(path.delimiter);
+
+ var result = sass.renderSync({
+ data: src,
+ includePaths: []
+ });
+
+ assert.equal(result.css.toString().trim(), expectedRed.replace(/\r\n/g, '\n'));
+
+ result = sass.renderSync({
+ data: src,
+ includePaths: [fixture('sass-path/orange')]
+ });
+
+ assert.equal(result.css.toString().trim(), expectedOrange.replace(/\r\n/g, '\n'));
+ 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').trim();
+ var result = sass.renderSync({
+ data: src,
+ precision: 10
+ });
+
+ assert.equal(result.css.toString().trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ it('should contain all included files in stats when data is passed', function(done) {
+ var src = read(fixture('include-files/index.scss'), 'utf8');
+ var expected = [
+ fixture('include-files/bar.scss').replace(/\\/g, '/'),
+ fixture('include-files/foo.scss').replace(/\\/g, '/')
+ ];
+
+ var result = sass.renderSync({
+ data: src,
+ includePaths: [fixture('include-files')]
+ });
+
+ assert.deepEqual(result.stats.includedFiles, expected);
+ done();
+ });
+
+ it('should render with indentWidth and indentType options', function(done) {
+ var result = sass.renderSync({
+ data: 'div { color: transparent; }',
+ indentWidth: 7,
+ indentType: 'tab'
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }');
+ done();
+ });
+
+ it('should render with linefeed option', function(done) {
+ var result = sass.renderSync({
+ data: 'div { color: transparent; }',
+ linefeed: 'lfcr'
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n\r color: transparent; }');
+ done();
+ });
+ });
+
+ describe('.renderSync(importer)', function() {
+ var src = read(fixture('include-files/index.scss'), 'utf8');
+
+ it('should override imports with "data" as input and returns file and contents', function(done) {
+ var result = sass.renderSync({
+ data: src,
+ importer: function(url, prev) {
+ return {
+ file: prev + url,
+ contents: 'div {color: yellow;}'
+ };
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+
+ it('should override imports with "file" as input and returns file and contents', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev) {
+ return {
+ file: prev + url,
+ contents: 'div {color: yellow;}'
+ };
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+
+ it('should override imports with "data" as input and returns file', function(done) {
+ var result = sass.renderSync({
+ data: src,
+ importer: function(url) {
+ return {
+ file: path.resolve(path.dirname(fixture('include-files/index.scss')), url + (path.extname(url) ? '' : '.scss'))
+ };
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+
+ it('should override imports with "file" as input and returns file', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function(url, prev) {
+ return {
+ file: path.resolve(path.dirname(prev), url + (path.extname(url) ? '' : '.scss'))
+ };
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+
+ it('should override imports with "data" as input and returns contents', function(done) {
+ var result = sass.renderSync({
+ data: src,
+ importer: function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+
+ it('should override imports with "file" as input and returns contents', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+
+
+
+ it('should fallback to default import behaviour if importer returns sass.NULL', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function() {
+ return sass.NULL;
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+
+ it('should fallback to default import behaviour if importer returns null for backwards compatibility', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function() {
+ return null;
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+
+ it('should fallback to default import behaviour if importer returns undefined for backwards compatibility', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function() {
+ return undefined;
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+
+ it('should fallback to default import behaviour if importer returns false for backwards compatibility', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function() {
+ return false;
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), '/* foo.scss */\n/* bar.scss */');
+ done();
+ });
+
+ it('should accept arrays of importers and return respect the order', function(done) {
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: [
+ function() {
+ return sass.NULL;
+ },
+ function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+ ]
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n color: yellow; }\n\ndiv {\n color: yellow; }');
+ done();
+ });
+
+ it('should be able to see its options in this.options', function(done) {
+ var fxt = fixture('include-files/index.scss');
+ var sync = false;
+ sass.renderSync({
+ file: fixture('include-files/index.scss'),
+ importer: function() {
+ assert.equal(fxt, this.options.file);
+ sync = true;
+ return {};
+ }
+ });
+ assert.equal(sync, true);
+ done();
+ });
+
+ it('should throw user-defined error', function(done) {
+ assert.throws(function() {
+ sass.renderSync({
+ data: src,
+ importer: function() {
+ return new Error('doesn\'t exist!');
+ }
+ });
+ }, /doesn\'t exist!/);
+
+ done();
+ });
+
+ it('should throw exception when importer returns an invalid value', function(done) {
+ assert.throws(function() {
+ sass.renderSync({
+ data: src,
+ importer: function() {
+ return { contents: new Buffer('i am not a string!') };
+ }
+ });
+ }, /returned value of `contents` must be a string/);
+
+ done();
+ });
+ });
+
+ describe('.renderSync(functions)', function() {
+ it('should call custom function in sync mode', function(done) {
+ var result = sass.renderSync({
+ data: 'div { width: cos(0) * 50px; }',
+ functions: {
+ 'cos($a)': function(angle) {
+ if (!(angle instanceof sass.types.Number)) {
+ throw new TypeError('Unexpected type for "angle"');
+ }
+ return new sass.types.Number(Math.cos(angle.getValue()));
+ }
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n width: 50px; }');
+ done();
+ });
+
+ it('should return a list of selectors after calling the headings custom function', function(done) {
+ var result = sass.renderSync({
+ data: '#{headings(2,5)} { color: #08c; }',
+ functions: {
+ 'headings($from: 0, $to: 6)': function(from, to) {
+ var i, f = from.getValue(), t = to.getValue(),
+ list = new sass.types.List(t - f + 1);
+
+ for (i = f; i <= t; i++) {
+ list.setValue(i - f, new sass.types.String('h' + i));
+ }
+
+ return list;
+ }
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'h2, h3, h4, h5 {\n color: #08c; }');
+ done();
+ });
+
+ it('should let custom function invoke sass types constructors without the `new` keyword', function(done) {
+ var result = sass.renderSync({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return sass.types.Number(42, 'em');
+ }
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n color: 42em; }');
+ done();
+ });
+
+ it('should let us register custom functions without signatures', function(done) {
+ var result = sass.renderSync({
+ data: 'div { color: foo(20, 22); }',
+ functions: {
+ foo: function(a, b) {
+ return new sass.types.Number(a.getValue() + b.getValue(), 'em');
+ }
+ }
+ });
+
+ assert.equal(result.css.toString().trim(), 'div {\n color: 42em; }');
+ done();
+ });
+
+ it('should fail when returning anything other than a sass value from a custom function', function(done) {
+ assert.throws(function() {
+ sass.renderSync({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return {};
+ }
+ }
+ });
+ }, /A SassValue object was expected/);
+
+ done();
+ });
+
+ it('should properly bubble up standard JS errors thrown by custom functions', function(done) {
+ assert.throws(function() {
+ sass.renderSync({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ throw new RangeError('This is a test error');
+ }
+ }
+ });
+ }, /This is a test error/);
+
+ done();
+ });
+
+ it('should properly bubble up unknown errors thrown by custom functions', function(done) {
+ assert.throws(function() {
+ sass.renderSync({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ throw {};
+ }
+ }
+ });
+ }, /unexpected error/);
+
+ done();
+ });
+
+ it('should properly bubble up errors from sass value getters/setters/constructors', function(done) {
+ assert.throws(function() {
+ sass.renderSync({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ return sass.types.Boolean('foo');
+ }
+ }
+ });
+ }, /Expected one boolean argument/);
+
+ assert.throws(function() {
+ sass.renderSync({
+ data: 'div { color: foo(); }',
+ functions: {
+ 'foo()': function() {
+ var ret = new sass.types.Number(42);
+ ret.setUnit(123);
+ return ret;
+ }
+ }
+ });
+ }, /Supplied value should be a string/);
+
+ done();
+ });
+
+ it('should call custom functions with correct context', function(done) {
+ function assertExpected(result) {
+ assert.equal(result.css.toString().trim(), 'div {\n foo1: 1;\n foo2: 2; }');
+ }
+ var options = {
+ data: 'div { foo1: foo(); foo2: foo(); }',
+ functions: {
+ // foo() is stateful and will persist an incrementing counter
+ 'foo()': function() {
+ assert(this);
+ this.fooCounter = (this.fooCounter || 0) + 1;
+ return new sass.types.Number(this.fooCounter);
+ }
+ }
+ };
+ assertExpected(sass.renderSync(options));
+ done();
+ });
+ });
+
+ describe('.renderSync({stats: {}})', function() {
+ var start = Date.now();
+ var result = sass.renderSync({
+ file: fixture('include-files/index.scss')
+ });
+
+ it('should provide a start timestamp', function(done) {
+ assert.strictEqual(typeof result.stats.start, 'number');
+ assert(result.stats.start >= start);
+ done();
+ });
+
+ it('should provide an end timestamp', function(done) {
+ assert.strictEqual(typeof result.stats.end, 'number');
+ assert(result.stats.end >= result.stats.start);
+ done();
+ });
+
+ it('should provide a duration', function(done) {
+ assert.strictEqual(typeof result.stats.duration, 'number');
+ assert.equal(result.stats.end - result.stats.start, result.stats.duration);
+ done();
+ });
+
+ it('should contain the given entry file', function(done) {
+ assert.equal(result.stats.entry, resolveFixture('include-files/index.scss'));
+ done();
+ });
+
+ it('should contain an array of all included files', function(done) {
+ var expected = [
+ fixture('include-files/bar.scss').replace(/\\/g, '/'),
+ fixture('include-files/foo.scss').replace(/\\/g, '/'),
+ fixture('include-files/index.scss').replace(/\\/g, '/')
+ ].sort();
+ var actual = result.stats.includedFiles.sort();
+
+ assert.equal(actual[0], expected[0]);
+ assert.equal(actual[1], expected[1]);
+ assert.equal(actual[2], expected[2]);
+ done();
+ });
+
+ it('should contain array with the entry if there are no import statements', function(done) {
+ var expected = fixture('simple/index.scss').replace(/\\/g, '/');
+
+ var result = sass.renderSync({
+ file: fixture('simple/index.scss')
+ });
+
+ assert.deepEqual(result.stats.includedFiles, [expected]);
+ done();
+ });
+
+ it('should state `data` as entry file', function(done) {
+ var result = sass.renderSync({
+ data: read(fixture('simple/index.scss'), 'utf8')
+ });
+
+ assert.equal(result.stats.entry, 'data');
+ done();
+ });
+
+ it('should contain an empty array as includedFiles', function(done) {
+ var result = sass.renderSync({
+ data: read(fixture('simple/index.scss'), 'utf8')
+ });
+
+ assert.deepEqual(result.stats.includedFiles, []);
+ done();
+ });
+ });
+
+ describe('.info', function() {
+ var package = require('../package.json'),
+ info = sass.info;
+
+ it('should return a correct version info', function(done) {
+ assert(info.indexOf(package.version) > 0);
+ assert(info.indexOf('(Wrapper)') > 0);
+ assert(info.indexOf('[JavaScript]') > 0);
+ assert(info.indexOf('[NA]') < 0);
+ assert(info.indexOf('(Sass Compiler)') > 0);
+ assert(info.indexOf('[C/C++]') > 0);
+
+ done();
+ });
+ });
+});
diff --git a/node_modules/node-sass/test/binding.js b/node_modules/node-sass/test/binding.js
new file mode 100644
index 0000000..200c780
--- /dev/null
+++ b/node_modules/node-sass/test/binding.js
@@ -0,0 +1,129 @@
+/*eslint new-cap: ["error", {"capIsNewExceptions": ["Color"]}]*/
+
+var assert = require('assert'),
+ path = require('path'),
+ etx = require('../lib/extensions'),
+ binding = process.env.NODESASS_COV
+ ? require('../lib-cov/binding')
+ : require('../lib/binding');
+
+describe('binding', function() {
+ describe('missing error', function() {
+ it('should be useful', function() {
+ process.env.SASS_BINARY_NAME = 'unknown-x64-48';
+
+ assert.throws(
+ function() { binding(etx); },
+ function(err) {
+ var re = new RegExp('Missing binding.*?\\' + path.sep + 'vendor\\' + path.sep);
+ if ((err instanceof Error)) {
+ return re.test(err);
+ }
+ }
+ );
+ });
+
+ it('should list currently installed bindings', function() {
+ assert.throws(
+ function() { binding(etx); },
+ function(err) {
+ var etx = require('../lib/extensions');
+
+ delete process.env.SASS_BINARY_NAME;
+
+ if ((err instanceof Error)) {
+ return err.message.indexOf(
+ etx.getHumanEnvironment(etx.getBinaryName())
+ ) !== -1;
+ }
+ }
+ );
+ });
+ });
+
+ describe('on unsupported environment', function() {
+ describe('with an unsupported architecture', function() {
+ beforeEach(function() {
+ Object.defineProperty(process, 'arch', {
+ value: 'foo',
+ });
+ });
+
+ afterEach(function() {
+ Object.defineProperty(process, 'arch', {
+ value: 'x64',
+ });
+ });
+
+ it('should error', function() {
+ assert.throws(
+ function() { binding(etx); },
+ 'Node Sass does not yet support your current environment'
+ );
+ });
+
+ it('should inform the user the architecture is unsupported', function() {
+ assert.throws(
+ function() { binding(etx); },
+ 'Unsupported architecture (foo)'
+ );
+ });
+ });
+
+ describe('with an unsupported platform', function() {
+ beforeEach(function() {
+ Object.defineProperty(process, 'platform', {
+ value: 'bar',
+ });
+ });
+
+ afterEach(function() {
+ Object.defineProperty(process, 'platform', {
+ value: 'darwin',
+ });
+ });
+
+ it('should error', function() {
+ assert.throws(
+ function() { binding(etx); },
+ 'Node Sass does not yet support your current environment'
+ );
+ });
+
+ it('should inform the user the platform is unsupported', function() {
+ assert.throws(
+ function() { binding(etx); },
+ 'Unsupported platform (bar)'
+ );
+ });
+ });
+
+ describe('with an unsupported runtime', function() {
+ beforeEach(function() {
+ Object.defineProperty(process.versions, 'modules', {
+ value: 'baz',
+ });
+ });
+
+ afterEach(function() {
+ Object.defineProperty(process.versions, 'modules', {
+ value: 51,
+ });
+ });
+
+ it('should error', function() {
+ assert.throws(
+ function() { binding(etx); },
+ 'Node Sass does not yet support your current environment'
+ );
+ });
+
+ it('should inform the user the runtime is unsupported', function() {
+ assert.throws(
+ function() { binding(etx); },
+ 'Unsupported runtime (baz)'
+ );
+ });
+ });
+ });
+});
diff --git a/node_modules/node-sass/test/cli.js b/node_modules/node-sass/test/cli.js
new file mode 100644
index 0000000..78a8091
--- /dev/null
+++ b/node_modules/node-sass/test/cli.js
@@ -0,0 +1,804 @@
+var assert = require('assert'),
+ fs = require('fs'),
+ path = require('path'),
+ read = require('fs').readFileSync,
+ glob = require('glob'),
+ rimraf = require('rimraf'),
+ stream = require('stream'),
+ spawn = require('cross-spawn'),
+ cli = path.join(__dirname, '..', 'bin', 'node-sass'),
+ fixture = path.join.bind(null, __dirname, 'fixtures');
+
+describe('cli', function() {
+ // For some reason we experience random timeout failures in CI
+ // due to spawn hanging/failing silently. See #1692.
+ this.retries(4);
+
+ describe('node-sass < in.scss', function() {
+ it('should read data from stdin', function(done) {
+ var src = fs.createReadStream(fixture('simple/index.scss'));
+ var expected = read(fixture('simple/expected.css'), 'utf8').trim();
+ var bin = spawn(cli);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ src.pipe(bin.stdin);
+ });
+
+ it('should compile sass using the --indented-syntax option', function(done) {
+ var src = fs.createReadStream(fixture('indent/index.sass'));
+ var expected = read(fixture('indent/expected.css'), 'utf8').trim();
+ var bin = spawn(cli, ['--indented-syntax']);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ src.pipe(bin.stdin);
+ });
+
+ it('should compile with the --quiet option', function(done) {
+ var src = fs.createReadStream(fixture('simple/index.scss'));
+ var expected = read(fixture('simple/expected.css'), 'utf8').trim();
+ var bin = spawn(cli, ['--quiet']);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ src.pipe(bin.stdin);
+ });
+
+ it('should compile with the --output-style option', function(done) {
+ var src = fs.createReadStream(fixture('compressed/index.scss'));
+ var expected = read(fixture('compressed/expected.css'), 'utf8').trim();
+ var bin = spawn(cli, ['--output-style', 'compressed']);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ src.pipe(bin.stdin);
+ });
+
+ it('should compile with the --source-comments option', function(done) {
+ var src = fs.createReadStream(fixture('source-comments/index.scss'));
+ var expected = read(fixture('source-comments/expected.css'), 'utf8').trim();
+ var bin = spawn(cli, ['--source-comments']);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+
+ src.pipe(bin.stdin);
+ });
+
+ it('should render with indentWidth and indentType options', function(done) {
+ var src = new stream.Readable();
+ var bin = spawn(cli, ['--indent-width', 7, '--indent-type', 'tab']);
+
+ src._read = function() { };
+ src.push('div { color: transparent; }');
+ src.push(null);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), 'div {\n\t\t\t\t\t\t\tcolor: transparent; }');
+ done();
+ });
+
+ src.pipe(bin.stdin);
+ });
+
+ it('should render with linefeed option', function(done) {
+ var src = new stream.Readable();
+ var bin = spawn(cli, ['--linefeed', 'lfcr']);
+
+ src._read = function() { };
+ src.push('div { color: transparent; }');
+ src.push(null);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), 'div {\n\r color: transparent; }');
+ done();
+ });
+
+ src.pipe(bin.stdin);
+ });
+ });
+
+ describe('node-sass in.scss', function() {
+ it('should compile a scss file', function(done) {
+ process.chdir(fixture('simple'));
+
+ var src = fixture('simple/index.scss');
+ var dest = fixture('simple/index.css');
+ var bin = spawn(cli, [src, dest]);
+
+ bin.once('close', function() {
+ assert(fs.existsSync(dest));
+ fs.unlinkSync(dest);
+ process.chdir(__dirname);
+ done();
+ });
+ });
+
+ it('should compile a scss file to custom destination', function(done) {
+ process.chdir(fixture('simple'));
+
+ var src = fixture('simple/index.scss');
+ var dest = fixture('simple/index-custom.css');
+ var bin = spawn(cli, [src, dest]);
+
+ bin.once('close', function() {
+ assert(fs.existsSync(dest));
+ fs.unlinkSync(dest);
+ process.chdir(__dirname);
+ done();
+ });
+ });
+
+ it('should compile with the --include-path option', function(done) {
+ var includePaths = [
+ '--include-path', fixture('include-path/functions'),
+ '--include-path', fixture('include-path/lib')
+ ];
+
+ var src = fixture('include-path/index.scss');
+ var expected = read(fixture('include-path/expected.css'), 'utf8').trim();
+ var bin = spawn(cli, [src].concat(includePaths));
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.equal(data.trim(), expected.replace(/\r\n/g, '\n'));
+ done();
+ });
+ });
+
+ it('should compile silently using the --quiet option', function(done) {
+ process.chdir(fixture('simple'));
+
+ var src = fixture('simple/index.scss');
+ var dest = fixture('simple/index.css');
+ var bin = spawn(cli, [src, dest, '--quiet']);
+ var didEmit = false;
+
+ bin.stderr.once('data', function() {
+ didEmit = true;
+ });
+
+ bin.once('close', function() {
+ assert.equal(didEmit, false);
+ fs.unlinkSync(dest);
+ process.chdir(__dirname);
+ done();
+ });
+ });
+
+ it('should still report errors with the --quiet option', function(done) {
+ process.chdir(fixture('invalid'));
+
+ var src = fixture('invalid/index.scss');
+ var dest = fixture('invalid/index.css');
+ var bin = spawn(cli, [src, dest, '--quiet']);
+ var didEmit = false;
+
+ bin.stderr.once('data', function() {
+ didEmit = true;
+ });
+
+ bin.once('close', function() {
+ assert.equal(didEmit, true);
+ process.chdir(__dirname);
+ done();
+ });
+ });
+
+ it('should not exit with the --watch option', function(done) {
+ var src = fixture('simple/index.scss');
+ var bin = spawn(cli, [src, '--watch']);
+ var exited;
+
+ bin.once('close', function() {
+ exited = true;
+ });
+
+ setTimeout(function() {
+ if (exited) {
+ throw new Error('Watch ended too early!');
+ } else {
+ bin.kill();
+ done();
+ }
+ }, 100);
+ });
+
+ it.skip('should emit `warn` on file change when using --watch option', function(done) {
+ var src = fixture('simple/tmp.scss');
+
+ fs.writeFileSync(src, '');
+
+ var bin = spawn(cli, ['--watch', src]);
+
+ bin.stderr.setEncoding('utf8');
+ bin.stderr.once('data', function(data) {
+ assert.strictEqual(data.trim(), '=> changed: ' + src);
+ fs.unlinkSync(src);
+ bin.kill();
+ done();
+ });
+
+ setTimeout(function() {
+ fs.appendFileSync(src, 'body {}');
+ }, 500);
+ });
+
+ it.skip('should emit nothing on file change when using --watch and --quiet options', function(done) {
+ var src = fixture('simple/tmp.scss');
+ var didEmit = false;
+ fs.writeFileSync(src, '');
+
+ var bin = spawn(cli, ['--watch', '--quiet', src]);
+
+ bin.stderr.setEncoding('utf8');
+ bin.stderr.once('data', function() {
+ didEmit = true;
+ });
+
+ setTimeout(function() {
+ fs.appendFileSync(src, 'body {}');
+ setTimeout(function() {
+ assert.equal(didEmit, false);
+ bin.kill();
+ done();
+ fs.unlinkSync(src);
+ }, 200);
+ }, 500);
+ });
+
+ it.skip('should render all watched files', function(done) {
+ var src = fixture('simple/bar.scss');
+
+ fs.writeFileSync(src, '');
+
+ var bin = spawn(cli, [
+ '--output-style', 'compressed',
+ '--watch', src
+ ]);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.strictEqual(data.trim(), 'body{background:white}');
+ fs.unlinkSync(src);
+ bin.kill();
+ done();
+ });
+
+ setTimeout(function() {
+ fs.appendFileSync(src, 'body{background:white}');
+ }, 500);
+ });
+
+ it.skip('should watch the full scss dep tree for a single file (scss)', function(done) {
+ var src = fixture('watching/index.scss');
+ var foo = fixture('watching/white.scss');
+
+ fs.writeFileSync(foo, '');
+
+ var bin = spawn(cli, [
+ '--output-style', 'compressed',
+ '--watch', src
+ ]);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.strictEqual(data.trim(), 'body{background:blue}');
+ bin.kill();
+ done();
+ });
+
+ setTimeout(function() {
+ fs.appendFileSync(foo, 'body{background:blue}\n');
+ }, 500);
+ });
+
+ it.skip('should watch the full sass dep tree for a single file (sass)', function(done) {
+ var src = fixture('watching/index.sass');
+ var foo = fixture('watching/bar.sass');
+
+ fs.writeFileSync(foo, '');
+
+ var bin = spawn(cli, [
+ '--output-style', 'compressed',
+ '--watch', src
+ ]);
+
+ bin.stdout.setEncoding('utf8');
+ bin.stdout.once('data', function(data) {
+ assert.strictEqual(data.trim(), 'body{background:red}');
+ bin.kill();
+ done();
+ });
+
+ setTimeout(function() {
+ fs.appendFileSync(foo, 'body\n\tbackground: red\n');
+ }, 500);
+ });
+ });
+
+ describe('node-sass --output directory', function() {
+ it.skip('should watch whole directory', function(done) {
+ var destDir = fixture('watching-css-out-01/');
+ var srcDir = fixture('watching-dir-01/');
+ var srcFile = path.join(srcDir, 'index.scss');
+
+ fs.writeFileSync(srcFile, '');
+
+ var bin = spawn(cli, [
+ '--output-style', 'compressed',
+ '--output', destDir,
+ '--watch', srcDir
+ ]);
+
+ setTimeout(function() {
+ fs.appendFileSync(srcFile, 'a {color:green;}\n');
+ setTimeout(function() {
+ bin.kill();
+ var files = fs.readdirSync(destDir);
+ assert.deepEqual(files, ['index.css']);
+ rimraf(destDir, done);
+ }, 200);
+ }, 500);
+ });
+
+ it.skip('should compile all changed files in watched directory', function(done) {
+ var destDir = fixture('watching-css-out-02/');
+ var srcDir = fixture('watching-dir-02/');
+ var srcFile = path.join(srcDir, 'foo.scss');
+
+ fs.writeFileSync(srcFile, '');
+
+ var bin = spawn(cli, [
+ '--output-style', 'compressed',
+ '--output', destDir,
+ '--watch', srcDir
+ ]);
+
+ setTimeout(function () {
+ fs.appendFileSync(srcFile, 'body{background:white}\n');
+ setTimeout(function () {
+ bin.kill();
+ var files = fs.readdirSync(destDir);
+ assert.deepEqual(files, ['foo.css', 'index.css']);
+ rimraf(destDir, done);
+ }, 200);
+ }, 500);
+ });
+ });
+
+ describe('node-sass in.scss --output out.css', function() {
+ it('should compile a scss file to build.css', function(done) {
+ var src = fixture('simple/index.scss');
+ var dest = fixture('simple/index.css');
+ var bin = spawn(cli, [src, '--output', path.dirname(dest)]);
+
+ bin.once('close', function() {
+ assert(fs.existsSync(dest));
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should compile with the --source-map option', function(done) {
+ var src = fixture('source-map/index.scss');
+ var destCss = fixture('source-map/index.css');
+ var destMap = fixture('source-map/index.map');
+ var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
+ var expectedMap = read(fixture('source-map/expected.map'), 'utf8').trim().replace(/\r\n/g, '\n');
+ var bin = spawn(cli, [src, '--output', path.dirname(destCss), '--source-map', destMap]);
+
+ bin.once('close', function() {
+ assert.equal(read(destCss, 'utf8').trim(), expectedCss);
+ assert.equal(read(destMap, 'utf8').trim(), expectedMap);
+ fs.unlinkSync(destCss);
+ fs.unlinkSync(destMap);
+ done();
+ });
+ });
+
+ it('should omit sourceMappingURL if --omit-source-map-url flag is used', function(done) {
+ var src = fixture('source-map/index.scss');
+ var dest = fixture('source-map/index.css');
+ var map = fixture('source-map/index.map');
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--source-map', map, '--omit-source-map-url'
+ ]);
+
+ bin.once('close', function() {
+ assert.strictEqual(read(dest, 'utf8').indexOf('sourceMappingURL'), -1);
+ assert(fs.existsSync(map));
+ fs.unlinkSync(map);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should compile with the --source-root option', function(done) {
+ var src = fixture('source-map/index.scss');
+ var destCss = fixture('source-map/index.css');
+ var destMap = fixture('source-map/index.map');
+ var expectedCss = read(fixture('source-map/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
+ var expectedUrl = 'http://test/';
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(destCss),
+ '--source-map-root', expectedUrl,
+ '--source-map', destMap
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(destCss, 'utf8').trim(), expectedCss);
+ assert.equal(JSON.parse(read(destMap, 'utf8')).sourceRoot, expectedUrl);
+ fs.unlinkSync(destCss);
+ fs.unlinkSync(destMap);
+ done();
+ });
+ });
+
+ it('should compile with the --source-map-embed option and no outfile', function(done) {
+ var src = fixture('source-map-embed/index.scss');
+ var expectedCss = read(fixture('source-map-embed/expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
+ var result = '';
+ var bin = spawn(cli, [
+ src,
+ '--source-map-embed',
+ '--source-map', 'true'
+ ]);
+
+ bin.stdout.on('data', function(data) {
+ result += data;
+ });
+
+ bin.once('close', function() {
+ assert.equal(result.trim().replace(/\r\n/g, '\n'), expectedCss);
+ done();
+ });
+ });
+ });
+
+ describe('node-sass sass/ --output css/', function() {
+ it('should create the output directory', function(done) {
+ var src = fixture('input-directory/sass');
+ var dest = fixture('input-directory/css');
+ var bin = spawn(cli, [src, '--output', dest]);
+
+ bin.once('close', function() {
+ assert(fs.existsSync(dest));
+ rimraf.sync(dest);
+ done();
+ });
+ });
+
+ it('should compile all files in the folder', function(done) {
+ var src = fixture('input-directory/sass');
+ var dest = fixture('input-directory/css');
+ var bin = spawn(cli, [src, '--output', dest]);
+
+ bin.once('close', function() {
+ var files = fs.readdirSync(dest).sort();
+ assert.deepEqual(files, ['one.css', 'two.css', 'nested'].sort());
+ var nestedFiles = fs.readdirSync(path.join(dest, 'nested'));
+ assert.deepEqual(nestedFiles, ['three.css']);
+ rimraf.sync(dest);
+ done();
+ });
+ });
+
+ it('should compile with --source-map set to directory', function(done) {
+ var src = fixture('input-directory/sass');
+ var dest = fixture('input-directory/css');
+ var destMap = fixture('input-directory/map');
+ var bin = spawn(cli, [src, '--output', dest, '--source-map', destMap]);
+
+ bin.once('close', function() {
+ var map = JSON.parse(read(fixture('input-directory/map/nested/three.css.map'), 'utf8'));
+
+ assert.equal(map.file, '../../css/nested/three.css');
+ rimraf.sync(dest);
+ rimraf.sync(destMap);
+ done();
+ });
+ });
+
+ it('should skip files with an underscore', function(done) {
+ var src = fixture('input-directory/sass');
+ var dest = fixture('input-directory/css');
+ var bin = spawn(cli, [src, '--output', dest]);
+
+ bin.once('close', function() {
+ var files = fs.readdirSync(dest);
+ assert.equal(files.indexOf('_skipped.css'), -1);
+ rimraf.sync(dest);
+ done();
+ });
+ });
+
+ it('should ignore nested files if --recursive false', function(done) {
+ var src = fixture('input-directory/sass');
+ var dest = fixture('input-directory/css');
+ var bin = spawn(cli, [
+ src, '--output', dest,
+ '--recursive', false
+ ]);
+
+ bin.once('close', function() {
+ var files = fs.readdirSync(dest);
+ assert.deepEqual(files, ['one.css', 'two.css']);
+ rimraf.sync(dest);
+ done();
+ });
+ });
+
+ it('should error if no output directory is provided', function(done) {
+ var src = fixture('input-directory/sass');
+ var bin = spawn(cli, [src]);
+
+ bin.once('close', function(code) {
+ assert.notStrictEqual(code, 0);
+ assert.strictEqual(glob.sync(fixture('input-directory/**/*.css')).length, 0);
+ done();
+ });
+ });
+
+ it('should error if output directory is not a directory', function(done) {
+ var src = fixture('input-directory/sass');
+ var dest = fixture('input-directory/sass/one.scss');
+ var bin = spawn(cli, [src, '--output', dest]);
+
+ bin.once('close', function(code) {
+ assert.notStrictEqual(code, 0);
+ assert.equal(glob.sync(fixture('input-directory/**/*.css')).length, 0);
+ done();
+ });
+ });
+
+ it('should not error if output directory is a symlink', function(done) {
+ var outputDir = fixture('input-directory/css');
+ var src = fixture('input-directory/sass');
+ var symlink = fixture('symlinked-css');
+ fs.mkdirSync(outputDir);
+ fs.symlinkSync(outputDir, symlink);
+ var bin = spawn(cli, [src, '--output', symlink]);
+
+ bin.once('close', function() {
+ var files = fs.readdirSync(outputDir).sort();
+ assert.deepEqual(files, ['one.css', 'two.css', 'nested'].sort());
+ var nestedFiles = fs.readdirSync(path.join(outputDir, 'nested'));
+ assert.deepEqual(nestedFiles, ['three.css']);
+ rimraf.sync(outputDir);
+ fs.unlinkSync(symlink);
+ done();
+ });
+ });
+ });
+
+ describe('node-sass in.scss --output path/to/file/out.css', function() {
+ it('should create the output directory', function(done) {
+ var src = fixture('output-directory/index.scss');
+ var dest = fixture('output-directory/path/to/file/index.css');
+ var bin = spawn(cli, [src, '--output', path.dirname(dest)]);
+
+ bin.once('close', function() {
+ assert(fs.existsSync(path.dirname(dest)));
+ fs.unlinkSync(dest);
+ fs.rmdirSync(path.dirname(dest));
+ dest = path.dirname(dest);
+ fs.rmdirSync(path.dirname(dest));
+ dest = path.dirname(dest);
+ fs.rmdirSync(path.dirname(dest));
+ done();
+ });
+ });
+
+ });
+
+ describe('node-sass --follow --output output-dir input-dir', function() {
+ it('should compile with the --follow option', function(done) {
+ var src = fixture('follow/input-dir');
+ var dest = fixture('follow/output-dir');
+
+ fs.mkdirSync(src);
+ fs.symlinkSync(path.join(path.dirname(src), 'foo'), path.join(src, 'foo'), 'dir');
+
+ var bin = spawn(cli, [src, '--follow', '--output', dest]);
+
+ bin.once('close', function() {
+ var expected = path.join(dest, 'foo/bar/index.css');
+ fs.unlinkSync(path.join(src, 'foo'));
+ fs.rmdirSync(src);
+ assert(fs.existsSync(expected));
+ fs.unlinkSync(expected);
+ expected = path.dirname(expected);
+ fs.rmdirSync(expected);
+ expected = path.dirname(expected);
+ fs.rmdirSync(expected);
+ fs.rmdirSync(dest);
+ done();
+ });
+ });
+ });
+
+ describe('importer', function() {
+ var dest = fixture('include-files/index.css');
+ var src = fixture('include-files/index.scss');
+ var expected = read(fixture('include-files/expected-importer.css'), 'utf8').trim().replace(/\r\n/g, '\n');
+
+ it('should override imports and fire callback with file and contents', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_importer_file_and_data_cb.js')
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(dest, 'utf8').trim(), expected);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should override imports and fire callback with file', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_importer_file_cb.js')
+ ]);
+
+ bin.once('close', function() {
+ if (fs.existsSync(dest)) {
+ assert.equal(read(dest, 'utf8').trim(), '');
+ fs.unlinkSync(dest);
+ }
+
+ done();
+ });
+ });
+
+ it('should override imports and fire callback with data', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_importer_data_cb.js')
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(dest, 'utf8').trim(), expected);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should override imports and return file and contents', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_importer_file_and_data.js')
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(dest, 'utf8').trim(), expected);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should override imports and return file', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_importer_file.js')
+ ]);
+
+ bin.once('close', function() {
+ if (fs.existsSync(dest)) {
+ assert.equal(read(dest, 'utf8').trim(), '');
+ fs.unlinkSync(dest);
+ }
+
+ done();
+ });
+ });
+
+ it('should override imports and return data', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_importer_data.js')
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(dest, 'utf8').trim(), expected);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should accept arrays of importers and return respect the order', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_arrays_of_importers.js')
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(dest, 'utf8').trim(), expected);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should return error for invalid importer file path', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('non/existing/path')
+ ]);
+
+ bin.once('close', function(code) {
+ assert.notStrictEqual(code, 0);
+ done();
+ });
+ });
+
+ it('should reflect user-defined Error', function(done) {
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--importer', fixture('extras/my_custom_importer_error.js')
+ ]);
+
+ bin.stderr.once('data', function(code) {
+ assert.equal(JSON.parse(code).message, 'doesn\'t exist!');
+ done();
+ });
+ });
+ });
+
+ describe('functions', function() {
+ it('should let custom functions call setter methods on wrapped sass values (number)', function(done) {
+ var dest = fixture('custom-functions/setter.css');
+ var src = fixture('custom-functions/setter.scss');
+ var expected = read(fixture('custom-functions/setter-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--functions', fixture('extras/my_custom_functions_setter.js')
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(dest, 'utf8').trim(), expected);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+
+ it('should properly convert strings when calling custom functions', function(done) {
+ var dest = fixture('custom-functions/string-conversion.css');
+ var src = fixture('custom-functions/string-conversion.scss');
+ var expected = read(fixture('custom-functions/string-conversion-expected.css'), 'utf8').trim().replace(/\r\n/g, '\n');
+ var bin = spawn(cli, [
+ src, '--output', path.dirname(dest),
+ '--functions', fixture('extras/my_custom_functions_string_conversion.js')
+ ]);
+
+ bin.once('close', function() {
+ assert.equal(read(dest, 'utf8').trim(), expected);
+ fs.unlinkSync(dest);
+ done();
+ });
+ });
+ });
+});
diff --git a/node_modules/node-sass/test/downloadoptions.js b/node_modules/node-sass/test/downloadoptions.js
new file mode 100644
index 0000000..18daeb9
--- /dev/null
+++ b/node_modules/node-sass/test/downloadoptions.js
@@ -0,0 +1,74 @@
+var assert = require('assert'),
+ ua = require('../scripts/util/useragent'),
+ opts = require('../scripts/util/downloadoptions');
+
+
+describe('util', function() {
+ describe('downloadoptions', function() {
+ describe('without a proxy', function() {
+ it('should look as we expect', function() {
+ var expected = {
+ rejectUnauthorized: false,
+ timeout: 60000,
+ headers: {
+ 'User-Agent': ua(),
+ },
+ encoding: null,
+ };
+
+ assert.deepEqual(opts(), expected);
+ });
+ });
+
+ describe('with an npm config proxy', function() {
+ var proxy = 'http://test.proxy:1234';
+
+ before(function() {
+ process.env.npm_config_proxy = proxy;
+ });
+
+ after(function() {
+ delete process.env.npm_config_proxy;
+ });
+
+ it('should look as we expect', function() {
+ var expected = {
+ rejectUnauthorized: false,
+ proxy: proxy,
+ timeout: 60000,
+ headers: {
+ 'User-Agent': ua(),
+ },
+ encoding: null,
+ };
+
+ assert.deepEqual(opts(), expected);
+ });
+ });
+
+ describe('with an env proxy proxy', function() {
+ var proxy = 'http://test.proxy:1234';
+
+ before(function() {
+ process.env.HTTP_PROXY = proxy;
+ });
+
+ after(function() {
+ delete process.env.HTTP_PROXY;
+ });
+
+ it('should look as we expect', function() {
+ var expected = {
+ rejectUnauthorized: false,
+ timeout: 60000,
+ headers: {
+ 'User-Agent': ua(),
+ },
+ encoding: null,
+ };
+
+ assert.deepEqual(opts(), expected);
+ });
+ });
+ });
+});
diff --git a/node_modules/node-sass/test/errors.js b/node_modules/node-sass/test/errors.js
new file mode 100644
index 0000000..4570c19
--- /dev/null
+++ b/node_modules/node-sass/test/errors.js
@@ -0,0 +1,53 @@
+var assert = require('assert'),
+ path = require('path'),
+ errors = require('../lib/errors');
+
+describe('binary errors', function() {
+
+ function getCurrentPlatform() {
+ if (process.platform === 'win32') {
+ return 'Windows';
+ } else if (process.platform === 'darwin') {
+ return 'OS X';
+ }
+ return '';
+ }
+
+ function getCurrentArchitecture() {
+ if (process.arch === 'x86' || process.arch === 'ia32') {
+ return '32-bit';
+ } else if (process.arch === 'x64') {
+ return '64-bit';
+ }
+ return '';
+ }
+
+ function getCurrentEnvironment() {
+ return getCurrentPlatform() + ' ' + getCurrentArchitecture();
+ }
+
+ describe('for an unsupported environment', function() {
+ it('identifies the current environment', function() {
+ var message = errors.unsupportedEnvironment();
+ assert.ok(message.indexOf(getCurrentEnvironment()) !== -1);
+ });
+
+ it('links to supported environment documentation', function() {
+ var message = errors.unsupportedEnvironment();
+ assert.ok(message.indexOf('https://github.com/sass/node-sass/releases/tag/v') !== -1);
+ });
+ });
+
+ describe('for an missing binary', function() {
+ it('identifies the current environment', function() {
+ var message = errors.missingBinary();
+ assert.ok(message.indexOf(getCurrentEnvironment()) !== -1);
+ });
+
+ it('documents the expected binary location', function() {
+ var message = errors.missingBinary();
+ assert.ok(message.indexOf(path.sep + 'vendor' + path.sep) !== -1);
+ });
+ });
+
+});
diff --git a/node_modules/node-sass/test/fixtures/compressed/expected.css b/node_modules/node-sass/test/fixtures/compressed/expected.css
new file mode 100644
index 0000000..197319f
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/compressed/expected.css
@@ -0,0 +1 @@
+#navbar{width:80%;height:23px}#navbar ul{list-style-type:none}#navbar li{float:left}#navbar li a{font-weight:bold}
diff --git a/node_modules/node-sass/test/fixtures/compressed/index.scss b/node_modules/node-sass/test/fixtures/compressed/index.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/compressed/index.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css b/node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css
new file mode 100644
index 0000000..9b67ea9
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/custom-functions/setter-expected.css
@@ -0,0 +1,3 @@
+div {
+ width: 42rem;
+ height: 84px; }
diff --git a/node_modules/node-sass/test/fixtures/custom-functions/setter.scss b/node_modules/node-sass/test/fixtures/custom-functions/setter.scss
new file mode 100644
index 0000000..fbc6116
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/custom-functions/setter.scss
@@ -0,0 +1 @@
+div { width: foo(42px); height: bar(42px); }
diff --git a/node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css
new file mode 100644
index 0000000..741d2cb
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion-expected.css
@@ -0,0 +1,2 @@
+div {
+ color: "barbar"; }
diff --git a/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss
new file mode 100644
index 0000000..4e6403f
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/custom-functions/string-conversion.scss
@@ -0,0 +1 @@
+div { color: foo("bar"); }
diff --git a/node_modules/node-sass/test/fixtures/cwd-include-path/expected.css b/node_modules/node-sass/test/fixtures/cwd-include-path/expected.css
new file mode 100644
index 0000000..1cfd35a
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/cwd-include-path/expected.css
@@ -0,0 +1,2 @@
+.outside {
+ color: red; }
diff --git a/node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss b/node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss
new file mode 100644
index 0000000..9568623
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/cwd-include-path/outside.scss
@@ -0,0 +1,3 @@
+.outside {
+ color: red;
+}
diff --git a/node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss b/node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss
new file mode 100644
index 0000000..0279f78
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/cwd-include-path/root/index.scss
@@ -0,0 +1 @@
+@import 'outside';
diff --git a/node_modules/node-sass/test/fixtures/depth-first/_common.scss b/node_modules/node-sass/test/fixtures/depth-first/_common.scss
new file mode 100644
index 0000000..7b30f5e
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/_common.scss
@@ -0,0 +1,6 @@
+@import "vars";
+@import "struct";
+
+.myvars {
+ content: quote($import_counter);
+}
diff --git a/node_modules/node-sass/test/fixtures/depth-first/_struct.scss b/node_modules/node-sass/test/fixtures/depth-first/_struct.scss
new file mode 100644
index 0000000..f3152b7
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/_struct.scss
@@ -0,0 +1,3 @@
+.common-struct {
+ content: "common-struct";
+}
diff --git a/node_modules/node-sass/test/fixtures/depth-first/_vars.scss b/node_modules/node-sass/test/fixtures/depth-first/_vars.scss
new file mode 100644
index 0000000..da5a7f2
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/_vars.scss
@@ -0,0 +1,5 @@
+$import_counter: $import_counter + 1;
+
+.common-vars {
+ content: "common-vars";
+}
diff --git a/node_modules/node-sass/test/fixtures/depth-first/a.scss b/node_modules/node-sass/test/fixtures/depth-first/a.scss
new file mode 100644
index 0000000..6c815de
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/a.scss
@@ -0,0 +1,7 @@
+@import "_common";
+@import "a1";
+
+.a2 {
+ content: "a2";
+}
+
diff --git a/node_modules/node-sass/test/fixtures/depth-first/a1.scss b/node_modules/node-sass/test/fixtures/depth-first/a1.scss
new file mode 100644
index 0000000..272671b
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/a1.scss
@@ -0,0 +1,3 @@
+.a1 {
+ content: "a1";
+}
diff --git a/node_modules/node-sass/test/fixtures/depth-first/b.scss b/node_modules/node-sass/test/fixtures/depth-first/b.scss
new file mode 100644
index 0000000..2f21d7d
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/b.scss
@@ -0,0 +1,5 @@
+@import "b1";
+
+.b2 {
+ content: "b2";
+}
diff --git a/node_modules/node-sass/test/fixtures/depth-first/b1.scss b/node_modules/node-sass/test/fixtures/depth-first/b1.scss
new file mode 100644
index 0000000..ec7b88d
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/b1.scss
@@ -0,0 +1,3 @@
+.b1 {
+ content: "b1";
+}
diff --git a/node_modules/node-sass/test/fixtures/depth-first/expected.css b/node_modules/node-sass/test/fixtures/depth-first/expected.css
new file mode 100644
index 0000000..f83c268
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/expected.css
@@ -0,0 +1,32 @@
+.common-vars {
+ content: "common-vars"; }
+
+.common-struct {
+ content: "common-struct"; }
+
+.myvars {
+ content: "1"; }
+
+.a1 {
+ content: "a1"; }
+
+.a2 {
+ content: "a2"; }
+
+.common-vars {
+ content: "common-vars"; }
+
+.common-struct {
+ content: "common-struct"; }
+
+.myvars {
+ content: "2"; }
+
+.b1 {
+ content: "b1"; }
+
+.b2 {
+ content: "b2"; }
+
+#the-last {
+ content: "LAST"; } \ No newline at end of file
diff --git a/node_modules/node-sass/test/fixtures/depth-first/index.scss b/node_modules/node-sass/test/fixtures/depth-first/index.scss
new file mode 100644
index 0000000..09b0e76
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/depth-first/index.scss
@@ -0,0 +1,8 @@
+$import_counter: 0;
+@import "a";
+@import "common";
+@import "b";
+
+#the-last {
+ content: "LAST";
+}
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js b/node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js
new file mode 100644
index 0000000..38c1c08
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_arrays_of_importers.js
@@ -0,0 +1,12 @@
+var sass = require('../../..');
+
+module.exports = [
+ function() {
+ return sass.NULL;
+ },
+ function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+ }
+];
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js
new file mode 100644
index 0000000..9ec8c24
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_setter.js
@@ -0,0 +1,10 @@
+module.exports = {
+ 'foo($a)': function(size) {
+ size.setUnit('rem');
+ return size;
+ },
+ 'bar($a)': function(size) {
+ size.setValue(size.getValue() * 2);
+ return size;
+ }
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js
new file mode 100644
index 0000000..3aa4eb8
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_functions_string_conversion.js
@@ -0,0 +1,8 @@
+var sass = require('../../..');
+
+module.exports = {
+ 'foo($a)': function(str) {
+ str = str.getValue().replace(/['"]/g, '');
+ return new sass.types.String('"' + str + str + '"');
+ }
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js
new file mode 100644
index 0000000..23f272a
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data.js
@@ -0,0 +1,5 @@
+module.exports = function() {
+ return {
+ contents: 'div {color: yellow;}'
+ };
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js
new file mode 100644
index 0000000..d587304
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_data_cb.js
@@ -0,0 +1,5 @@
+module.exports = function(file, prev, done) {
+ done({
+ contents: 'div {color: yellow;}'
+ });
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js
new file mode 100644
index 0000000..eb1c959
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_error.js
@@ -0,0 +1,3 @@
+module.exports = function() {
+ return new Error('doesn\'t exist!');
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js
new file mode 100644
index 0000000..ad7b17d
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file.js
@@ -0,0 +1,7 @@
+var path = require('path');
+
+module.exports = function(file) {
+ return {
+ file: path.resolve(path.join(process.cwd(), 'test/fixtures/include-files/', file + (path.extname(file) ? '' : '.scss')))
+ };
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js
new file mode 100644
index 0000000..e29f042
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data.js
@@ -0,0 +1,6 @@
+module.exports = function() {
+ return {
+ file: '/some/random/path/file.scss',
+ contents: 'div {color: yellow;}'
+ };
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js
new file mode 100644
index 0000000..e24f05e
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_and_data_cb.js
@@ -0,0 +1,6 @@
+module.exports = function(file, prev, done) {
+ done({
+ file: '/some/random/path/file.scss',
+ contents: 'div {color: yellow;}'
+ });
+};
diff --git a/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js
new file mode 100644
index 0000000..dc5b8bd
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/extras/my_custom_importer_file_cb.js
@@ -0,0 +1,7 @@
+var path = require('path');
+
+module.exports = function(file, /* jshint unused:false */ prev, done) {
+ done({
+ file: path.resolve(path.join(process.cwd(), 'test/fixtures/include-files/', file + (path.extname(file) ? '' : '.scss')))
+ });
+};
diff --git a/node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss b/node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/follow/foo/bar/index.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/include-files/bar.scss b/node_modules/node-sass/test/fixtures/include-files/bar.scss
new file mode 100644
index 0000000..f377712
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-files/bar.scss
@@ -0,0 +1 @@
+/* bar.scss */
diff --git a/node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss b/node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss
new file mode 100644
index 0000000..8dbe665
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-files/chained-imports-with-custom-importer.scss
@@ -0,0 +1 @@
+@import "file-not-processed-by-loader", "file-processed-by-loader";
diff --git a/node_modules/node-sass/test/fixtures/include-files/expected-importer.css b/node_modules/node-sass/test/fixtures/include-files/expected-importer.css
new file mode 100644
index 0000000..1925a60
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-files/expected-importer.css
@@ -0,0 +1,5 @@
+div {
+ color: yellow; }
+
+div {
+ color: yellow; }
diff --git a/node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss b/node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss
new file mode 100644
index 0000000..47f8c1d
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-files/file-not-processed-by-loader.scss
@@ -0,0 +1 @@
+$variable-defined-by-file-not-processed-by-loader: 'red';
diff --git a/node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss b/node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss
new file mode 100644
index 0000000..4c79efe
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-files/file-processed-by-loader.scss
@@ -0,0 +1,3 @@
+body {
+ color: $variable-defined-by-file-not-processed-by-loader;
+}
diff --git a/node_modules/node-sass/test/fixtures/include-files/foo.scss b/node_modules/node-sass/test/fixtures/include-files/foo.scss
new file mode 100644
index 0000000..9834f54
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-files/foo.scss
@@ -0,0 +1 @@
+/* foo.scss */
diff --git a/node_modules/node-sass/test/fixtures/include-files/index.scss b/node_modules/node-sass/test/fixtures/include-files/index.scss
new file mode 100644
index 0000000..01bdbe2
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-files/index.scss
@@ -0,0 +1,2 @@
+@import 'foo';
+@import 'bar';
diff --git a/node_modules/node-sass/test/fixtures/include-path/expected.css b/node_modules/node-sass/test/fixtures/include-path/expected.css
new file mode 100644
index 0000000..1f0ae60
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-path/expected.css
@@ -0,0 +1,3 @@
+body {
+ background: red;
+ color: #0000fe; }
diff --git a/node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss b/node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss
new file mode 100644
index 0000000..4fa618c
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-path/functions/colorBlue.scss
@@ -0,0 +1,3 @@
+@function colorBlue() {
+ @return #0000fe;
+}
diff --git a/node_modules/node-sass/test/fixtures/include-path/index.scss b/node_modules/node-sass/test/fixtures/include-path/index.scss
new file mode 100644
index 0000000..8b0f5e8
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-path/index.scss
@@ -0,0 +1,7 @@
+@import 'vars';
+@import 'colorBlue';
+
+body {
+ background: $color;
+ color: colorBlue();
+}
diff --git a/node_modules/node-sass/test/fixtures/include-path/lib/vars.scss b/node_modules/node-sass/test/fixtures/include-path/lib/vars.scss
new file mode 100644
index 0000000..4b04915
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/include-path/lib/vars.scss
@@ -0,0 +1 @@
+$color: red;
diff --git a/node_modules/node-sass/test/fixtures/indent/expected.css b/node_modules/node-sass/test/fixtures/indent/expected.css
new file mode 100644
index 0000000..a7df077
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/indent/expected.css
@@ -0,0 +1,2 @@
+foo + bar {
+ color: red; }
diff --git a/node_modules/node-sass/test/fixtures/indent/index.sass b/node_modules/node-sass/test/fixtures/indent/index.sass
new file mode 100644
index 0000000..3f7dfae
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/indent/index.sass
@@ -0,0 +1,3 @@
+foo
+ + bar
+ color: red
diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/input-directory/sass/_skipped.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/input-directory/sass/nested/three.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/one.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/one.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/input-directory/sass/one.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/input-directory/sass/two.scss b/node_modules/node-sass/test/fixtures/input-directory/sass/two.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/input-directory/sass/two.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/invalid/index.scss b/node_modules/node-sass/test/fixtures/invalid/index.scss
new file mode 100644
index 0000000..e04c557
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/invalid/index.scss
@@ -0,0 +1,3 @@
+body {
+ background-color: $green;
+}
diff --git a/node_modules/node-sass/test/fixtures/output-directory/index.scss b/node_modules/node-sass/test/fixtures/output-directory/index.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/output-directory/index.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/precision/expected.css b/node_modules/node-sass/test/fixtures/precision/expected.css
new file mode 100644
index 0000000..c9a0a06
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/precision/expected.css
@@ -0,0 +1,2 @@
+.foo {
+ margin: 1.23456789 px; }
diff --git a/node_modules/node-sass/test/fixtures/precision/index.scss b/node_modules/node-sass/test/fixtures/precision/index.scss
new file mode 100644
index 0000000..328b214
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/precision/index.scss
@@ -0,0 +1,3 @@
+.foo {
+ margin: 1.23456789 px;
+}
diff --git a/node_modules/node-sass/test/fixtures/sass-path/expected-orange.css b/node_modules/node-sass/test/fixtures/sass-path/expected-orange.css
new file mode 100644
index 0000000..32b0627
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/sass-path/expected-orange.css
@@ -0,0 +1,3 @@
+body {
+ background: orange; }
+
diff --git a/node_modules/node-sass/test/fixtures/sass-path/expected-red.css b/node_modules/node-sass/test/fixtures/sass-path/expected-red.css
new file mode 100644
index 0000000..3884d51
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/sass-path/expected-red.css
@@ -0,0 +1,3 @@
+body {
+ background: red; }
+
diff --git a/node_modules/node-sass/test/fixtures/sass-path/index.scss b/node_modules/node-sass/test/fixtures/sass-path/index.scss
new file mode 100644
index 0000000..867386c
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/sass-path/index.scss
@@ -0,0 +1,6 @@
+@import 'colors';
+
+body {
+ background: $color;
+}
+
diff --git a/node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss b/node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss
new file mode 100644
index 0000000..ca95971
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/sass-path/orange/colors.scss
@@ -0,0 +1 @@
+$color: orange;
diff --git a/node_modules/node-sass/test/fixtures/sass-path/red/colors.scss b/node_modules/node-sass/test/fixtures/sass-path/red/colors.scss
new file mode 100644
index 0000000..4b04915
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/sass-path/red/colors.scss
@@ -0,0 +1 @@
+$color: red;
diff --git a/node_modules/node-sass/test/fixtures/simple/expected.css b/node_modules/node-sass/test/fixtures/simple/expected.css
new file mode 100644
index 0000000..402ae50
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/simple/expected.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/node_modules/node-sass/test/fixtures/simple/index.scss b/node_modules/node-sass/test/fixtures/simple/index.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/simple/index.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/source-comments/expected.css b/node_modules/node-sass/test/fixtures/source-comments/expected.css
new file mode 100644
index 0000000..53b1a38
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/source-comments/expected.css
@@ -0,0 +1,15 @@
+/* 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; }
diff --git a/node_modules/node-sass/test/fixtures/source-comments/index.scss b/node_modules/node-sass/test/fixtures/source-comments/index.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/source-comments/index.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/source-map-embed/expected.css b/node_modules/node-sass/test/fixtures/source-map-embed/expected.css
new file mode 100644
index 0000000..56f2e59
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/source-map-embed/expected.css
@@ -0,0 +1,13 @@
+#navbar {
+ width: 80%;
+ height: 23px; }
+
+#navbar ul {
+ list-style-type: none; }
+
+#navbar li {
+ float: left; }
+ #navbar li a {
+ font-weight: bold; }
+
+/*# sourceMappingURL=data:application/json;base64,ewoJInZlcnNpb24iOiAzLAoJImZpbGUiOiAiZml4dHVyZXMvc291cmNlLW1hcC1lbWJlZC9pbmRleC5jc3MiLAoJInNvdXJjZXMiOiBbCgkJImZpeHR1cmVzL3NvdXJjZS1tYXAtZW1iZWQvaW5kZXguc2NzcyIKCV0sCgkibmFtZXMiOiBbXSwKCSJtYXBwaW5ncyI6ICJBQUFBLEFBQUEsT0FBTyxDQUFDO0VBQ04sS0FBSyxFQUFFLEdBQUc7RUFDVixNQUFNLEVBQUUsSUFBSSxHQUNiOztBQUVELEFBQUEsT0FBTyxDQUFDLEVBQUUsQ0FBQztFQUNULGVBQWUsRUFBRSxJQUFJLEdBQ3RCOztBQUVELEFBQUEsT0FBTyxDQUFDLEVBQUUsQ0FBQztFQUNULEtBQUssRUFBRSxJQUFJLEdBS1o7RUFORCxBQUdFLE9BSEssQ0FBQyxFQUFFLENBR1IsQ0FBQyxDQUFDO0lBQ0EsV0FBVyxFQUFFLElBQUksR0FDbEIiCn0= */
diff --git a/node_modules/node-sass/test/fixtures/source-map-embed/index.scss b/node_modules/node-sass/test/fixtures/source-map-embed/index.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/source-map-embed/index.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/source-map/expected.css b/node_modules/node-sass/test/fixtures/source-map/expected.css
new file mode 100644
index 0000000..708bc47
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/source-map/expected.css
@@ -0,0 +1,13 @@
+#navbar {
+ width: 80%;
+ height: 23px; }
+
+#navbar ul {
+ list-style-type: none; }
+
+#navbar li {
+ float: left; }
+ #navbar li a {
+ font-weight: bold; }
+
+/*# sourceMappingURL=index.map */
diff --git a/node_modules/node-sass/test/fixtures/source-map/expected.map b/node_modules/node-sass/test/fixtures/source-map/expected.map
new file mode 100644
index 0000000..bd43765
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/source-map/expected.map
@@ -0,0 +1,9 @@
+{
+ "version": 3,
+ "file": "index.css",
+ "sources": [
+ "index.scss"
+ ],
+ "names": [],
+ "mappings": "AAAA,AAAA,OAAO,CAAC;EACN,KAAK,EAAE,GAAG;EACV,MAAM,EAAE,IAAI,GACb;;AAED,AAAA,OAAO,CAAC,EAAE,CAAC;EACT,eAAe,EAAE,IAAI,GACtB;;AAED,AAAA,OAAO,CAAC,EAAE,CAAC;EACT,KAAK,EAAE,IAAI,GAKZ;EAND,AAGE,OAHK,CAAC,EAAE,CAGR,CAAC,CAAC;IACA,WAAW,EAAE,IAAI,GAClB"
+}
diff --git a/node_modules/node-sass/test/fixtures/source-map/index.scss b/node_modules/node-sass/test/fixtures/source-map/index.scss
new file mode 100644
index 0000000..38a8fe6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/source-map/index.scss
@@ -0,0 +1,16 @@
+#navbar {
+ width: 80%;
+ height: 23px;
+}
+
+#navbar ul {
+ list-style-type: none;
+}
+
+#navbar li {
+ float: left;
+
+ a {
+ font-weight: bold;
+ }
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/main/one.scss b/node_modules/node-sass/test/fixtures/watcher/main/one.scss
new file mode 100644
index 0000000..414af5e
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/main/one.scss
@@ -0,0 +1,5 @@
+@import "partials/one";
+
+.one {
+ color: red;
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/main/partials/_one.scss b/node_modules/node-sass/test/fixtures/watcher/main/partials/_one.scss
new file mode 100644
index 0000000..379ec65
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/main/partials/_one.scss
@@ -0,0 +1,5 @@
+@import "partials/three";
+
+.one {
+ color: darkred;
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/main/partials/_three.scss b/node_modules/node-sass/test/fixtures/watcher/main/partials/_three.scss
new file mode 100644
index 0000000..1846e9a
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/main/partials/_three.scss
@@ -0,0 +1,3 @@
+.three {
+ color: darkgreen;
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/main/partials/_two.scss b/node_modules/node-sass/test/fixtures/watcher/main/partials/_two.scss
new file mode 100644
index 0000000..7a1ace9
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/main/partials/_two.scss
@@ -0,0 +1,5 @@
+@import "partials/three";
+
+.two {
+ color: darkblue;
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/main/three.scss b/node_modules/node-sass/test/fixtures/watcher/main/three.scss
new file mode 100644
index 0000000..24cab72
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/main/three.scss
@@ -0,0 +1,3 @@
+.three {
+ color: green;
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/main/two.scss b/node_modules/node-sass/test/fixtures/watcher/main/two.scss
new file mode 100644
index 0000000..68036db
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/main/two.scss
@@ -0,0 +1,3 @@
+.two {
+ color: blue;
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/sibling/partials/_three.scss b/node_modules/node-sass/test/fixtures/watcher/sibling/partials/_three.scss
new file mode 100644
index 0000000..1846e9a
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/sibling/partials/_three.scss
@@ -0,0 +1,3 @@
+.three {
+ color: darkgreen;
+}
diff --git a/node_modules/node-sass/test/fixtures/watcher/sibling/three.scss b/node_modules/node-sass/test/fixtures/watcher/sibling/three.scss
new file mode 100644
index 0000000..4e9d1a7
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watcher/sibling/three.scss
@@ -0,0 +1,5 @@
+@import "partials/three";
+
+.three {
+ color: green;
+}
diff --git a/node_modules/node-sass/test/fixtures/watching-dir-01/index.scss b/node_modules/node-sass/test/fixtures/watching-dir-01/index.scss
new file mode 100644
index 0000000..b189432
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watching-dir-01/index.scss
@@ -0,0 +1 @@
+a {color:green;}
diff --git a/node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss b/node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss
new file mode 100644
index 0000000..620aa31
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watching-dir-02/foo.scss
@@ -0,0 +1 @@
+body{background:white}
diff --git a/node_modules/node-sass/test/fixtures/watching-dir-02/index.scss b/node_modules/node-sass/test/fixtures/watching-dir-02/index.scss
new file mode 100644
index 0000000..dece2c6
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watching-dir-02/index.scss
@@ -0,0 +1 @@
+@import './foo';
diff --git a/node_modules/node-sass/test/fixtures/watching/bar.sass b/node_modules/node-sass/test/fixtures/watching/bar.sass
new file mode 100644
index 0000000..de9fd93
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watching/bar.sass
@@ -0,0 +1,2 @@
+body
+ background: white
diff --git a/node_modules/node-sass/test/fixtures/watching/index.sass b/node_modules/node-sass/test/fixtures/watching/index.sass
new file mode 100644
index 0000000..9f146c8
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watching/index.sass
@@ -0,0 +1 @@
+@import "bar.sass";
diff --git a/node_modules/node-sass/test/fixtures/watching/index.scss b/node_modules/node-sass/test/fixtures/watching/index.scss
new file mode 100644
index 0000000..7905647
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watching/index.scss
@@ -0,0 +1 @@
+@import './white';
diff --git a/node_modules/node-sass/test/fixtures/watching/white.scss b/node_modules/node-sass/test/fixtures/watching/white.scss
new file mode 100644
index 0000000..620aa31
--- /dev/null
+++ b/node_modules/node-sass/test/fixtures/watching/white.scss
@@ -0,0 +1 @@
+body{background:white}
diff --git a/node_modules/node-sass/test/lowlevel.js b/node_modules/node-sass/test/lowlevel.js
new file mode 100644
index 0000000..a849a46
--- /dev/null
+++ b/node_modules/node-sass/test/lowlevel.js
@@ -0,0 +1,243 @@
+process.env.NODESASS_COV ? require('../lib-cov') : require('../lib');
+
+var assert = require('assert'),
+ sass = require('../lib/extensions'),
+ binding = require(sass.getBinaryPath());
+
+describe('lowlevel', function() {
+ it('fail with options not an object', function(done) {
+ var options = 2;
+ assert.throws(function() {
+ binding.renderSync(options);
+ }, /"result" element is not an object/);
+ done();
+ });
+
+ it('data context with options.data not provided', function(done) {
+ var options = {
+ /* data: */
+ sourceComments: false,
+ file: null,
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: {} } };
+
+ binding.renderSync(options);
+ assert(/Data context created without a source string/.test(options.result.error),
+ 'Should fail with error message "Data context created without a source string"');
+ done();
+ });
+
+ it('data context with both options.data and options.file not provided', function(done) {
+ var options = {
+ /* data: */
+ sourceComments: false,
+ /* file: null, */
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: {} } };
+
+ binding.renderSync(options);
+ assert(/Data context created without a source string/.test(options.result.error),
+ 'Should fail with error message "Data context created without a source string"');
+ done();
+ });
+
+ it('file context with both options.data and options.file not provided', function(done) {
+ var options = {
+ /* data: */
+ sourceComments: false,
+ /* file: null, */
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: {} } };
+
+ binding.renderFileSync(options);
+ assert(/File context created without an input path/.test(options.result.error),
+ 'Should fail with error message "File context created without an input path"');
+ done();
+ });
+
+ it('file context with options.file not provided, options.data given', function(done) {
+ var options = {
+ data: 'div { width: 10px; } ',
+ sourceComments: false,
+ /* file: null, */
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: {} } };
+
+ binding.renderFileSync(options);
+ assert(/File context created without an input path/.test(options.result.error),
+ 'Should fail with error message "File context created without an input path"');
+ done();
+ });
+
+ it('fail with options.result not provided', function(done) {
+ var options = { data: 'div { width: 10px; } ',
+ sourceComments: false,
+ file: null,
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n' };
+
+ assert.throws(function() {
+ binding.renderSync(options);
+ }, /"result" element is not an object/);
+ done();
+ });
+
+
+ it('fail with options.result not an object', function(done) {
+ var options = { data: 'div { width: 10px; } ',
+ sourceComments: false,
+ file: null,
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n',
+ result: 2 };
+
+ assert.throws(function() {
+ binding.renderSync(options);
+ }, /"result" element is not an object/);
+ done();
+ });
+
+
+ it('fail with options.result.stats not provided', function(done) {
+
+ var options = { data: 'div { width: 10px; } ',
+ sourceComments: false,
+ file: null,
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n',
+ result: {} };
+
+ assert.throws(function() {
+ binding.renderSync(options);
+ }, /"result.stats" element is not an object/);
+ done();
+ });
+
+ it('fail with options.result.stats not an object', function(done) {
+
+ var options = { data: 'div { width: 10px; } ',
+ sourceComments: false,
+ file: null,
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ indentWidth: 2,
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: 2 } };
+
+ assert.throws(function() {
+ binding.renderSync(options);
+ }, /"result.stats" element is not an object/);
+ done();
+ });
+
+ it('options.indentWidth not provided', function(done) {
+ var options = { data: 'div { width: 10px; }',
+ sourceComments: false,
+ file: null,
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ /* indentWidth */
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: {} } };
+
+ binding.renderSync(options);
+ assert(options.result.css);
+ done();
+ });
+
+ it('empty data string', function(done) {
+ var options = { data: '',
+ sourceComments: false,
+ file: null,
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ /* indentWidth */
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: {} } };
+
+ binding.renderSync(options);
+ assert(/empty source string/.test(options.result.error),
+ 'Should fail with error message "Data context created with empty source string"');
+ done();
+ });
+
+
+ it('empty file string', function(done) {
+ var options = {
+ sourceComments: false,
+ file: '',
+ outFile: null,
+ includePaths: '',
+ precision: 5,
+ sourceMap: null,
+ style: 0,
+ /* indentWidth */
+ indentType: 0,
+ linefeed: '\n',
+ result: { stats: {} } };
+
+ binding.renderFileSync(options);
+ assert(/empty input path/.test(options.result.error),
+ 'Should fail with error message "File context created with empty input path"');
+ done();
+ });
+
+}); // lowlevel
diff --git a/node_modules/node-sass/test/runtime.js b/node_modules/node-sass/test/runtime.js
new file mode 100644
index 0000000..c4ae9d5
--- /dev/null
+++ b/node_modules/node-sass/test/runtime.js
@@ -0,0 +1,185 @@
+var assert = require('assert'),
+ sass = process.env.NODESASS_COV
+ ? require('../lib-cov/extensions')
+ : require('../lib/extensions');
+
+describe('runtime parameters', function() {
+ var pkg = require('../package'),
+ // Let's use JSON to fake a deep copy
+ savedArgv = JSON.stringify(process.argv),
+ savedEnv = JSON.stringify(process.env);
+
+ afterEach(function() {
+ process.argv = JSON.parse(savedArgv);
+ process.env = JSON.parse(savedEnv);
+ delete pkg.nodeSassConfig;
+ });
+
+ describe('configuration precedence should be respected', function() {
+
+ describe('SASS_BINARY_NAME', function() {
+ beforeEach(function() {
+ process.argv.push('--sass-binary-name', 'aaa');
+ process.env.SASS_BINARY_NAME = 'bbb';
+ process.env.npm_config_sass_binary_name = 'ccc';
+ pkg.nodeSassConfig = { binaryName: 'ddd' };
+ });
+
+ it('command line argument', function() {
+ assert.equal(sass.getBinaryName(), 'aaa_binding.node');
+ });
+
+ it('environment variable', function() {
+ process.argv = [];
+ assert.equal(sass.getBinaryName(), 'bbb_binding.node');
+ });
+
+ it('npm config variable', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_NAME = null;
+ assert.equal(sass.getBinaryName(), 'ccc_binding.node');
+ });
+
+ it('package.json', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_NAME = null;
+ process.env.npm_config_sass_binary_name = null;
+ assert.equal(sass.getBinaryName(), 'ddd_binding.node');
+ });
+ });
+
+ describe('SASS_BINARY_SITE', function() {
+ beforeEach(function() {
+ process.argv.push('--sass-binary-site', 'http://aaa.example.com:9999');
+ process.env.SASS_BINARY_SITE = 'http://bbb.example.com:8888';
+ process.env.npm_config_sass_binary_site = 'http://ccc.example.com:7777';
+ pkg.nodeSassConfig = { binarySite: 'http://ddd.example.com:6666' };
+ });
+
+ it('command line argument', function() {
+ var URL = 'http://aaa.example.com:9999';
+ assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL);
+ });
+
+ it('environment variable', function() {
+ process.argv = [];
+ var URL = 'http://bbb.example.com:8888';
+ assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL);
+ });
+
+ it('npm config variable', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_SITE = null;
+ var URL = 'http://ccc.example.com:7777';
+ assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL);
+ });
+
+ it('package.json', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_SITE = null;
+ process.env.npm_config_sass_binary_site = null;
+ var URL = 'http://ddd.example.com:6666';
+ assert.equal(sass.getBinaryUrl().substr(0, URL.length), URL);
+ });
+ });
+
+ describe('SASS_BINARY_DIR', function() {
+ beforeEach(function() {
+ process.argv.push('--sass-binary-dir', 'aaa');
+ process.env.SASS_BINARY_DIR = 'bbb';
+ process.env.npm_config_sass_binary_dir = 'ccc';
+ pkg.nodeSassConfig = { binaryDir: 'ddd' };
+ });
+
+ it('command line argument', function() {
+ assert.equal(sass.getBinaryDir(), 'aaa');
+ });
+
+ it('environment variable', function() {
+ process.argv = [];
+ assert.equal(sass.getBinaryDir(), 'bbb');
+ });
+
+ it('npm config variable', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_DIR = null;
+ assert.equal(sass.getBinaryDir(), 'ccc');
+ });
+
+ it('package.json', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_DIR = null;
+ process.env.npm_config_sass_binary_dir = null;
+ assert.equal(sass.getBinaryDir(), 'ddd');
+ });
+ });
+
+ describe('SASS_BINARY_PATH', function() {
+ beforeEach(function() {
+ process.argv.push('--sass-binary-path', 'aaa_binding.node');
+ process.env.SASS_BINARY_PATH = 'bbb_binding.node';
+ process.env.npm_config_sass_binary_path = 'ccc_binding.node';
+ pkg.nodeSassConfig = { binaryPath: 'ddd_binding.node' };
+ });
+
+ it('command line argument', function() {
+ assert.equal(sass.getBinaryPath(), 'aaa_binding.node');
+ });
+
+ it('environment variable', function() {
+ process.argv = [];
+ assert.equal(sass.getBinaryPath(), 'bbb_binding.node');
+ });
+
+ it('npm config variable', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_PATH = null;
+ assert.equal(sass.getBinaryPath(), 'ccc_binding.node');
+ });
+
+ it('package.json', function() {
+ process.argv = [];
+ process.env.SASS_BINARY_PATH = null;
+ process.env.npm_config_sass_binary_path = null;
+ assert.equal(sass.getBinaryPath(), 'ddd_binding.node');
+ });
+ });
+
+ });
+
+ describe.skip('Sass Binary Cache', function() {
+ var npmCacheDir;
+ before(function() {
+ npmCacheDir = process.env.npm_config_cache;
+ });
+
+ beforeEach(function() {
+ delete process.env.npm_config_sass_binary_cache;
+ });
+
+ it('npm config variable', function() {
+ var overridenCachePath = '/foo/bar/';
+ process.env.npm_config_sass_binary_cache = overridenCachePath;
+ assert.equal(sass.getCachePath(), overridenCachePath);
+ });
+
+ it('With no value, falls back to NPM cache', function() {
+ assert.equal(sass.getCachePath(), npmCacheDir);
+ });
+ });
+});
+
+// describe('library detection', function() {
+// it('should throw error when libsass binary is missing.', function() {
+// var sass = require(extensionsPath),
+// originalBin = sass.getBinaryPath(),
+// renamedBin = [originalBin, '_moved'].join('');
+
+// assert.throws(function() {
+// fs.renameSync(originalBin, renamedBin);
+// sass.getBinaryPath(true);
+// }, /The `libsass` binding was not found/);
+
+// fs.renameSync(renamedBin, originalBin);
+// });
+// });
diff --git a/node_modules/node-sass/test/scripts/util/proxy.js b/node_modules/node-sass/test/scripts/util/proxy.js
new file mode 100644
index 0000000..d829bdb
--- /dev/null
+++ b/node_modules/node-sass/test/scripts/util/proxy.js
@@ -0,0 +1,76 @@
+var assert = require('assert'),
+ proxy = require('../../../scripts/util/proxy');
+
+describe('proxy', function() {
+ var oldEnvironment;
+
+ beforeEach(function() {
+ oldEnvironment = process.env;
+ });
+
+ afterEach(function() {
+ process.env = oldEnvironment;
+ });
+
+ describe('without an npm proxy config', function() {
+ delete process.env.npm_config_https_proxy;
+ delete process.env.npm_config_proxy;
+ delete process.env.npm_config_http_proxy;
+
+ it('should return an empty string', function() {
+ assert.strictEqual('', proxy());
+ });
+
+ it('should ignore system proxy environment variables', function() {
+ process.env.HTTPS_PROXY = 'http://https_proxy.com';
+ process.env.PROXY = 'http://proxy.com';
+ process.env.HTTP_PROXY = 'http://http_proxy.com';
+
+ assert.strictEqual('', proxy());
+ });
+ });
+
+ describe('with an npm proxy config', function() {
+ beforeEach(function() {
+ process.env.npm_config_https_proxy = 'http://https_proxy.com';
+ process.env.npm_config_proxy = 'http://proxy.com';
+ process.env.npm_config_http_proxy = 'http://http_proxy.com';
+ });
+
+ describe('https_proxy', function() {
+ it('should have the highest precedence', function() {
+ assert.strictEqual(process.env.npm_config_https_proxy, proxy());
+ });
+ });
+
+ describe('proxy', function() {
+ it('should have the higher precedence than https_proxy', function() {
+ assert.strictEqual(process.env.npm_config_https_proxy, proxy());
+ delete process.env.npm_config_https_proxy;
+
+ assert.strictEqual(process.env.npm_config_proxy, proxy());
+ });
+
+ it('should have the lower precedence than http_proxy', function() {
+ delete process.env.npm_config_https_proxy;
+
+ assert.strictEqual(process.env.npm_config_proxy, proxy());
+ delete process.env.npm_config_proxy;
+
+ assert.strictEqual(process.env.npm_config_http_proxy, proxy());
+ });
+ });
+
+ describe('http_proxy', function() {
+ it('should have the lowest precedence', function() {
+ assert.strictEqual(process.env.npm_config_https_proxy, proxy());
+ delete process.env.npm_config_https_proxy;
+
+ assert.strictEqual(process.env.npm_config_proxy, proxy());
+ delete process.env.npm_config_proxy;
+
+ assert.strictEqual(process.env.npm_config_http_proxy, proxy());
+ });
+ });
+ });
+}); \ No newline at end of file
diff --git a/node_modules/node-sass/test/spec.js b/node_modules/node-sass/test/spec.js
new file mode 100644
index 0000000..1ccaa8d
--- /dev/null
+++ b/node_modules/node-sass/test/spec.js
@@ -0,0 +1,192 @@
+var assert = require('assert'),
+ fs = require('fs'),
+ exists = fs.existsSync,
+ join = require('path').join,
+ read = fs.readFileSync,
+ sass = process.env.NODESASS_COV
+ ? require('../lib-cov')
+ : require('../lib'),
+ readYaml = require('read-yaml'),
+ mergeWith = require('lodash/mergeWith'),
+ assign = require('lodash/assign'),
+ glob = require('glob'),
+ specPath = require('sass-spec').dirname.replace(/\\/g, '/'),
+ impl = 'libsass',
+ version = 3.5;
+
+var normalize = function(str) {
+ // This should be /\r\n/g, '\n', but there seems to be some empty line issues
+ return str.replace(/\s+/g, '');
+};
+
+var inputs = glob.sync(specPath + '/**/input.*');
+
+var initialize = function(inputCss, options) {
+ var testCase = {};
+ var folders = inputCss.split('/');
+ var folder = join(inputCss, '..');
+ testCase.folder = folder;
+ testCase.name = folders[folders.length - 2];
+ testCase.inputPath = inputCss;
+ testCase.expectedPath = join(folder, 'expected_output.css');
+ testCase.errorPath = join(folder, 'error');
+ testCase.statusPath = join(folder, 'status');
+ testCase.optionsPath = join(folder, 'options.yml');
+ if (exists(testCase.optionsPath)) {
+ options = mergeWith(assign({}, options), readYaml.sync(testCase.optionsPath), customizer);
+ }
+ testCase.includePaths = [
+ folder,
+ join(folder, 'sub')
+ ];
+ testCase.precision = parseFloat(options[':precision']) || 5;
+ testCase.outputStyle = options[':output_style'] ? options[':output_style'].replace(':', '') : 'nested';
+ testCase.todo = options[':todo'] !== undefined && options[':todo'] !== null && options[':todo'].indexOf(impl) !== -1;
+ testCase.only = options[':only_on'] !== undefined && options[':only_on'] !== null && options[':only_on'];
+ testCase.warningTodo = options[':warning_todo'] !== undefined && options[':warning_todo'] !== null && options[':warning_todo'].indexOf(impl) !== -1;
+ testCase.startVersion = parseFloat(options[':start_version']) || 0;
+ testCase.endVersion = parseFloat(options[':end_version']) || 99;
+ testCase.options = options;
+ testCase.result = false;
+
+ // Probe filesystem once and cache the results
+ testCase.shouldFail = exists(testCase.statusPath) && !fs.statSync(testCase.statusPath).isDirectory();
+ testCase.verifyStderr = exists(testCase.errorPath) && !fs.statSync(testCase.errorPath).isDirectory();
+ return testCase;
+};
+
+var runTest = function(inputCssPath, options) {
+ var test = initialize(inputCssPath, options);
+
+ it(test.name, function(done) {
+ if (test.todo || test.warningTodo) {
+ this.skip('Test marked with TODO');
+ } else if (test.only && test.only.indexOf(impl) === -1) {
+ this.skip('Tests marked for only: ' + test.only.join(', '));
+ } else if (version < test.startVersion) {
+ this.skip('Tests marked for newer Sass versions only');
+ } else if (version > test.endVersion) {
+ this.skip('Tests marked for older Sass versions only');
+ } else {
+ var expected = normalize(read(test.expectedPath, 'utf8'));
+ sass.render({
+ file: test.inputPath,
+ includePaths: test.includePaths,
+ precision: test.precision,
+ outputStyle: test.outputStyle
+ }, function(error, result) {
+ if (test.shouldFail) {
+ // Replace 1, with parseInt(read(test.statusPath, 'utf8')) pending
+ // https://github.com/sass/libsass/issues/2162
+ assert.equal(error.status, 1);
+ } else if (test.verifyStderr) {
+ var expectedError = read(test.errorPath, 'utf8');
+ if (error === null) {
+ // Probably a warning
+ assert.ok(expectedError, 'Expected some sort of warning, but found none');
+ } else {
+ // The error messages seem to have some differences in areas
+ // like line numbering, so we'll check the first line for the
+ // general errror message only
+ assert.equal(
+ error.formatted.toString().split('\n')[0],
+ expectedError.toString().split('\n')[0],
+ 'Should Error.\nOptions' + JSON.stringify(test.options));
+ }
+ } else if (expected) {
+ assert.equal(
+ normalize(result.css.toString()),
+ expected,
+ 'Should equal with options ' + JSON.stringify(test.options)
+ );
+ }
+ done();
+ });
+ }
+ });
+};
+
+var specSuite = {
+ name: specPath.split('/').slice(-1)[0],
+ folder: specPath,
+ tests: [],
+ suites: [],
+ options: {}
+};
+
+function customizer(objValue, srcValue) {
+ if (Array.isArray(objValue)) {
+ return objValue.concat(srcValue);
+ }
+}
+
+var executeSuite = function(suite, tests) {
+ var suiteFolderLength = suite.folder.split('/').length;
+ var optionsFile = join(suite.folder, 'options.yml');
+ if (exists(optionsFile)) {
+ suite.options = mergeWith(assign({}, suite.options), readYaml.sync(optionsFile), customizer);
+ }
+
+ // Push tests in the current suite
+ tests = tests.filter(function(test) {
+ var testSuiteFolder = test.split('/');
+ var inputSass = testSuiteFolder[suiteFolderLength + 1];
+ // Add the test if the specPath matches the testname
+ if (inputSass === 'input.scss' || inputSass === 'input.sass') {
+ suite.tests.push(test);
+ } else {
+ return test;
+ }
+ });
+
+ if (tests.length !== 0) {
+ var prevSuite = tests[0].split('/')[suiteFolderLength];
+ var suiteName = '';
+ var prevSuiteStart = 0;
+ for (var i = 0; i < tests.length; i++) {
+ var test = tests[i];
+ suiteName = test.split('/')[suiteFolderLength];
+ if (suiteName !== prevSuite) {
+ suite.suites.push(
+ executeSuite(
+ {
+ name: prevSuite,
+ folder: suite.folder + '/' + prevSuite,
+ tests: [],
+ suites: [],
+ options: assign({}, suite.options),
+ },
+ tests.slice(prevSuiteStart, i)
+ )
+ );
+ prevSuite = suiteName;
+ prevSuiteStart = i;
+ }
+ }
+ suite.suites.push(
+ executeSuite(
+ {
+ name: suiteName,
+ folder: suite.folder + '/' + suiteName,
+ tests: [],
+ suites: [],
+ options: assign({}, suite.options),
+ },
+ tests.slice(prevSuiteStart, tests.length)
+ )
+ );
+ }
+ return suite;
+};
+var allSuites = executeSuite(specSuite, inputs);
+var runSuites = function(suite) {
+ describe(suite.name, function(){
+ suite.tests.forEach(function(test){
+ runTest(test, suite.options);
+ });
+ suite.suites.forEach(function(subsuite) {
+ runSuites(subsuite);
+ });
+ });
+};
+runSuites(allSuites);
diff --git a/node_modules/node-sass/test/types.js b/node_modules/node-sass/test/types.js
new file mode 100644
index 0000000..b1863af
--- /dev/null
+++ b/node_modules/node-sass/test/types.js
@@ -0,0 +1,643 @@
+/*eslint new-cap: ["error", { "capIsNew": false }]*/
+'use strict';
+
+var assert = require('assert');
+var sass = require('../');
+
+describe('sass.types', function() {
+ describe('Boolean', function() {
+ it('exists', function() {
+ assert(sass.types.Boolean);
+ });
+
+ it('names the constructor correctly', function() {
+ assert.equal(sass.types.Boolean.name, 'SassBoolean');
+ });
+
+ it('supports call constructor', function() {
+ var t = sass.types.Boolean(true);
+ assert.equal(t.toString(), '[object SassBoolean]');
+
+ var f = sass.types.Boolean(false);
+ assert.equal(f.toString(), '[object SassBoolean]');
+ });
+
+ it('has true and false singletons', function() {
+ assert.equal(sass.types.Boolean(true), sass.types.Boolean(true));
+ assert.equal(sass.types.Boolean(false), sass.types.Boolean(false));
+ assert.notEqual(sass.types.Boolean(false), sass.types.Boolean(true));
+ assert.equal(sass.types.Boolean(true), sass.types.Boolean.TRUE);
+ assert.equal(sass.types.Boolean(false), sass.types.Boolean.FALSE);
+ });
+
+ it('supports DOES NOT support new constructor', function() {
+ assert.throws(function() {
+ new sass.types.Boolean(true);
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Cannot instantiate SassBoolean');
+ return true;
+ });
+ });
+
+ it('throws with incorrect constructor args', function() {
+ assert.throws(function() {
+ sass.types.Boolean();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected one boolean argument');
+ return true;
+ });
+
+ [1, 2, '', 'hi', {}, []].forEach(function(arg) {
+ assert.throws(function() {
+ sass.types.Boolean(arg);
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected one boolean argument');
+ return true;
+ });
+ });
+
+ assert.throws(function() {
+ sass.types.Boolean(true, false);
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected one boolean argument');
+ return true;
+ });
+ });
+
+ it('implements getValue', function() {
+ var t = sass.types.Boolean(true);
+ assert.equal(typeof t.getValue, 'function');
+ assert.equal(t.getValue(), true);
+
+ var f = sass.types.Boolean(false);
+ assert.equal(typeof f.getValue, 'function');
+ assert.equal(f.getValue(), false);
+ });
+ });
+
+ describe('Color', function() {
+ it('exists', function() {
+ assert(sass.types.Color);
+ });
+
+ it('names the constructor correctly', function() {
+ assert.equal(sass.types.Color.name, 'SassColor');
+ });
+
+ it('supports call constructor', function() {
+ var t = sass.types.Color();
+ assert.equal(t.toString(), '[object SassColor]');
+ });
+
+ it('supports new constructor', function() {
+ var t = new sass.types.Color(1);
+ assert.equal(t.toString(), '[object SassColor]');
+ });
+
+ it('supports variadic constructor args', function() {
+ var a = new sass.types.Color();
+
+ assert.equal(a.getR(), 0);
+ assert.equal(a.getG(), 0);
+ assert.equal(a.getB(), 0);
+ assert.equal(a.getA(), 1);
+
+ var b = new sass.types.Color(1);
+
+ assert.equal(b.getR(), 0);
+ assert.equal(b.getG(), 0);
+ assert.equal(b.getB(), 1);
+ assert.equal(b.getA(), 0); // why ?
+
+ assert.throws(function() {
+ new sass.types.Color(1, 2);
+ }, function(error) {
+ // assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Constructor should be invoked with either 0, 1, 3 or 4 arguments.');
+ return true;
+ });
+
+ var c = new sass.types.Color(1, 2, 3);
+
+ assert.equal(c.getR(), 1);
+ assert.equal(c.getG(), 2);
+ assert.equal(c.getB(), 3);
+ assert.equal(c.getA(), 1);
+
+ var d = new sass.types.Color(1, 2, 3, 4);
+
+ assert.equal(d.getR(), 1);
+ assert.equal(d.getG(), 2);
+ assert.equal(d.getB(), 3);
+ assert.equal(d.getA(), 4);
+
+ assert.throws(function() {
+ new sass.types.Color(1, 2, 3, 4, 5);
+ }, function(error) {
+ // assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Constructor should be invoked with either 0, 1, 3 or 4 arguments.');
+ return true;
+ });
+ });
+
+ it('supports get{R,G,B,A} and set{R,G,B,A}', function() {
+ var c = new sass.types.Color();
+
+ assert.equal(c.getR(), 0);
+ assert.equal(c.getG(), 0);
+ assert.equal(c.getB(), 0);
+ assert.equal(c.getA(), 1);
+
+ assert.equal(c.setR(1), undefined);
+
+ assert.equal(c.getR(), 1);
+ assert.equal(c.getG(), 0);
+ assert.equal(c.getB(), 0);
+ assert.equal(c.getA(), 1);
+
+ assert.equal(c.setG(1), undefined);
+
+ assert.equal(c.getR(), 1);
+ assert.equal(c.getG(), 1);
+ assert.equal(c.getB(), 0);
+ assert.equal(c.getA(), 1);
+
+ assert.equal(c.setB(1), undefined);
+
+ assert.equal(c.getR(), 1);
+ assert.equal(c.getG(), 1);
+ assert.equal(c.getB(), 1);
+ assert.equal(c.getA(), 1);
+
+ assert.equal(c.setA(0), undefined);
+
+ assert.equal(c.getR(), 1);
+ assert.equal(c.getG(), 1);
+ assert.equal(c.getB(), 1);
+ assert.equal(c.getA(), 0);
+ });
+
+ it('throws with incorrect set{R,G,B,A} arguments', function() {
+ var c = new sass.types.Color();
+
+ function assertJustOneArgument(cb) {
+ assert.throws(function() {
+ cb();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected just one argument');
+
+ return true;
+ });
+ }
+
+ function assertNumberArgument(arg, cb) {
+ assert.throws(function() {
+ cb();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Supplied value should be a number');
+
+ return true;
+ }, 'argument was: ' + arg);
+ }
+
+ assertJustOneArgument(function() { c.setR(); });
+ assertJustOneArgument(function() { c.setG(); });
+ assertJustOneArgument(function() { c.setB(); });
+ assertJustOneArgument(function() { c.setA(); });
+
+ assertJustOneArgument(function() { c.setR(1, 2); });
+ assertJustOneArgument(function() { c.setG(1, 2); });
+ assertJustOneArgument(function() { c.setB(1, 2); });
+ assertJustOneArgument(function() { c.setA(1, 2); });
+
+ [true, false, '0', '1', '', 'omg', {}, []].forEach(function(arg) {
+ assertNumberArgument(arg, function() { c.setR(arg); });
+ assertNumberArgument(arg, function() { c.setG(arg); });
+ assertNumberArgument(arg, function() { c.setB(arg); });
+ assertNumberArgument(arg, function() { c.setA(arg); });
+ });
+ });
+ });
+
+ describe('Error', function() {
+ it('exists', function() {
+ assert(sass.types.Error);
+ });
+
+ it('has a correctly named constructor', function() {
+ assert.equal(sass.types.Error.name, 'SassError');
+ });
+
+ it('supports call constructor', function() {
+ var e = sass.types.Error('Such Error');
+ assert.ok(e instanceof sass.types.Error);
+ assert.equal(e.toString(), '[object SassError]');
+
+ // TODO: I'm not sure this object works well, it likely needs to be fleshed out more...
+ });
+
+ it('supports new constructor', function() {
+ var e = new sass.types.Error('Such Error');
+ assert.ok(e instanceof sass.types.Error);
+ assert.equal(e.toString(), '[object SassError]');
+ // TODO: I'm not sure this object works well, it likely needs to be fleshed out more...
+ });
+ });
+
+ describe('List', function() {
+ it('exists', function() {
+ assert(sass.types.List);
+ });
+
+ it('has a corectly named constructor', function() {
+ assert.equal(sass.types.List.name, 'SassList');
+ });
+
+ it('support call constructor', function() {
+ var list = sass.types.List();
+ assert.ok(list instanceof sass.types.List);
+ assert.equal(list.toString(), '[object SassList]');
+ });
+
+ it('support new constructor', function() {
+ var list = new sass.types.List();
+ assert.ok(list instanceof sass.types.List);
+ assert.equal(list.toString(), '[object SassList]');
+ });
+
+ it('support variadic constructor', function() {
+ var a = new sass.types.List();
+ assert.equal(a.getLength(), 0);
+ assert.equal(a.getSeparator(), true);
+ var b = new sass.types.List(1);
+ assert.equal(b.getSeparator(), true);
+ assert.equal(b.getLength(), 1);
+ var c = new sass.types.List(1, true);
+ assert.equal(b.getLength(), 1);
+ assert.equal(c.getSeparator(), true);
+ var d = new sass.types.List(1, false);
+ assert.equal(b.getLength(), 1);
+ assert.equal(d.getSeparator(), false);
+ var e = new sass.types.List(1, true, 2);
+ assert.equal(b.getLength(), 1);
+ assert.equal(e.getSeparator(), true);
+
+ assert.throws(function() {
+ new sass.types.List('not-a-number');
+ }, function(error) {
+ // TODO: TypeError
+ assert.equal(error.message, 'First argument should be an integer.');
+ return true;
+ });
+
+ assert.throws(function() {
+ new sass.types.List(1, 'not-a-boolean');
+ }, function(error) {
+ // TODO: TypeError
+ assert.equal(error.message, 'Second argument should be a boolean.');
+ return true;
+ });
+ });
+
+ it('supports {get,set}Separator', function() {
+ var a = new sass.types.List();
+ assert.equal(a.getSeparator(), true);
+ assert.equal(a.setSeparator(true), undefined);
+ assert.equal(a.getSeparator(), true);
+ assert.equal(a.setSeparator(false), undefined);
+ assert.equal(a.getSeparator(), false);
+
+ assert.throws(function() {
+ a.setSeparator();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected just one argument');
+ return true;
+ });
+
+ [1, '', [], {}].forEach(function(arg) {
+ assert.throws(function() {
+ a.setSeparator(arg);
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Supplied value should be a boolean');
+ return true;
+ }, 'setSeparator(' + arg + ')');
+ });
+ });
+
+ it('supports setValue and getValue', function() {
+ var a = new sass.types.List();
+
+ assert.throws(function() {
+ a.getValue();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected just one argument');
+
+ return true;
+ });
+
+ ['hi', [], {}].forEach(function(arg) {
+ assert.throws(function() {
+ a.getValue(arg);
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Supplied index should be an integer');
+
+ return true;
+ }, 'getValue(' + arg + ')');
+ });
+
+ assert.throws(function() {
+ a.getValue(0);
+ }, function(error) {
+ assert.ok(error instanceof RangeError);
+ assert.equal(error.message, 'Out of bound index');
+
+ return true;
+ });
+
+ assert.throws(function() {
+ a.getValue(-1);
+ }, function(error) {
+ assert.ok(error instanceof RangeError);
+ assert.equal(error.message, 'Out of bound index');
+
+ return true;
+ });
+
+ assert.throws(function() {
+ a.setValue();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected two arguments');
+ return true;
+ });
+
+ assert.throws(function() {
+ a.setValue(1);
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected two arguments');
+ return true;
+ });
+
+ assert.throws(function() {
+ a.setValue(0, 'no-a-sass-value');
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Supplied value should be a SassValue object');
+ return true;
+ });
+ });
+
+ // TODO: more complex set/get value scenarios
+ });
+
+ describe('Map', function() {
+ it('exists', function() {
+ assert(sass.types.Map);
+ });
+
+ it('has a correctly named constructor', function() {
+ assert.equal(sass.types.Map.name, 'SassMap');
+ });
+
+ it('supports call constructor', function() {
+ var x = sass.types.Map();
+ assert.equal(x.toString(), '[object SassMap]');
+ });
+
+ it('supports new constructor', function() {
+ var x = new sass.types.Map();
+ assert.equal(x.toString(), '[object SassMap]');
+ });
+
+ it('supports an optional constructor argument', function() {
+ var x = new sass.types.Map();
+ var y = new sass.types.Map(1);
+ var z = new sass.types.Map(2, 3);
+
+ assert.throws(function() {
+ new sass.types.Map('OMG');
+ }, function(error) {
+ assert.equal(error.message, 'First argument should be an integer.');
+ // TODO: TypeError
+
+ return true;
+ });
+
+ assert.equal(x.getLength(), 0);
+ assert.equal(y.getLength(), 1);
+ assert.equal(z.getLength(), 2);
+ });
+
+ it('supports length', function() {
+ var y = new sass.types.Map(1);
+ var z = new sass.types.Map(2);
+
+ assert.equal(y.getLength(), 1);
+ assert.equal(z.getLength(), 2);
+ });
+
+ it('supports {get,set}Value {get,set}Key', function() {
+ var y = new sass.types.Map(1);
+ var omg = new sass.types.String('OMG');
+ y.setValue(0, omg);
+ console.log(y.getValue(0));
+ });
+ });
+
+ describe('Null', function() {
+ it('exists', function() {
+ assert(sass.types.Null);
+ });
+
+ it('has a correctly named constructor', function() {
+ assert.equal(sass.types.Null.name, 'SassNull');
+ });
+
+ it('does not support new constructor', function() {
+ assert.throws(function() {
+ new sass.types.Null();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Cannot instantiate SassNull');
+ return true;
+ });
+ });
+
+ it('supports call constructor (and is a singleton)', function() {
+ assert.equal(sass.types.Null(), sass.types.Null());
+ assert.equal(sass.types.Null(), sass.types.Null.NULL);
+ });
+ });
+
+ describe('Number', function() {
+ it('exists', function() {
+ assert(sass.types.Number);
+ });
+
+ it('has a correctly named constructor', function() {
+ assert.equal(sass.types.Number.name, 'SassNumber');
+ });
+
+ it('supports new constructor', function() {
+ var number = new sass.types.Number();
+ assert.equal(number.toString(), '[object SassNumber]');
+ });
+
+ it('supports call constructor', function() {
+ var number = sass.types.Number();
+ assert.equal(number.toString(), '[object SassNumber]');
+ });
+
+ it('supports multiple constructor arguments', function() {
+ var a = new sass.types.Number();
+ var b = new sass.types.Number(1);
+ var c = new sass.types.Number(2, 'px');
+
+ assert.throws(function() {
+ new sass.types.Number('OMG');
+ }, function(error) {
+ // TODO: TypeError
+ assert.equal(error.message, 'First argument should be a number.');
+ return true;
+ });
+
+ assert.throws(function() {
+ new sass.types.Number(1, 2);
+ }, function(error) {
+ // TODO: TypeError
+ assert.equal(error.message, 'Second argument should be a string.');
+ return true;
+ });
+
+ assert.equal(a.getValue(), 0);
+ assert.equal(a.getUnit(), '');
+ assert.equal(b.getValue(), 1);
+ assert.equal(b.getUnit(), '');
+ assert.equal(c.getValue(), 2);
+ assert.equal(c.getUnit(), 'px');
+ });
+
+ it('supports get{Unit,Value}, set{Unit,Value}', function() {
+ var number = new sass.types.Number(1, 'px');
+ assert.equal(number.getValue(), 1);
+ assert.equal(number.getUnit(), 'px');
+
+ number.setValue(2);
+ assert.equal(number.getValue(), 2);
+ assert.equal(number.getUnit(), 'px');
+
+ number.setUnit('em');
+ assert.equal(number.getValue(), 2);
+ assert.equal(number.getUnit(), 'em');
+
+ assert.throws(function() {
+ number.setValue('OMG');
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Supplied value should be a number');
+ return true;
+ });
+
+ assert.throws(function() {
+ number.setValue();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected just one argument');
+ return true;
+ });
+
+ assert.throws(function() {
+ number.setUnit();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected just one argument');
+ return true;
+ });
+
+ assert.throws(function() {
+ number.setUnit(1);
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Supplied value should be a string');
+ return true;
+ });
+ });
+ });
+
+ describe('String', function() {
+ it('exists', function() {
+ assert(sass.types.String);
+ });
+
+ it('has a properly named constructor', function() {
+ assert.equal(sass.types.String.name, 'SassString');
+ });
+
+ it('supports call constructor', function() {
+ var x = sass.types.String('OMG');
+
+ assert.equal(x.toString(), '[object SassString]');
+ assert.equal(x.getValue(), 'OMG');
+ });
+
+ it('supports new constructor', function() {
+ var x = new sass.types.String('OMG');
+
+ assert.equal(x.toString(), '[object SassString]');
+ assert.equal(x.getValue(), 'OMG');
+ });
+
+ it('supports multiple constructor arg combinations', function() {
+ new sass.types.String();
+ new sass.types.String('OMG');
+ new sass.types.String('OMG', 'NOPE');
+
+ [null, undefined, [], {}, function() { }].forEach(function(arg) {
+ assert.throws(function() {
+ new sass.types.String(arg);
+ }, function(error) {
+ // TODO: TypeError
+ assert.equal(error.message, 'Argument should be a string.');
+ return true;
+ });
+ });
+ });
+
+ it('supports {get,set}Value', function() {
+ var x = new sass.types.String();
+
+ assert.equal(x.getValue(), '');
+ assert.equal(x.setValue('hi'), undefined);
+ assert.equal(x.getValue(), 'hi');
+ assert.equal(x.setValue('bye'), undefined);
+ assert.equal(x.getValue(), 'bye');
+
+ assert.throws(function() {
+ x.setValue();
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected just one argument');
+ return true;
+ });
+
+ assert.throws(function() {
+ x.setValue('hi', 'hi');
+ }, function(error) {
+ assert.ok(error instanceof TypeError);
+ assert.equal(error.message, 'Expected just one argument');
+ return true;
+ });
+ });
+ });
+});
diff --git a/node_modules/node-sass/test/useragent.js b/node_modules/node-sass/test/useragent.js
new file mode 100644
index 0000000..27e4e78
--- /dev/null
+++ b/node_modules/node-sass/test/useragent.js
@@ -0,0 +1,15 @@
+var assert = require('assert'),
+ pkg = require('../package.json'),
+ ua = require('../scripts/util/useragent');
+
+describe('util', function() {
+ describe('useragent', function() {
+ it('should look as we expect', function() {
+ var reNode = 'node/' + process.version;
+ var reSass = 'node-sass-installer/' + pkg.version;
+ var reUA = new RegExp('^' + reNode + ' ' + reSass + '$');
+
+ assert.ok(reUA.test(ua()));
+ });
+ });
+});
diff --git a/node_modules/node-sass/test/watcher.js b/node_modules/node-sass/test/watcher.js
new file mode 100644
index 0000000..c96d398
--- /dev/null
+++ b/node_modules/node-sass/test/watcher.js
@@ -0,0 +1,503 @@
+var assert = require('assert'),
+ fs = require('fs-extra'),
+ path = require('path'),
+ temp = require('unique-temp-dir'),
+ watcher = require('../lib/watcher');
+
+describe('watcher', function() {
+ var main, sibling;
+ var origin = path.join(__dirname, 'fixtures', 'watcher');
+
+ beforeEach(function() {
+ var fixture = temp();
+ fs.ensureDirSync(fixture);
+ fs.copySync(origin, fixture);
+ main = fs.realpathSync(path.join(fixture, 'main'));
+ sibling = fs.realpathSync(path.join(fixture, 'sibling'));
+ });
+
+ describe('with directory', function() {
+ beforeEach(function() {
+ watcher.reset({
+ directory: main,
+ includePath: [main]
+ });
+ });
+
+ describe('when a file is changed', function() {
+ describe('and it is in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should record its ancestors as changed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.changed, [
+ path.join(main, 'one.scss'),
+ ]);
+ });
+
+ it('should record its descendants as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.added, [
+ path.join(main, 'partials', '_three.scss'),
+ ]);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record itself as changed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.changed, [
+ file,
+ ]);
+ });
+
+ it('should record its descendants as added', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.added, [
+ path.join(main, 'partials', '_one.scss'),
+ path.join(main, 'partials', '_three.scss'),
+ ]);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+ });
+
+ describe('and is not in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should not record anything', function() {
+ var file = path.join(sibling, 'partials', '_three.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files, {
+ added: [],
+ changed: [],
+ removed: [],
+ });
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record itself as changed', function() {
+ var file = path.join(sibling, 'three.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files, {
+ added: [],
+ changed: [file],
+ removed: [],
+ });
+ });
+ });
+ });
+ });
+
+ describe('when a file is added', function() {
+ describe('and it is in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record its descendants as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, [
+ path.join(main, 'partials', '_three.scss')
+ ]);
+ });
+
+ it('should record nothing as changed', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.changed, []);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record its descendants as added', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, [
+ path.join(main, 'partials', '_one.scss'),
+ path.join(main, 'partials', '_three.scss'),
+ ]);
+ });
+
+ it('should record nothing as changed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.changed, []);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+ });
+ });
+
+ describe('when a file is removed', function() {
+ describe('and it is in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record its ancestors as changed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.changed, [
+ path.join(main, 'one.scss'),
+ ]);
+ });
+
+ it('should record itself as removed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.removed, [file]);
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record nothing as changed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.changed, []);
+ });
+
+ it('should record itself as removed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.removed, [file]);
+ });
+ });
+ });
+
+ describe('and is not in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should record nothing', function() {
+ var file = path.join(sibling, 'partials', '_three.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files, {
+ added: [],
+ changed: [],
+ removed: [],
+ });
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record nothing', function() {
+ var file = path.join(sibling, 'three.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files, {
+ added: [],
+ changed: [],
+ removed: [],
+ });
+ });
+ });
+ });
+ });
+ });
+
+ describe('with file', function() {
+ beforeEach(function() {
+ watcher.reset({
+ src: path.join(main, 'one.scss'),
+ includePath: [main]
+ });
+ });
+
+ describe('when a file is changed', function() {
+ describe('and it is in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should record its descendants as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.added, [
+ path.join(main, 'partials', '_three.scss'),
+ ]);
+ });
+
+ it('should record its ancenstors as changed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.changed, [
+ path.join(main, 'one.scss'),
+ ]);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record its descendants as added', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.added, [
+ path.join(main, 'partials', '_one.scss'),
+ path.join(main, 'partials', '_three.scss'),
+ ]);
+ });
+
+ it('should record itself as changed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.changed, [file]);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+ });
+
+ describe('and it is not in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should record nothing', function() {
+ var file = path.join(sibling, 'partials', '_three.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files, {
+ added: [],
+ changed: [],
+ removed: [],
+ });
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(sibling, 'three.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record itself as changed', function() {
+ var file = path.join(sibling, 'three.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.changed, [file]);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(sibling, 'three.scss');
+ var files = watcher.changed(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+ });
+ });
+
+ describe('when a file is added', function() {
+ describe('and it is in the graph', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record its descendants as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, [
+ path.join(main, 'partials', '_three.scss'),
+ ]);
+ });
+
+ it('should record nothing as changed', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.changed, []);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+
+ describe('and it is not in the graph', function() {
+ beforeEach(function() {
+ watcher.reset({
+ src: path.join(main, 'two.scss'),
+ includePath: [main]
+ });
+ });
+
+ describe('if it is a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, [
+ file,
+ ]);
+ });
+
+ it('should not record its descendants as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, [
+ file,
+ ]);
+ });
+
+ it('should record nothing as changed', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.changed, []);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'partials', '_three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record itself as added', function() {
+ var file = path.join(main, 'three.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.added, [
+ file,
+ ]);
+ });
+
+ it('should record nothing as changed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.changed, []);
+ });
+
+ it('should record nothing as removed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.added(file);
+ assert.deepEqual(files.removed, []);
+ });
+ });
+ });
+ });
+
+ describe('when a file is removed', function() {
+ describe('and it is in the graph', function() {
+ describe('if it is a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record its ancestors as changed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.changed, [
+ path.join(main, 'one.scss'),
+ ]);
+ });
+
+ it('should record itself as removed', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.removed, [file]);
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.added, []);
+ });
+
+ it('should record nothing as changed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.changed, []);
+ });
+
+ it('should record itself as removed', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files.removed, [file]);
+ });
+ });
+ });
+
+ describe('and is not in the graph', function() {
+ beforeEach(function() {
+ watcher.reset({
+ src: path.join(main, 'two.scss'),
+ includePath: [main]
+ });
+ });
+
+ describe('if it is a partial', function() {
+ it('should record nothing as added', function() {
+ var file = path.join(main, 'partials', '_one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files, {
+ added: [],
+ changed: [],
+ removed: [],
+ });
+ });
+ });
+
+ describe('if it is not a partial', function() {
+ it('should record nothing', function() {
+ var file = path.join(main, 'one.scss');
+ var files = watcher.removed(file);
+ assert.deepEqual(files, {
+ added: [],
+ changed: [],
+ removed: [],
+ });
+ });
+ });
+ });
+ });
+ });
+});