From 7656eff2976c45caf7f29a18073614dd20edabe7 Mon Sep 17 00:00:00 2001 From: xzyfer Date: Mon, 12 Mar 2018 00:02:26 +1100 Subject: [PATCH] Adopt airbnb eslint preset --- .eslintrc | 156 +------------------ index.js | 282 +++++++++++++++------------------- package.json | 4 +- test/lint.js | 37 +++-- test/main.js | 424 ++++++++++++++++++++++++--------------------------- 5 files changed, 350 insertions(+), 553 deletions(-) diff --git a/.eslintrc b/.eslintrc index 3a8ea38..6bebcd2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,159 +4,9 @@ env: mocha: true node: true -# globals: - ######################### - ## Only add globals if you're absolutely certain they need to be globals - ########################## - # console: true - -######################### -## set to 0 to allow -## set to 1 to disallow as warning -## set to 2 to disallow as error -######################### rules: - ######################### - ## Optional Rules - ######################### - # Disallow use of `console` - no-console: 2 - - # Disallow warning comments - no-warning-comments: - - 1 - - terms: - - todo - - fixme - location: anywhere - - # Warns when variables are defined but never used - no-unused-vars: 1 - - # Enforces comma style (first or last) - comma-style: + max-len: - 2 - - last + - 120 - # Enforces one true `this` variable - consistent-this: - - 2 - - self - # Allows dangling underscores in identifiers - no-underscore-dangle: 2 - - # Enforces function expressions to have a name - func-names: 0 - - # Set maximum depth of nested callbacks - max-nested-callbacks: - - 1 - - 3 - - ######################### - ## Core Rules - ########################## - # Enforces camel case names - camelcase: 2 - - # Prohibit use of == and != in favor of === and !== - eqeqeq: 2 - - # Suppresses warnings about == null comparisons - no-eq-null: 2 - - # No mixing tabs and spaces, with 2 spaces only - no-mixed-spaces-and-tabs: 2 - - # Prohibits use of a variable before it is defined - no-use-before-define: 2 - - # Requires capitalized names for constructor functions - new-cap: 2 - - # Prohibits use of explicitly undeclared variables - no-undef: 2 - - # Enforces Use Strict at the top of function scope - strict: - - 2 - - global - - # Requires variable declarations to be at the top - vars-on-top: 2 - - # Enforce curly braces around blocks in loops and conditionals - curly: 2 - - # Prohibits the use of immediate function invocations w/o wrapping in parentheses - wrap-iife: 2 - - # Prohibits `argument.caller` and `argument.callee` - no-caller: 2 - - # Requires all `for in` loops to filter object's items - guard-for-in: 2 - - # Prohibits comparing a variable against itself - no-self-compare: 2 - - # Prohibits use of `undefined` variable - no-undefined: 0 - - # Prohibits nested ternaries - no-nested-ternary: 2 - - # Enforces a space before blocks - space-before-blocks: - - 2 - - always - - # Enforces spaces following keywords - keyword-spacing: - - 2 - - after: true - - # Enforces quoted property names - quote-props: - - 2 - - always - - # Enforces padded blocks - padded-blocks: - - 1 - - never - - # Enforce functions as expressions - func-style: - - 2 - - expression - - # Require brace style - brace-style: - - 2 - - stroustrup - - # Prohibits Yoda conditions - yoda: - - 2 - - never - - # Enforce use of single quotation marks for strings. - quotes: - - 2 - - single - - # Disallow or enforce spaces inside of curly braces in objects. - object-curly-spacing: - - 2 - - always - - # Disallow or enforce spaces inside of brackets. - array-bracket-spacing: - - 2 - - never - - # Disallow or enforce spaces inside of computed properties. - computed-property-spacing: - - 2 - - never +extends: "airbnb-base" diff --git a/index.js b/index.js index be45916..bd146cd 100644 --- a/index.js +++ b/index.js @@ -1,186 +1,158 @@ -'use strict'; +const chalk = require('chalk'); +const PluginError = require('plugin-error'); +const replaceExtension = require('replace-ext'); +const stripAnsi = require('strip-ansi'); +const through = require('through2'); +const clonedeep = require('lodash.clonedeep'); +const path = require('path'); +const applySourceMap = require('vinyl-sourcemaps-apply'); -var chalk = require('chalk'); -var PluginError = require('plugin-error'); -var replaceExtension = require('replace-ext'); -var stripAnsi = require('strip-ansi'); -var through = require('through2'); -var clonedeep = require('lodash.clonedeep'); -var path = require('path'); -var applySourceMap = require('vinyl-sourcemaps-apply'); - -var PLUGIN_NAME = 'gulp-sass'; +const PLUGIN_NAME = 'gulp-sass'; ////////////////////////////// // Main Gulp Sass function ////////////////////////////// -var gulpSass = function gulpSass(options, sync) { - return through.obj(function(file, enc, cb) { - var opts, - filePush, - errorM, - callback, - result; +const gulpSass = (options, sync) => through.obj((file, enc, cb) => { // eslint-disable-line consistent-return + if (file.isNull()) { + return cb(null, file); + } - if (file.isNull()) { - return cb(null, file); - } - if (file.isStream()) { - return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported')); - } - if (path.basename(file.path).indexOf('_') === 0) { - return cb(); - } - if (!file.contents.length) { - file.path = replaceExtension(file.path, '.css'); - return cb(null, file); + if (file.isStream()) { + return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported')); + } + + if (path.basename(file.path).indexOf('_') === 0) { + return cb(); + } + + if (!file.contents.length) { + file.path = replaceExtension(file.path, '.css'); // eslint-disable-line no-param-reassign + return cb(null, file); + } + + const opts = clonedeep(options || {}); + opts.data = file.contents.toString(); + + // we set the file path here so that libsass can correctly resolve import paths + opts.file = file.path; + + // Ensure `indentedSyntax` is true if a `.sass` file + if (path.extname(file.path) === '.sass') { + opts.indentedSyntax = true; + } + + // Ensure file's parent directory in the include path + if (opts.includePaths) { + if (typeof opts.includePaths === 'string') { + opts.includePaths = [opts.includePaths]; } + } else { + opts.includePaths = []; + } + opts.includePaths.unshift(path.dirname(file.path)); - opts = clonedeep(options || {}); - opts.data = file.contents.toString(); + // Generate Source Maps if plugin source-map present + if (file.sourceMap) { + opts.sourceMap = file.path; + opts.omitSourceMapUrl = true; + opts.sourceMapContents = true; + } - // we set the file path here so that libsass can correctly resolve import paths - opts.file = file.path; + ////////////////////////////// + // Handles returning the file to the stream + ////////////////////////////// + const filePush = (sassObj) => { + let sassMap; + let sassMapFile; + let sassFileSrc; + let sassFileSrcPath; + let sourceFileIndex; - // Ensure `indentedSyntax` is true if a `.sass` file - if (path.extname(file.path) === '.sass') { - opts.indentedSyntax = true; - } - - // Ensure file's parent directory in the include path - if (opts.includePaths) { - if (typeof opts.includePaths === 'string') { - opts.includePaths = [opts.includePaths]; - } - } - else { - opts.includePaths = []; - } - - opts.includePaths.unshift(path.dirname(file.path)); - - // Generate Source Maps if plugin source-map present - if (file.sourceMap) { - opts.sourceMap = file.path; - opts.omitSourceMapUrl = true; - opts.sourceMapContents = true; - } - - ////////////////////////////// - // Handles returning the file to the stream - ////////////////////////////// - filePush = function filePush(sassObj) { - var sassMap, - sassMapFile, - sassFileSrc, - sassFileSrcPath, - sourceFileIndex; - - // Build Source Maps! - if (sassObj.map) { - // Transform map into JSON - sassMap = JSON.parse(sassObj.map.toString()); - // Grab the stdout and transform it into stdin - sassMapFile = sassMap.file.replace(/^stdout$/, 'stdin'); - // Grab the base file name that's being worked on - sassFileSrc = file.relative; - // Grab the path portion of the file that's being worked on - sassFileSrcPath = path.dirname(sassFileSrc); - if (sassFileSrcPath) { - // Prepend the path to all files in the sources array except the file that's being worked on - sourceFileIndex = sassMap.sources.indexOf(sassMapFile); - sassMap.sources = sassMap.sources.map(function(source, index) { - return (index === sourceFileIndex) ? source : path.join(sassFileSrcPath, source); - }); - } - - // Remove 'stdin' from souces and replace with filenames! - sassMap.sources = sassMap.sources.filter(function(src) { - if (src !== 'stdin') { - return src; - } + // Build Source Maps! + if (sassObj.map) { + // Transform map into JSON + sassMap = JSON.parse(sassObj.map.toString()); + // Grab the stdout and transform it into stdin + sassMapFile = sassMap.file.replace(/^stdout$/, 'stdin'); + // Grab the base file name that's being worked on + sassFileSrc = file.relative; + // Grab the path portion of the file that's being worked on + sassFileSrcPath = path.dirname(sassFileSrc); + if (sassFileSrcPath) { + // Prepend the path to all files in the sources array except the file that's being worked on + sourceFileIndex = sassMap.sources.indexOf(sassMapFile); + sassMap.sources = sassMap.sources.map((source, index) => { // eslint-disable-line arrow-body-style + return index === sourceFileIndex ? source : path.join(sassFileSrcPath, source); }); - - // Replace the map file with the original file name (but new extension) - sassMap.file = replaceExtension(sassFileSrc, '.css'); - // Apply the map - applySourceMap(file, sassMap); } - file.contents = sassObj.css; - file.path = replaceExtension(file.path, '.css'); + // Remove 'stdin' from souces and replace with filenames! + sassMap.sources = sassMap.sources.filter(src => src !== 'stdin' && src); - cb(null, file); - }; - - ////////////////////////////// - // Handles error message - ////////////////////////////// - errorM = function errorM(error) { - var relativePath = '', - filePath = error.file === 'stdin' ? file.path : error.file, - message = ''; - - filePath = filePath ? filePath : file.path; - relativePath = path.relative(process.cwd(), filePath); - - message += chalk.underline(relativePath) + '\n'; - message += error.formatted; - - error.messageFormatted = message; - error.messageOriginal = error.message; - error.message = stripAnsi(message); - - error.relativePath = relativePath; - - return cb(new PluginError( - PLUGIN_NAME, error - )); - }; - - if (sync !== true) { - ////////////////////////////// - // Async Sass render - ////////////////////////////// - callback = function(error, obj) { - if (error) { - return errorM(error); - } - filePush(obj); - }; - - gulpSass.compiler.render(opts, callback); + // Replace the map file with the original file name (but new extension) + sassMap.file = replaceExtension(sassFileSrc, '.css'); + // Apply the map + applySourceMap(file, sassMap); } - else { - ////////////////////////////// - // Sync Sass render - ////////////////////////////// - try { - result = gulpSass.compiler.renderSync(opts); - filePush(result); - } - catch (error) { + file.contents = sassObj.css; // eslint-disable-line no-param-reassign + file.path = replaceExtension(file.path, '.css'); // eslint-disable-line no-param-reassign + + cb(null, file); + }; + + ////////////////////////////// + // Handles error message + ////////////////////////////// + const errorM = (error) => { + const filePath = (error.file === 'stdin' ? file.path : error.file) || file.path; + const relativePath = path.relative(process.cwd(), filePath); + const message = [chalk.underline(relativePath), error.formatted].join('\n'); + + error.messageFormatted = message; // eslint-disable-line no-param-reassign + error.messageOriginal = error.message; // eslint-disable-line no-param-reassign + error.message = stripAnsi(message); // eslint-disable-line no-param-reassign + error.relativePath = relativePath; // eslint-disable-line no-param-reassign + + return cb(new PluginError(PLUGIN_NAME, error)); + }; + + if (sync !== true) { + ////////////////////////////// + // Async Sass render + ////////////////////////////// + const callback = (error, obj) => { // eslint-disable-line consistent-return + if (error) { return errorM(error); } + filePush(obj); + }; + + gulpSass.compiler.render(opts, callback); + } else { + ////////////////////////////// + // Sync Sass render + ////////////////////////////// + try { + filePush(gulpSass.compiler.renderSync(opts)); + } catch (error) { + return errorM(error); } - }); -}; + } +}); ////////////////////////////// // Sync Sass render ////////////////////////////// -gulpSass.sync = function sync(options) { - return gulpSass(options, true); -}; +gulpSass.sync = options => gulpSass(options, true); ////////////////////////////// // Log errors nicely ////////////////////////////// -gulpSass.logError = function logError(error) { - var message = new PluginError('sass', error.messageFormatted).toString(); - process.stderr.write(message + '\n'); +gulpSass.logError = (error) => { + const message = new PluginError('sass', error.messageFormatted).toString(); + process.stderr.write(`${message}\n`); this.emit('end'); }; diff --git a/package.json b/package.json index 77026d5..3c59031 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,10 @@ "vinyl-sourcemaps-apply": "^0.2.0" }, "devDependencies": { - "eslint": "^2.9.0", "autoprefixer": "^8.1.0", + "eslint": "^4.18.2", + "eslint-config-airbnb-base": "^12.1.0", + "eslint-plugin-import": "^2.9.0", "globule": "^1.0.0", "gulp": "^3.8.11", "gulp-postcss": "^7.0.1", diff --git a/test/lint.js b/test/lint.js index ba58856..071b8fc 100644 --- a/test/lint.js +++ b/test/lint.js @@ -1,16 +1,12 @@ -'use strict'; +const eslint = require('eslint'); +const should = require('should'); -var eslint = require('eslint'); -var should = require('should'); +describe('code style guide', () => { + it('index.js should follow our lint style guide', (done) => { + const cli = new eslint.CLIEngine({ rules: { 'spaced-comment': 0 } }); + const formatter = cli.getFormatter(); + const report = cli.executeOnFiles(['index.js']); -var cli = new eslint.CLIEngine(); -var formatter = cli.getFormatter(); - -var report; - -describe('code style guide', function() { - it('index.js should follow our lint style guide', function(done) { - report = cli.executeOnFiles(['index.js']); if (report.errorCount > 0 || report.warningCount > 0) { console.log(formatter(report.results)); } @@ -20,8 +16,11 @@ describe('code style guide', function() { done(); }); - it('test/main.js should follow our lint style guide', function(done) { - report = cli.executeOnFiles(['test/main.js']); + it('test/main.js should follow our lint style guide', (done) => { + const cli = new eslint.CLIEngine(); + const formatter = cli.getFormatter(); + const report = cli.executeOnFiles(['test/main.js']); + if (report.errorCount > 0 || report.warningCount > 0) { console.log(formatter(report.results)); } @@ -31,13 +30,11 @@ describe('code style guide', function() { done(); }); - it('test/lint.js should follow our lint style guide', function(done) { - cli = new eslint.CLIEngine({ - 'rules': { - 'no-console': 0 - } - }); - report = cli.executeOnFiles(['test/lint.js']); + it('test/lint.js should follow our lint style guide', (done) => { + const cli = new eslint.CLIEngine({ rules: { 'no-console': 0 } }); + const formatter = cli.getFormatter(); + const report = cli.executeOnFiles(['test/lint.js']); + if (report.errorCount > 0 || report.warningCount > 0) { console.log(formatter(report.results)); } diff --git a/test/main.js b/test/main.js index a963442..77f77af 100644 --- a/test/main.js +++ b/test/main.js @@ -1,121 +1,107 @@ -'use strict'; +const should = require('should'); +const Vinyl = require('vinyl'); +const path = require('path'); +const fs = require('fs'); +const sass = require('../index'); +const rimraf = require('rimraf'); +const gulp = require('gulp'); +const sourcemaps = require('gulp-sourcemaps'); +const postcss = require('gulp-postcss'); +const autoprefixer = require('autoprefixer'); +const tap = require('gulp-tap'); +const globule = require('globule'); -var should = require('should'); -var Vinyl = require('vinyl'); -var path = require('path'); -var fs = require('fs'); -var sass = require('../index'); -var rimraf = require('rimraf'); -var gulp = require('gulp'); -var sourcemaps = require('gulp-sourcemaps'); -var postcss = require('gulp-postcss'); -var autoprefixer = require('autoprefixer'); -var tap = require('gulp-tap'); -var globule = require('globule'); - -var createVinyl = function createVinyl(filename, contents) { - var base = path.join(__dirname, 'scss'); - var filePath = path.join(base, filename); +const createVinyl = (filename, contents) => { + const base = path.join(__dirname, 'scss'); + const filePath = path.join(base, filename); return new Vinyl({ - 'cwd': __dirname, - 'base': base, - 'path': filePath, - 'contents': contents || fs.readFileSync(filePath) + cwd: __dirname, + base, + path: filePath, + contents: contents || fs.readFileSync(filePath), }); }; -var normaliseEOL = function(str) { - if (typeof(str) === 'object') { - str = str.toString('utf8'); - } +const normaliseEOL = str => str.toString('utf8').replace(/\r\n/g, '\n'); - return str.replace(/\r\n/g, '\n'); -} - -describe('test helpers', function() { - it('should normalise EOL', function(done) { +describe('test helpers', () => { + it('should normalise EOL', (done) => { should.equal(normaliseEOL('foo\r\nbar'), 'foo\nbar'); should.equal(normaliseEOL('foo\nbar'), 'foo\nbar'); done(); }); }); -describe('gulp-sass -- async compile', function() { - it('should pass file when it isNull()', function(done) { - var stream = sass(); - var emptyFile = { - 'isNull': function () { - return true; - } +describe('gulp-sass -- async compile', () => { + it('should pass file when it isNull()', (done) => { + const stream = sass(); + const emptyFile = { + isNull: () => true, }; - stream.on('data', function(data) { + stream.on('data', (data) => { data.should.equal(emptyFile); done(); }); stream.write(emptyFile); }); - it('should emit error when file isStream()', function (done) { - var stream = sass(); - var streamFile = { - 'isNull': function () { - return false; - }, - 'isStream': function () { - return true; - } + it('should emit error when file isStream()', (done) => { + const stream = sass(); + const streamFile = { + isNull: () => false, + isStream: () => true, }; - stream.on('error', function(err) { + stream.on('error', (err) => { err.message.should.equal('Streaming not supported'); done(); }); stream.write(streamFile); }); - it('should compile an empty sass file', function(done) { - var sassFile = createVinyl('empty.scss'); - var stream = sass(); - stream.on('data', function(cssFile) { + it('should compile an empty sass file', (done) => { + const sassFile = createVinyl('empty.scss'); + const stream = sass(); + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); should.equal(path.basename(cssFile.path), 'empty.css'); - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'empty.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'empty.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); done(); }); stream.write(sassFile); }); - it('should compile a single sass file', function(done) { - var sassFile = createVinyl('mixins.scss'); - var stream = sass(); - stream.on('data', function(cssFile) { + it('should compile a single sass file', (done) => { + const sassFile = createVinyl('mixins.scss'); + const stream = sass(); + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); done(); }); stream.write(sassFile); }); - it('should compile multiple sass files', function(done) { - var files = [ + it('should compile multiple sass files', (done) => { + const files = [ createVinyl('mixins.scss'), - createVinyl('variables.scss') + createVinyl('variables.scss'), ]; - var stream = sass(); - var mustSee = files.length; - var expectedPath = path.join('expected', 'mixins.css'); + const stream = sass(); + let mustSee = files.length; + let expectedPath = path.join('expected', 'mixins.css'); - stream.on('data', function(cssFile) { + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); @@ -123,41 +109,42 @@ describe('gulp-sass -- async compile', function() { if (cssFile.path.indexOf('variables') !== -1) { expectedPath = path.join('expected', 'variables.css'); } - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8')) - ); - mustSee--; + + const actual = fs.readFileSync(path.join(__dirname, expectedPath), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); + + mustSee -= 1; if (mustSee <= 0) { done(); } }); - files.forEach(function (file) { + files.forEach((file) => { stream.write(file); }); }); - it('should compile files with partials in another folder', function(done) { - var sassFile = createVinyl('inheritance.scss'); - var stream = sass(); - stream.on('data', function(cssFile) { + it('should compile files with partials in another folder', (done) => { + const sassFile = createVinyl('inheritance.scss'); + const stream = sass(); + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'inheritance.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'inheritance.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); done(); }); stream.write(sassFile); }); - it('should handle sass errors', function(done) { - var errorFile = createVinyl('error.scss'); - var stream = sass(); + it('should handle sass errors', (done) => { + const errorFile = createVinyl('error.scss'); + const stream = sass(); - stream.on('error', function(err) { + stream.on('error', (err) => { // Error must include message body err.message.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1); // Error must include file error occurs in @@ -171,11 +158,11 @@ describe('gulp-sass -- async compile', function() { stream.write(errorFile); }); - it('should preserve the original sass error message', function(done) { - var errorFile = createVinyl('error.scss'); - var stream = sass(); + it('should preserve the original sass error message', (done) => { + const errorFile = createVinyl('error.scss'); + const stream = sass(); - stream.on('error', function(err) { + stream.on('error', (err) => { // Error must include original error message err.messageOriginal.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1); // Error must not format or change the original error message @@ -185,60 +172,48 @@ describe('gulp-sass -- async compile', function() { stream.write(errorFile); }); - it('should compile a single sass file if the file name has been changed in the stream', function(done) { - var sassFile = createVinyl('mixins.scss'); - var stream; - + it('should compile a single sass file if the file name has been changed in the stream', (done) => { + const sassFile = createVinyl('mixins.scss'); // Transform file name sassFile.path = path.join(path.join(__dirname, 'scss'), 'mixin--changed.scss'); - stream = sass(); - stream.on('data', function(cssFile) { + const stream = sass(); + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); cssFile.path.split(path.sep).pop().should.equal('mixin--changed.css'); should.exist(cssFile.relative); should.exist(cssFile.contents); - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); done(); }); stream.write(sassFile); }); - it('should preserve changes made in-stream to a Sass file', function(done) { - var sassFile = createVinyl('mixins.scss'); - var stream; - + it('should preserve changes made in-stream to a Sass file', (done) => { + const sassFile = createVinyl('mixins.scss'); // Transform file name - sassFile.contents = new Buffer('/* Added Dynamically */' + sassFile.contents.toString()); + sassFile.contents = Buffer.from(`/* Added Dynamically */${sassFile.contents.toString()}`); - stream = sass(); - stream.on('data', function(cssFile) { + const stream = sass(); + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); - String(normaliseEOL(cssFile.contents)).should.equal('/* Added Dynamically */\n' + - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)) + .should.equal(`/* Added Dynamically */\n${normaliseEOL(actual)}`); done(); }); stream.write(sassFile); }); - it('should work with gulp-sourcemaps', function(done) { - var sassFile = createVinyl('inheritance.scss'); - - // Expected sources are relative to file.base - var expectedSources = [ - 'inheritance.scss', - 'includes/_cats.scss', - 'includes/_dogs.sass', - ]; - - var stream; + it('should work with gulp-sourcemaps', (done) => { + const sassFile = createVinyl('inheritance.scss'); sassFile.sourceMap = '{' + '"version": 3,' + @@ -249,8 +224,15 @@ describe('gulp-sass -- async compile', function() { '"sourcesContent": [ "@import ../inheritance;" ]' + '}'; - stream = sass(); - stream.on('data', function(cssFile) { + // Expected sources are relative to file.base + const expectedSources = [ + 'inheritance.scss', + 'includes/_cats.scss', + 'includes/_dogs.sass', + ]; + + const stream = sass(); + stream.on('data', (cssFile) => { should.exist(cssFile.sourceMap); cssFile.sourceMap.sources.should.eql(expectedSources); done(); @@ -258,32 +240,32 @@ describe('gulp-sass -- async compile', function() { stream.write(sassFile); }); - it('should compile a single indented sass file', function(done) { - var sassFile = createVinyl('indent.sass'); - var stream = sass(); - stream.on('data', function(cssFile) { + it('should compile a single indented sass file', (done) => { + const sassFile = createVinyl('indent.sass'); + const stream = sass(); + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'indent.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'indent.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); done(); }); stream.write(sassFile); }); - it('should parse files in sass and scss', function(done) { - var files = [ + it('should parse files in sass and scss', (done) => { + const files = [ createVinyl('mixins.scss'), - createVinyl('indent.sass') + createVinyl('indent.sass'), ]; - var stream = sass(); - var mustSee = files.length; - var expectedPath = path.join('expected', 'mixins.css'); + const stream = sass(); + let mustSee = files.length; + let expectedPath = path.join('expected', 'mixins.css'); - stream.on('data', function(cssFile) { + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); @@ -291,125 +273,123 @@ describe('gulp-sass -- async compile', function() { if (cssFile.path.indexOf('indent') !== -1) { expectedPath = path.join('expected', 'indent.css'); } - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8')) - ); - mustSee--; + + const actual = fs.readFileSync(path.join(__dirname, expectedPath), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); + + mustSee -= 1; if (mustSee <= 0) { done(); } }); - files.forEach(function (file) { + files.forEach((file) => { stream.write(file); }); }); }); -describe('gulp-sass -- sync compile', function() { - beforeEach(function(done) { +describe('gulp-sass -- sync compile', () => { + beforeEach((done) => { rimraf(path.join(__dirname, 'results'), done); }); - it('should pass file when it isNull()', function(done) { - var stream = sass.sync(); - var emptyFile = { - 'isNull': function () { - return true; - } + it('should pass file when it isNull()', (done) => { + const stream = sass.sync(); + const emptyFile = { + isNull: () => true, }; - stream.on('data', function(data) { + stream.on('data', (data) => { data.should.equal(emptyFile); done(); }); stream.write(emptyFile); }); - it('should emit error when file isStream()', function (done) { - var stream = sass.sync(); - var streamFile = { - 'isNull': function () { - return false; - }, - 'isStream': function () { - return true; - } + it('should emit error when file isStream()', (done) => { + const stream = sass.sync(); + const streamFile = { + isNull: () => false, + isStream: () => true, }; - stream.on('error', function(err) { + stream.on('error', (err) => { err.message.should.equal('Streaming not supported'); done(); }); stream.write(streamFile); }); - it('should compile a single sass file', function(done) { - var sassFile = createVinyl('mixins.scss'); - var stream = sass.sync(); - stream.on('data', function(cssFile) { + it('should compile a single sass file', (done) => { + const sassFile = createVinyl('mixins.scss'); + const stream = sass.sync(); + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'mixins.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); done(); }); stream.write(sassFile); }); - it('should compile multiple sass files', function(done) { - var files = [ + it('should compile multiple sass files', (done) => { + const files = [ createVinyl('mixins.scss'), - createVinyl('variables.scss') + createVinyl('variables.scss'), ]; - var stream = sass.sync(); - var mustSee = files.length; - var expectedPath = path.join('expected', 'mixins.css'); + const stream = sass.sync(); + let mustSee = files.length; + let expectedPath = path.join('expected', 'mixins.css'); - stream.on('data', function(cssFile) { + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); + if (cssFile.path.indexOf('variables') !== -1) { expectedPath = path.join('expected', 'variables.css'); } - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8')) - ); - mustSee--; + + const actual = normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8')); + String(normaliseEOL(cssFile.contents)).should.equal(actual); + + mustSee -= 1; if (mustSee <= 0) { done(); } }); - files.forEach(function (file) { + files.forEach((file) => { stream.write(file); }); }); - it('should compile files with partials in another folder', function(done) { - var sassFile = createVinyl('inheritance.scss'); - var stream = sass.sync(); - stream.on('data', function(cssFile) { + it('should compile files with partials in another folder', (done) => { + const sassFile = createVinyl('inheritance.scss'); + const stream = sass.sync(); + + stream.on('data', (cssFile) => { should.exist(cssFile); should.exist(cssFile.path); should.exist(cssFile.relative); should.exist(cssFile.contents); - String(normaliseEOL(cssFile.contents)).should.equal( - normaliseEOL(fs.readFileSync(path.join(__dirname, 'expected', 'inheritance.css'), 'utf8')) - ); + + const actual = fs.readFileSync(path.join(__dirname, 'expected', 'inheritance.css'), 'utf8'); + String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual)); done(); }); stream.write(sassFile); }); - it('should handle sass errors', function(done) { - var errorFile = createVinyl('error.scss'); - var stream = sass.sync(); + it('should handle sass errors', (done) => { + const errorFile = createVinyl('error.scss'); + const stream = sass.sync(); - stream.on('error', function(err) { + stream.on('error', (err) => { err.message.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1); err.relativePath.should.equal(path.join('test', 'scss', 'error.scss')); done(); @@ -417,18 +397,16 @@ describe('gulp-sass -- sync compile', function() { stream.write(errorFile); }); - it('should work with gulp-sourcemaps', function(done) { - var sassFile = createVinyl('inheritance.scss'); + it('should work with gulp-sourcemaps', (done) => { + const sassFile = createVinyl('inheritance.scss'); // Expected sources are relative to file.base - var expectedSources = [ + const expectedSources = [ 'inheritance.scss', 'includes/_cats.scss', 'includes/_dogs.sass', ]; - var stream; - sassFile.sourceMap = '{' + '"version": 3,' + '"file": "scss/subdir/multilevelimport.scss",' + @@ -438,8 +416,8 @@ describe('gulp-sass -- sync compile', function() { '"sourcesContent": [ "@import ../inheritance;" ]' + '}'; - stream = sass.sync(); - stream.on('data', function(cssFile) { + const stream = sass.sync(); + stream.on('data', (cssFile) => { should.exist(cssFile.sourceMap); cssFile.sourceMap.sources.should.eql(expectedSources); done(); @@ -447,14 +425,14 @@ describe('gulp-sass -- sync compile', function() { stream.write(sassFile); }); - it('should work with gulp-sourcemaps and autoprefixer', function(done) { - var expectedSourcesBefore = [ + it('should work with gulp-sourcemaps and autoprefixer', (done) => { + const expectedSourcesBefore = [ 'inheritance.scss', 'includes/_cats.scss', 'includes/_dogs.sass', ]; - var expectedSourcesAfter = [ + const expectedSourcesAfter = [ 'includes/_cats.scss', 'includes/_dogs.sass', 'inheritance.scss', @@ -463,80 +441,78 @@ describe('gulp-sass -- sync compile', function() { gulp.src(path.join(__dirname, 'scss', 'inheritance.scss')) .pipe(sourcemaps.init()) .pipe(sass.sync()) - .pipe(tap(function(file) { + .pipe(tap((file) => { should.exist(file.sourceMap); file.sourceMap.sources.should.eql(expectedSourcesBefore); })) .pipe(postcss([autoprefixer()])) .pipe(sourcemaps.write()) .pipe(gulp.dest(path.join(__dirname, 'results'))) - .pipe(tap(function(file) { + .pipe(tap((file) => { should.exist(file.sourceMap); file.sourceMap.sources.should.eql(expectedSourcesAfter); })) .on('end', done); }); - it('should work with gulp-sourcemaps and a globbed source', function(done) { - var files, filesContent, actualContent, expectedContent, globPath; - globPath = path.join(__dirname, 'scss', 'globbed'); - files = globule.find(path.join(__dirname, 'scss', 'globbed', '**', '*.scss')); - filesContent = {}; + it('should work with gulp-sourcemaps and a globbed source', (done) => { + const globPath = path.join(__dirname, 'scss', 'globbed'); + const files = globule.find(path.join(__dirname, 'scss', 'globbed', '**', '*.scss')); + const filesContent = {}; - files.forEach(function(file) { - var source = path.normalize(path.relative(globPath, file)); + files.forEach((file) => { + const source = path.normalize(path.relative(globPath, file)); filesContent[source] = fs.readFileSync(file, 'utf8'); }); gulp.src(path.join(__dirname, 'scss', 'globbed', '**', '*.scss')) .pipe(sourcemaps.init()) .pipe(sass.sync()) - .pipe(tap(function(file) { + .pipe(tap((file) => { should.exist(file.sourceMap); - actualContent = normaliseEOL(file.sourceMap.sourcesContent[0]); - expectedContent = normaliseEOL(filesContent[path.normalize(file.sourceMap.sources[0])]); - actualContent.should.eql(expectedContent); + const actual = normaliseEOL(file.sourceMap.sourcesContent[0]); + const expected = normaliseEOL(filesContent[path.normalize(file.sourceMap.sources[0])]); + actual.should.eql(expected); })) .on('end', done); }); - it('should work with gulp-sourcemaps and autoprefixer with different file.base', function(done) { - var expectedSourcesBefore = [ + it('should work with gulp-sourcemaps and autoprefixer with different file.base', (done) => { + const expectedSourcesBefore = [ 'scss/inheritance.scss', 'scss/includes/_cats.scss', - 'scss/includes/_dogs.sass' + 'scss/includes/_dogs.sass', ]; - var expectedSourcesAfter = [ + const expectedSourcesAfter = [ 'scss/includes/_cats.scss', 'scss/includes/_dogs.sass', - 'scss/inheritance.scss' + 'scss/inheritance.scss', ]; - gulp.src(path.join(__dirname, 'scss', 'inheritance.scss'), { 'base': 'test' }) + gulp.src(path.join(__dirname, 'scss', 'inheritance.scss'), { base: 'test' }) .pipe(sourcemaps.init()) .pipe(sass.sync()) - .pipe(tap(function(file) { + .pipe(tap((file) => { should.exist(file.sourceMap); file.sourceMap.sources.should.eql(expectedSourcesBefore); })) .pipe(postcss([autoprefixer()])) - .pipe(tap(function(file) { + .pipe(tap((file) => { should.exist(file.sourceMap); file.sourceMap.sources.should.eql(expectedSourcesAfter); })) .on('end', done); }); - it('should work with empty files', function(done) { + it('should work with empty files', (done) => { gulp.src(path.join(__dirname, 'scss', 'empty.scss')) .pipe(sass.sync()) .pipe(gulp.dest(path.join(__dirname, 'results'))) - .pipe(tap(function() { + .pipe(tap(() => { try { fs.statSync(path.join(__dirname, 'results', 'empty.css')); - } - catch (e) { + } catch (e) { should.fail(false, true, 'Empty file was produced'); } }))