diff --git a/lib/index.js b/lib/index.js index 4d880a8f5..fafbe55f2 100644 --- a/lib/index.js +++ b/lib/index.js @@ -171,6 +171,11 @@ function buildIncludePaths(options) { ); } + // Preserve the behaviour people have come to expect. + // This behaviour was removed from Sass in 3.4 and + // LibSass in 3.5. + options.includePaths.unshift(process.cwd()); + return options.includePaths.join(path.delimiter); } diff --git a/test/api.js b/test/api.js index 8ff5a972d..e082c9714 100644 --- a/test/api.js +++ b/test/api.js @@ -87,6 +87,19 @@ describe('api', function() { }); }); + 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: '' @@ -96,27 +109,14 @@ describe('api', function() { }); }); - it('should NOT compile without parameters', function(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 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 throw error status 1 for bad input', function(done) { + it('should returnn error status 1 for bad input', function(done) { sass.render({ data: '#navbar width 80%;' }, function(error) { @@ -142,6 +142,23 @@ describe('api', function() { }); }); + 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(); @@ -1389,6 +1406,143 @@ describe('api', function() { 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() { diff --git a/test/fixtures/cwd-include-path/expected.css b/test/fixtures/cwd-include-path/expected.css new file mode 100644 index 000000000..1cfd35a4a --- /dev/null +++ b/test/fixtures/cwd-include-path/expected.css @@ -0,0 +1,2 @@ +.outside { + color: red; } diff --git a/test/fixtures/cwd-include-path/outside.scss b/test/fixtures/cwd-include-path/outside.scss new file mode 100644 index 000000000..956862381 --- /dev/null +++ b/test/fixtures/cwd-include-path/outside.scss @@ -0,0 +1,3 @@ +.outside { + color: red; +} diff --git a/test/fixtures/cwd-include-path/root/index.scss b/test/fixtures/cwd-include-path/root/index.scss new file mode 100644 index 000000000..0279f783b --- /dev/null +++ b/test/fixtures/cwd-include-path/root/index.scss @@ -0,0 +1 @@ +@import 'outside';