Merge pull request #667 from dlmanning/next
Drop support for non-Active LTS and Current releases
This commit is contained in:
commit
44be409bd9
156
.eslintrc
156
.eslintrc
|
@ -4,159 +4,9 @@ env:
|
||||||
mocha: true
|
mocha: true
|
||||||
node: 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:
|
rules:
|
||||||
#########################
|
max-len:
|
||||||
## 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:
|
|
||||||
- 2
|
- 2
|
||||||
- last
|
- 120
|
||||||
|
|
||||||
# Enforces one true `this` variable
|
extends: "airbnb-base"
|
||||||
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
|
|
||||||
|
|
12
.travis.yml
12
.travis.yml
|
@ -1,6 +1,8 @@
|
||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- "0.10"
|
|
||||||
- node
|
|
||||||
- iojs
|
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
|
language: node_js
|
||||||
|
|
||||||
|
node_js:
|
||||||
|
- lts/boron
|
||||||
|
- lts/carbon
|
||||||
|
- current
|
||||||
|
|
|
@ -4,6 +4,12 @@ Sass plugin for [Gulp](https://github.com/gulpjs/gulp).
|
||||||
|
|
||||||
**_Before filing an issue, please make sure you have [Updated to the latest Gulp Sass](https://github.com/dlmanning/gulp-sass/wiki/Update-to-the-latest-Gulp-Sass) and have gone through our [Common Issues and Their Fixes](https://github.com/dlmanning/gulp-sass/wiki/Common-Issues-and-Their-Fixes) section._**
|
**_Before filing an issue, please make sure you have [Updated to the latest Gulp Sass](https://github.com/dlmanning/gulp-sass/wiki/Update-to-the-latest-Gulp-Sass) and have gone through our [Common Issues and Their Fixes](https://github.com/dlmanning/gulp-sass/wiki/Common-Issues-and-Their-Fixes) section._**
|
||||||
|
|
||||||
|
# Support
|
||||||
|
|
||||||
|
Only [Active LTS and Current releases][1] are supported.
|
||||||
|
|
||||||
|
[1]: https://github.com/nodejs/Release#release-schedule
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -52,7 +58,7 @@ gulp.task('sass:watch', function () {
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
Pass in options just like you would for [`node-sass`](https://github.com/sass/node-sass#options); they will be passed along just as if you were using `node-sass`. Except for the `data` option which is used by gulp-sass internally. Using the `file` option is also unsupported and results in undefined behaviour that may change without notice.
|
Pass in options just like you would for [`node-sass`](https://github.com/sass/node-sass#options); they will be passed along just as if you were using `node-sass`. Except for the `data` option which is used by gulp-sass internally. Using the `file` option is also unsupported and results in undefined behaviour that may change without notice.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,9 @@ platform:
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- nodejs_version: 0.10
|
- nodejs_version: lts/boron
|
||||||
- nodejs_version: 0.12
|
- nodejs_version: lts/carbon
|
||||||
- nodejs_version: 4
|
- nodejs_version: current
|
||||||
- nodejs_version: 6
|
|
||||||
- nodejs_version: 8
|
|
||||||
- nodejs_version: 9
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
- ps: Install-Product node $env:nodejs_version $env:platform
|
||||||
|
|
279
index.js
279
index.js
|
@ -1,183 +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 gutil = require('gulp-util');
|
const PLUGIN_NAME = 'gulp-sass';
|
||||||
var through = require('through2');
|
|
||||||
var clonedeep = require('lodash.clonedeep');
|
|
||||||
var path = require('path');
|
|
||||||
var applySourceMap = require('vinyl-sourcemaps-apply');
|
|
||||||
|
|
||||||
var PLUGIN_NAME = 'gulp-sass';
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Main Gulp Sass function
|
// Main Gulp Sass function
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
var gulpSass = function gulpSass(options, sync) {
|
const gulpSass = (options, sync) => through.obj((file, enc, cb) => { // eslint-disable-line consistent-return
|
||||||
return through.obj(function(file, enc, cb) {
|
if (file.isNull()) {
|
||||||
var opts,
|
return cb(null, file);
|
||||||
filePush,
|
}
|
||||||
errorM,
|
|
||||||
callback,
|
|
||||||
result;
|
|
||||||
|
|
||||||
if (file.isNull()) {
|
if (file.isStream()) {
|
||||||
return cb(null, file);
|
return cb(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
|
||||||
}
|
}
|
||||||
if (file.isStream()) {
|
|
||||||
return cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
|
if (path.basename(file.path).indexOf('_') === 0) {
|
||||||
}
|
return cb();
|
||||||
if (path.basename(file.path).indexOf('_') === 0) {
|
}
|
||||||
return cb();
|
|
||||||
}
|
if (!file.contents.length) {
|
||||||
if (!file.contents.length) {
|
file.path = replaceExtension(file.path, '.css'); // eslint-disable-line no-param-reassign
|
||||||
file.path = gutil.replaceExtension(file.path, '.css');
|
return cb(null, file);
|
||||||
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 || {});
|
// Generate Source Maps if plugin source-map present
|
||||||
opts.data = file.contents.toString();
|
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
|
// Build Source Maps!
|
||||||
if (path.extname(file.path) === '.sass') {
|
if (sassObj.map) {
|
||||||
opts.indentedSyntax = true;
|
// Transform map into JSON
|
||||||
}
|
sassMap = JSON.parse(sassObj.map.toString());
|
||||||
|
// Grab the stdout and transform it into stdin
|
||||||
// Ensure file's parent directory in the include path
|
sassMapFile = sassMap.file.replace(/^stdout$/, 'stdin');
|
||||||
if (opts.includePaths) {
|
// Grab the base file name that's being worked on
|
||||||
if (typeof opts.includePaths === 'string') {
|
sassFileSrc = file.relative;
|
||||||
opts.includePaths = [opts.includePaths];
|
// Grab the path portion of the file that's being worked on
|
||||||
}
|
sassFileSrcPath = path.dirname(sassFileSrc);
|
||||||
}
|
if (sassFileSrcPath) {
|
||||||
else {
|
// Prepend the path to all files in the sources array except the file that's being worked on
|
||||||
opts.includePaths = [];
|
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);
|
||||||
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;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Replace the map file with the original file name (but new extension)
|
|
||||||
sassMap.file = gutil.replaceExtension(sassFileSrc, '.css');
|
|
||||||
// Apply the map
|
|
||||||
applySourceMap(file, sassMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file.contents = sassObj.css;
|
// Remove 'stdin' from souces and replace with filenames!
|
||||||
file.path = gutil.replaceExtension(file.path, '.css');
|
sassMap.sources = sassMap.sources.filter(src => src !== 'stdin' && src);
|
||||||
|
|
||||||
cb(null, file);
|
// Replace the map file with the original file name (but new extension)
|
||||||
};
|
sassMap.file = replaceExtension(sassFileSrc, '.css');
|
||||||
|
// Apply the map
|
||||||
//////////////////////////////
|
applySourceMap(file, sassMap);
|
||||||
// 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 += gutil.colors.underline(relativePath) + '\n';
|
|
||||||
message += error.formatted;
|
|
||||||
|
|
||||||
error.messageFormatted = message;
|
|
||||||
error.messageOriginal = error.message;
|
|
||||||
error.message = gutil.colors.stripColor(message);
|
|
||||||
|
|
||||||
error.relativePath = relativePath;
|
|
||||||
|
|
||||||
return cb(new gutil.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);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
//////////////////////////////
|
|
||||||
// Sync Sass render
|
|
||||||
//////////////////////////////
|
|
||||||
try {
|
|
||||||
result = gulpSass.compiler.renderSync(opts);
|
|
||||||
|
|
||||||
filePush(result);
|
file.contents = sassObj.css; // eslint-disable-line no-param-reassign
|
||||||
}
|
file.path = replaceExtension(file.path, '.css'); // eslint-disable-line no-param-reassign
|
||||||
catch (error) {
|
|
||||||
|
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);
|
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
|
// Sync Sass render
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
gulpSass.sync = function sync(options) {
|
gulpSass.sync = options => gulpSass(options, true);
|
||||||
return gulpSass(options, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Log errors nicely
|
// Log errors nicely
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
gulpSass.logError = function logError(error) {
|
gulpSass.logError = (error) => {
|
||||||
var message = new gutil.PluginError('sass', error.messageFormatted).toString();
|
const message = new PluginError('sass', error.messageFormatted).toString();
|
||||||
process.stderr.write(message + '\n');
|
process.stderr.write(`${message}\n`);
|
||||||
this.emit('end');
|
this.emit('end');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
23
package.json
23
package.json
|
@ -3,6 +3,9 @@
|
||||||
"version": "3.2.1",
|
"version": "3.2.1",
|
||||||
"description": "Gulp plugin for sass",
|
"description": "Gulp plugin for sass",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "./node_modules/.bin/mocha test"
|
"test": "./node_modules/.bin/mocha test"
|
||||||
},
|
},
|
||||||
|
@ -21,22 +24,28 @@
|
||||||
"url": "https://github.com/dlmanning/gulp-sass/issues"
|
"url": "https://github.com/dlmanning/gulp-sass/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"gulp-util": "^3.0",
|
"chalk": "^2.3.0",
|
||||||
"lodash.clonedeep": "^4.3.2",
|
"lodash.clonedeep": "^4.3.2",
|
||||||
"node-sass": "^4.8.3",
|
"node-sass": "^4.8.3",
|
||||||
|
"plugin-error": "^1.0.1",
|
||||||
|
"replace-ext": "^1.0.0",
|
||||||
|
"strip-ansi": "^4.0.0",
|
||||||
"through2": "^2.0.0",
|
"through2": "^2.0.0",
|
||||||
"vinyl-sourcemaps-apply": "^0.2.0"
|
"vinyl-sourcemaps-apply": "^0.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer-core": "^5.2.1",
|
"autoprefixer": "^8.1.0",
|
||||||
"eslint": "^2.9.0",
|
"eslint": "^4.18.2",
|
||||||
|
"eslint-config-airbnb-base": "^12.1.0",
|
||||||
|
"eslint-plugin-import": "^2.9.0",
|
||||||
"globule": "^1.0.0",
|
"globule": "^1.0.0",
|
||||||
"gulp": "^3.8.11",
|
"gulp": "^3.8.11",
|
||||||
"gulp-postcss": "^5.1.10",
|
"gulp-postcss": "^7.0.1",
|
||||||
"gulp-sourcemaps": "^1.5.2",
|
"gulp-sourcemaps": "^2.6.4",
|
||||||
"gulp-tap": "^0.1.3",
|
"gulp-tap": "^0.1.3",
|
||||||
"mocha": "^2.2.1",
|
"mocha": "^5.0.4",
|
||||||
"rimraf": "^2.4.3",
|
"rimraf": "^2.4.3",
|
||||||
"should": "^8.3.1"
|
"should": "^13.2.1",
|
||||||
|
"vinyl": "^2.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
test/lint.js
37
test/lint.js
|
@ -1,16 +1,12 @@
|
||||||
'use strict';
|
const eslint = require('eslint');
|
||||||
|
const should = require('should');
|
||||||
|
|
||||||
var eslint = require('eslint');
|
describe('code style guide', () => {
|
||||||
var should = require('should');
|
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) {
|
if (report.errorCount > 0 || report.warningCount > 0) {
|
||||||
console.log(formatter(report.results));
|
console.log(formatter(report.results));
|
||||||
}
|
}
|
||||||
|
@ -20,8 +16,11 @@ describe('code style guide', function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test/main.js should follow our lint style guide', function(done) {
|
it('test/main.js should follow our lint style guide', (done) => {
|
||||||
report = cli.executeOnFiles(['test/main.js']);
|
const cli = new eslint.CLIEngine();
|
||||||
|
const formatter = cli.getFormatter();
|
||||||
|
const report = cli.executeOnFiles(['test/main.js']);
|
||||||
|
|
||||||
if (report.errorCount > 0 || report.warningCount > 0) {
|
if (report.errorCount > 0 || report.warningCount > 0) {
|
||||||
console.log(formatter(report.results));
|
console.log(formatter(report.results));
|
||||||
}
|
}
|
||||||
|
@ -31,13 +30,11 @@ describe('code style guide', function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test/lint.js should follow our lint style guide', function(done) {
|
it('test/lint.js should follow our lint style guide', (done) => {
|
||||||
cli = new eslint.CLIEngine({
|
const cli = new eslint.CLIEngine({ rules: { 'no-console': 0 } });
|
||||||
'rules': {
|
const formatter = cli.getFormatter();
|
||||||
'no-console': 0
|
const report = cli.executeOnFiles(['test/lint.js']);
|
||||||
}
|
|
||||||
});
|
|
||||||
report = cli.executeOnFiles(['test/lint.js']);
|
|
||||||
if (report.errorCount > 0 || report.warningCount > 0) {
|
if (report.errorCount > 0 || report.warningCount > 0) {
|
||||||
console.log(formatter(report.results));
|
console.log(formatter(report.results));
|
||||||
}
|
}
|
||||||
|
|
426
test/main.js
426
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');
|
const createVinyl = (filename, contents) => {
|
||||||
var gutil = require('gulp-util');
|
const base = path.join(__dirname, 'scss');
|
||||||
var path = require('path');
|
const filePath = path.join(base, filename);
|
||||||
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-core');
|
|
||||||
var tap = require('gulp-tap');
|
|
||||||
var globule = require('globule');
|
|
||||||
|
|
||||||
var createVinyl = function createVinyl(filename, contents) {
|
return new Vinyl({
|
||||||
var base = path.join(__dirname, 'scss');
|
cwd: __dirname,
|
||||||
var filePath = path.join(base, filename);
|
base,
|
||||||
|
path: filePath,
|
||||||
return new gutil.File({
|
contents: contents || fs.readFileSync(filePath),
|
||||||
'cwd': __dirname,
|
|
||||||
'base': base,
|
|
||||||
'path': filePath,
|
|
||||||
'contents': contents || fs.readFileSync(filePath)
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var normaliseEOL = function(str) {
|
const normaliseEOL = str => str.toString('utf8').replace(/\r\n/g, '\n');
|
||||||
if (typeof(str) === 'object') {
|
|
||||||
str = str.toString('utf8');
|
|
||||||
}
|
|
||||||
|
|
||||||
return str.replace(/\r\n/g, '\n');
|
describe('test helpers', () => {
|
||||||
}
|
it('should normalise EOL', (done) => {
|
||||||
|
|
||||||
describe('test helpers', function() {
|
|
||||||
it('should normalise EOL', function(done) {
|
|
||||||
should.equal(normaliseEOL('foo\r\nbar'), 'foo\nbar');
|
should.equal(normaliseEOL('foo\r\nbar'), 'foo\nbar');
|
||||||
should.equal(normaliseEOL('foo\nbar'), 'foo\nbar');
|
should.equal(normaliseEOL('foo\nbar'), 'foo\nbar');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('gulp-sass -- async compile', function() {
|
describe('gulp-sass -- async compile', () => {
|
||||||
it('should pass file when it isNull()', function(done) {
|
it('should pass file when it isNull()', (done) => {
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
var emptyFile = {
|
const emptyFile = {
|
||||||
'isNull': function () {
|
isNull: () => true,
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
stream.on('data', function(data) {
|
stream.on('data', (data) => {
|
||||||
data.should.equal(emptyFile);
|
data.should.equal(emptyFile);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(emptyFile);
|
stream.write(emptyFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit error when file isStream()', function (done) {
|
it('should emit error when file isStream()', (done) => {
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
var streamFile = {
|
const streamFile = {
|
||||||
'isNull': function () {
|
isNull: () => false,
|
||||||
return false;
|
isStream: () => true,
|
||||||
},
|
|
||||||
'isStream': function () {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
stream.on('error', function(err) {
|
stream.on('error', (err) => {
|
||||||
err.message.should.equal('Streaming not supported');
|
err.message.should.equal('Streaming not supported');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(streamFile);
|
stream.write(streamFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile an empty sass file', function(done) {
|
it('should compile an empty sass file', (done) => {
|
||||||
var sassFile = createVinyl('empty.scss');
|
const sassFile = createVinyl('empty.scss');
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
should.exist(cssFile.contents);
|
||||||
should.equal(path.basename(cssFile.path), 'empty.css');
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile a single sass file', function(done) {
|
it('should compile a single sass file', (done) => {
|
||||||
var sassFile = createVinyl('mixins.scss');
|
const sassFile = createVinyl('mixins.scss');
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile multiple sass files', function(done) {
|
it('should compile multiple sass files', (done) => {
|
||||||
var files = [
|
const files = [
|
||||||
createVinyl('mixins.scss'),
|
createVinyl('mixins.scss'),
|
||||||
createVinyl('variables.scss')
|
createVinyl('variables.scss'),
|
||||||
];
|
];
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
var mustSee = files.length;
|
let mustSee = files.length;
|
||||||
var expectedPath = path.join('expected', 'mixins.css');
|
let expectedPath = path.join('expected', 'mixins.css');
|
||||||
|
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
|
@ -123,41 +109,42 @@ describe('gulp-sass -- async compile', function() {
|
||||||
if (cssFile.path.indexOf('variables') !== -1) {
|
if (cssFile.path.indexOf('variables') !== -1) {
|
||||||
expectedPath = path.join('expected', 'variables.css');
|
expectedPath = path.join('expected', 'variables.css');
|
||||||
}
|
}
|
||||||
String(normaliseEOL(cssFile.contents)).should.equal(
|
|
||||||
normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8'))
|
const actual = fs.readFileSync(path.join(__dirname, expectedPath), 'utf8');
|
||||||
);
|
String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual));
|
||||||
mustSee--;
|
|
||||||
|
mustSee -= 1;
|
||||||
if (mustSee <= 0) {
|
if (mustSee <= 0) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
files.forEach(function (file) {
|
files.forEach((file) => {
|
||||||
stream.write(file);
|
stream.write(file);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile files with partials in another folder', function(done) {
|
it('should compile files with partials in another folder', (done) => {
|
||||||
var sassFile = createVinyl('inheritance.scss');
|
const sassFile = createVinyl('inheritance.scss');
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle sass errors', function(done) {
|
it('should handle sass errors', (done) => {
|
||||||
var errorFile = createVinyl('error.scss');
|
const errorFile = createVinyl('error.scss');
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
|
|
||||||
stream.on('error', function(err) {
|
stream.on('error', (err) => {
|
||||||
// Error must include message body
|
// Error must include message body
|
||||||
err.message.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1);
|
err.message.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1);
|
||||||
// Error must include file error occurs in
|
// Error must include file error occurs in
|
||||||
|
@ -171,11 +158,11 @@ describe('gulp-sass -- async compile', function() {
|
||||||
stream.write(errorFile);
|
stream.write(errorFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should preserve the original sass error message', function(done) {
|
it('should preserve the original sass error message', (done) => {
|
||||||
var errorFile = createVinyl('error.scss');
|
const errorFile = createVinyl('error.scss');
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
|
|
||||||
stream.on('error', function(err) {
|
stream.on('error', (err) => {
|
||||||
// Error must include original error message
|
// Error must include original error message
|
||||||
err.messageOriginal.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1);
|
err.messageOriginal.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1);
|
||||||
// Error must not format or change the original error message
|
// Error must not format or change the original error message
|
||||||
|
@ -185,60 +172,48 @@ describe('gulp-sass -- async compile', function() {
|
||||||
stream.write(errorFile);
|
stream.write(errorFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile a single sass file if the file name has been changed in the stream', function(done) {
|
it('should compile a single sass file if the file name has been changed in the stream', (done) => {
|
||||||
var sassFile = createVinyl('mixins.scss');
|
const sassFile = createVinyl('mixins.scss');
|
||||||
var stream;
|
|
||||||
|
|
||||||
// Transform file name
|
// Transform file name
|
||||||
sassFile.path = path.join(path.join(__dirname, 'scss'), 'mixin--changed.scss');
|
sassFile.path = path.join(path.join(__dirname, 'scss'), 'mixin--changed.scss');
|
||||||
|
|
||||||
stream = sass();
|
const stream = sass();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
cssFile.path.split(path.sep).pop().should.equal('mixin--changed.css');
|
cssFile.path.split(path.sep).pop().should.equal('mixin--changed.css');
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should preserve changes made in-stream to a Sass file', function(done) {
|
it('should preserve changes made in-stream to a Sass file', (done) => {
|
||||||
var sassFile = createVinyl('mixins.scss');
|
const sassFile = createVinyl('mixins.scss');
|
||||||
var stream;
|
|
||||||
|
|
||||||
// Transform file name
|
// Transform file name
|
||||||
sassFile.contents = new Buffer('/* Added Dynamically */' + sassFile.contents.toString());
|
sassFile.contents = Buffer.from(`/* Added Dynamically */${sassFile.contents.toString()}`);
|
||||||
|
|
||||||
stream = sass();
|
const stream = sass();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with gulp-sourcemaps', function(done) {
|
it('should work with gulp-sourcemaps', (done) => {
|
||||||
var sassFile = createVinyl('inheritance.scss');
|
const sassFile = createVinyl('inheritance.scss');
|
||||||
|
|
||||||
// Expected sources are relative to file.base
|
|
||||||
var expectedSources = [
|
|
||||||
'inheritance.scss',
|
|
||||||
'includes/_cats.scss',
|
|
||||||
'includes/_dogs.sass',
|
|
||||||
];
|
|
||||||
|
|
||||||
var stream;
|
|
||||||
|
|
||||||
sassFile.sourceMap = '{' +
|
sassFile.sourceMap = '{' +
|
||||||
'"version": 3,' +
|
'"version": 3,' +
|
||||||
|
@ -249,8 +224,15 @@ describe('gulp-sass -- async compile', function() {
|
||||||
'"sourcesContent": [ "@import ../inheritance;" ]' +
|
'"sourcesContent": [ "@import ../inheritance;" ]' +
|
||||||
'}';
|
'}';
|
||||||
|
|
||||||
stream = sass();
|
// Expected sources are relative to file.base
|
||||||
stream.on('data', function(cssFile) {
|
const expectedSources = [
|
||||||
|
'inheritance.scss',
|
||||||
|
'includes/_cats.scss',
|
||||||
|
'includes/_dogs.sass',
|
||||||
|
];
|
||||||
|
|
||||||
|
const stream = sass();
|
||||||
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile.sourceMap);
|
should.exist(cssFile.sourceMap);
|
||||||
cssFile.sourceMap.sources.should.eql(expectedSources);
|
cssFile.sourceMap.sources.should.eql(expectedSources);
|
||||||
done();
|
done();
|
||||||
|
@ -258,32 +240,32 @@ describe('gulp-sass -- async compile', function() {
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile a single indented sass file', function(done) {
|
it('should compile a single indented sass file', (done) => {
|
||||||
var sassFile = createVinyl('indent.sass');
|
const sassFile = createVinyl('indent.sass');
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should parse files in sass and scss', function(done) {
|
it('should parse files in sass and scss', (done) => {
|
||||||
var files = [
|
const files = [
|
||||||
createVinyl('mixins.scss'),
|
createVinyl('mixins.scss'),
|
||||||
createVinyl('indent.sass')
|
createVinyl('indent.sass'),
|
||||||
];
|
];
|
||||||
var stream = sass();
|
const stream = sass();
|
||||||
var mustSee = files.length;
|
let mustSee = files.length;
|
||||||
var expectedPath = path.join('expected', 'mixins.css');
|
let expectedPath = path.join('expected', 'mixins.css');
|
||||||
|
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
|
@ -291,125 +273,123 @@ describe('gulp-sass -- async compile', function() {
|
||||||
if (cssFile.path.indexOf('indent') !== -1) {
|
if (cssFile.path.indexOf('indent') !== -1) {
|
||||||
expectedPath = path.join('expected', 'indent.css');
|
expectedPath = path.join('expected', 'indent.css');
|
||||||
}
|
}
|
||||||
String(normaliseEOL(cssFile.contents)).should.equal(
|
|
||||||
normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8'))
|
const actual = fs.readFileSync(path.join(__dirname, expectedPath), 'utf8');
|
||||||
);
|
String(normaliseEOL(cssFile.contents)).should.equal(normaliseEOL(actual));
|
||||||
mustSee--;
|
|
||||||
|
mustSee -= 1;
|
||||||
if (mustSee <= 0) {
|
if (mustSee <= 0) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
files.forEach(function (file) {
|
files.forEach((file) => {
|
||||||
stream.write(file);
|
stream.write(file);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('gulp-sass -- sync compile', function() {
|
describe('gulp-sass -- sync compile', () => {
|
||||||
beforeEach(function(done) {
|
beforeEach((done) => {
|
||||||
rimraf(path.join(__dirname, 'results'), done);
|
rimraf(path.join(__dirname, 'results'), done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass file when it isNull()', function(done) {
|
it('should pass file when it isNull()', (done) => {
|
||||||
var stream = sass.sync();
|
const stream = sass.sync();
|
||||||
var emptyFile = {
|
const emptyFile = {
|
||||||
'isNull': function () {
|
isNull: () => true,
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
stream.on('data', function(data) {
|
stream.on('data', (data) => {
|
||||||
data.should.equal(emptyFile);
|
data.should.equal(emptyFile);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(emptyFile);
|
stream.write(emptyFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit error when file isStream()', function (done) {
|
it('should emit error when file isStream()', (done) => {
|
||||||
var stream = sass.sync();
|
const stream = sass.sync();
|
||||||
var streamFile = {
|
const streamFile = {
|
||||||
'isNull': function () {
|
isNull: () => false,
|
||||||
return false;
|
isStream: () => true,
|
||||||
},
|
|
||||||
'isStream': function () {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
stream.on('error', function(err) {
|
stream.on('error', (err) => {
|
||||||
err.message.should.equal('Streaming not supported');
|
err.message.should.equal('Streaming not supported');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(streamFile);
|
stream.write(streamFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile a single sass file', function(done) {
|
it('should compile a single sass file', (done) => {
|
||||||
var sassFile = createVinyl('mixins.scss');
|
const sassFile = createVinyl('mixins.scss');
|
||||||
var stream = sass.sync();
|
const stream = sass.sync();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile multiple sass files', function(done) {
|
it('should compile multiple sass files', (done) => {
|
||||||
var files = [
|
const files = [
|
||||||
createVinyl('mixins.scss'),
|
createVinyl('mixins.scss'),
|
||||||
createVinyl('variables.scss')
|
createVinyl('variables.scss'),
|
||||||
];
|
];
|
||||||
var stream = sass.sync();
|
const stream = sass.sync();
|
||||||
var mustSee = files.length;
|
let mustSee = files.length;
|
||||||
var expectedPath = path.join('expected', 'mixins.css');
|
let expectedPath = path.join('expected', 'mixins.css');
|
||||||
|
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
should.exist(cssFile.contents);
|
||||||
|
|
||||||
if (cssFile.path.indexOf('variables') !== -1) {
|
if (cssFile.path.indexOf('variables') !== -1) {
|
||||||
expectedPath = path.join('expected', 'variables.css');
|
expectedPath = path.join('expected', 'variables.css');
|
||||||
}
|
}
|
||||||
String(normaliseEOL(cssFile.contents)).should.equal(
|
|
||||||
normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8'))
|
const actual = normaliseEOL(fs.readFileSync(path.join(__dirname, expectedPath), 'utf8'));
|
||||||
);
|
String(normaliseEOL(cssFile.contents)).should.equal(actual);
|
||||||
mustSee--;
|
|
||||||
|
mustSee -= 1;
|
||||||
if (mustSee <= 0) {
|
if (mustSee <= 0) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
files.forEach(function (file) {
|
files.forEach((file) => {
|
||||||
stream.write(file);
|
stream.write(file);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should compile files with partials in another folder', function(done) {
|
it('should compile files with partials in another folder', (done) => {
|
||||||
var sassFile = createVinyl('inheritance.scss');
|
const sassFile = createVinyl('inheritance.scss');
|
||||||
var stream = sass.sync();
|
const stream = sass.sync();
|
||||||
stream.on('data', function(cssFile) {
|
|
||||||
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile);
|
should.exist(cssFile);
|
||||||
should.exist(cssFile.path);
|
should.exist(cssFile.path);
|
||||||
should.exist(cssFile.relative);
|
should.exist(cssFile.relative);
|
||||||
should.exist(cssFile.contents);
|
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();
|
done();
|
||||||
});
|
});
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle sass errors', function(done) {
|
it('should handle sass errors', (done) => {
|
||||||
var errorFile = createVinyl('error.scss');
|
const errorFile = createVinyl('error.scss');
|
||||||
var stream = sass.sync();
|
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.message.indexOf('property "font" must be followed by a \':\'').should.not.equal(-1);
|
||||||
err.relativePath.should.equal(path.join('test', 'scss', 'error.scss'));
|
err.relativePath.should.equal(path.join('test', 'scss', 'error.scss'));
|
||||||
done();
|
done();
|
||||||
|
@ -417,18 +397,16 @@ describe('gulp-sass -- sync compile', function() {
|
||||||
stream.write(errorFile);
|
stream.write(errorFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with gulp-sourcemaps', function(done) {
|
it('should work with gulp-sourcemaps', (done) => {
|
||||||
var sassFile = createVinyl('inheritance.scss');
|
const sassFile = createVinyl('inheritance.scss');
|
||||||
|
|
||||||
// Expected sources are relative to file.base
|
// Expected sources are relative to file.base
|
||||||
var expectedSources = [
|
const expectedSources = [
|
||||||
'inheritance.scss',
|
'inheritance.scss',
|
||||||
'includes/_cats.scss',
|
'includes/_cats.scss',
|
||||||
'includes/_dogs.sass',
|
'includes/_dogs.sass',
|
||||||
];
|
];
|
||||||
|
|
||||||
var stream;
|
|
||||||
|
|
||||||
sassFile.sourceMap = '{' +
|
sassFile.sourceMap = '{' +
|
||||||
'"version": 3,' +
|
'"version": 3,' +
|
||||||
'"file": "scss/subdir/multilevelimport.scss",' +
|
'"file": "scss/subdir/multilevelimport.scss",' +
|
||||||
|
@ -438,8 +416,8 @@ describe('gulp-sass -- sync compile', function() {
|
||||||
'"sourcesContent": [ "@import ../inheritance;" ]' +
|
'"sourcesContent": [ "@import ../inheritance;" ]' +
|
||||||
'}';
|
'}';
|
||||||
|
|
||||||
stream = sass.sync();
|
const stream = sass.sync();
|
||||||
stream.on('data', function(cssFile) {
|
stream.on('data', (cssFile) => {
|
||||||
should.exist(cssFile.sourceMap);
|
should.exist(cssFile.sourceMap);
|
||||||
cssFile.sourceMap.sources.should.eql(expectedSources);
|
cssFile.sourceMap.sources.should.eql(expectedSources);
|
||||||
done();
|
done();
|
||||||
|
@ -447,14 +425,14 @@ describe('gulp-sass -- sync compile', function() {
|
||||||
stream.write(sassFile);
|
stream.write(sassFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with gulp-sourcemaps and autoprefixer', function(done) {
|
it('should work with gulp-sourcemaps and autoprefixer', (done) => {
|
||||||
var expectedSourcesBefore = [
|
const expectedSourcesBefore = [
|
||||||
'inheritance.scss',
|
'inheritance.scss',
|
||||||
'includes/_cats.scss',
|
'includes/_cats.scss',
|
||||||
'includes/_dogs.sass',
|
'includes/_dogs.sass',
|
||||||
];
|
];
|
||||||
|
|
||||||
var expectedSourcesAfter = [
|
const expectedSourcesAfter = [
|
||||||
'includes/_cats.scss',
|
'includes/_cats.scss',
|
||||||
'includes/_dogs.sass',
|
'includes/_dogs.sass',
|
||||||
'inheritance.scss',
|
'inheritance.scss',
|
||||||
|
@ -463,80 +441,78 @@ describe('gulp-sass -- sync compile', function() {
|
||||||
gulp.src(path.join(__dirname, 'scss', 'inheritance.scss'))
|
gulp.src(path.join(__dirname, 'scss', 'inheritance.scss'))
|
||||||
.pipe(sourcemaps.init())
|
.pipe(sourcemaps.init())
|
||||||
.pipe(sass.sync())
|
.pipe(sass.sync())
|
||||||
.pipe(tap(function(file) {
|
.pipe(tap((file) => {
|
||||||
should.exist(file.sourceMap);
|
should.exist(file.sourceMap);
|
||||||
file.sourceMap.sources.should.eql(expectedSourcesBefore);
|
file.sourceMap.sources.should.eql(expectedSourcesBefore);
|
||||||
}))
|
}))
|
||||||
.pipe(postcss([autoprefixer()]))
|
.pipe(postcss([autoprefixer()]))
|
||||||
.pipe(sourcemaps.write())
|
.pipe(sourcemaps.write())
|
||||||
.pipe(gulp.dest(path.join(__dirname, 'results')))
|
.pipe(gulp.dest(path.join(__dirname, 'results')))
|
||||||
.pipe(tap(function(file) {
|
.pipe(tap((file) => {
|
||||||
should.exist(file.sourceMap);
|
should.exist(file.sourceMap);
|
||||||
file.sourceMap.sources.should.eql(expectedSourcesAfter);
|
file.sourceMap.sources.should.eql(expectedSourcesAfter);
|
||||||
}))
|
}))
|
||||||
.on('end', done);
|
.on('end', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with gulp-sourcemaps and a globbed source', function(done) {
|
it('should work with gulp-sourcemaps and a globbed source', (done) => {
|
||||||
var files, filesContent, actualContent, expectedContent, globPath;
|
const globPath = path.join(__dirname, 'scss', 'globbed');
|
||||||
globPath = path.join(__dirname, 'scss', 'globbed');
|
const files = globule.find(path.join(__dirname, 'scss', 'globbed', '**', '*.scss'));
|
||||||
files = globule.find(path.join(__dirname, 'scss', 'globbed', '**', '*.scss'));
|
const filesContent = {};
|
||||||
filesContent = {};
|
|
||||||
|
|
||||||
files.forEach(function(file) {
|
files.forEach((file) => {
|
||||||
var source = path.normalize(path.relative(globPath, file));
|
const source = path.normalize(path.relative(globPath, file));
|
||||||
filesContent[source] = fs.readFileSync(file, 'utf8');
|
filesContent[source] = fs.readFileSync(file, 'utf8');
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.src(path.join(__dirname, 'scss', 'globbed', '**', '*.scss'))
|
gulp.src(path.join(__dirname, 'scss', 'globbed', '**', '*.scss'))
|
||||||
.pipe(sourcemaps.init())
|
.pipe(sourcemaps.init())
|
||||||
.pipe(sass.sync())
|
.pipe(sass.sync())
|
||||||
.pipe(tap(function(file) {
|
.pipe(tap((file) => {
|
||||||
should.exist(file.sourceMap);
|
should.exist(file.sourceMap);
|
||||||
actualContent = normaliseEOL(file.sourceMap.sourcesContent[0]);
|
const actual = normaliseEOL(file.sourceMap.sourcesContent[0]);
|
||||||
expectedContent = normaliseEOL(filesContent[path.normalize(file.sourceMap.sources[0])]);
|
const expected = normaliseEOL(filesContent[path.normalize(file.sourceMap.sources[0])]);
|
||||||
actualContent.should.eql(expectedContent);
|
actual.should.eql(expected);
|
||||||
}))
|
}))
|
||||||
.on('end', done);
|
.on('end', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with gulp-sourcemaps and autoprefixer with different file.base', function(done) {
|
it('should work with gulp-sourcemaps and autoprefixer with different file.base', (done) => {
|
||||||
var expectedSourcesBefore = [
|
const expectedSourcesBefore = [
|
||||||
'scss/inheritance.scss',
|
'scss/inheritance.scss',
|
||||||
'scss/includes/_cats.scss',
|
'scss/includes/_cats.scss',
|
||||||
'scss/includes/_dogs.sass'
|
'scss/includes/_dogs.sass',
|
||||||
];
|
];
|
||||||
|
|
||||||
var expectedSourcesAfter = [
|
const expectedSourcesAfter = [
|
||||||
'scss/includes/_cats.scss',
|
'scss/includes/_cats.scss',
|
||||||
'scss/includes/_dogs.sass',
|
'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(sourcemaps.init())
|
||||||
.pipe(sass.sync())
|
.pipe(sass.sync())
|
||||||
.pipe(tap(function(file) {
|
.pipe(tap((file) => {
|
||||||
should.exist(file.sourceMap);
|
should.exist(file.sourceMap);
|
||||||
file.sourceMap.sources.should.eql(expectedSourcesBefore);
|
file.sourceMap.sources.should.eql(expectedSourcesBefore);
|
||||||
}))
|
}))
|
||||||
.pipe(postcss([autoprefixer()]))
|
.pipe(postcss([autoprefixer()]))
|
||||||
.pipe(tap(function(file) {
|
.pipe(tap((file) => {
|
||||||
should.exist(file.sourceMap);
|
should.exist(file.sourceMap);
|
||||||
file.sourceMap.sources.should.eql(expectedSourcesAfter);
|
file.sourceMap.sources.should.eql(expectedSourcesAfter);
|
||||||
}))
|
}))
|
||||||
.on('end', done);
|
.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'))
|
gulp.src(path.join(__dirname, 'scss', 'empty.scss'))
|
||||||
.pipe(sass.sync())
|
.pipe(sass.sync())
|
||||||
.pipe(gulp.dest(path.join(__dirname, 'results')))
|
.pipe(gulp.dest(path.join(__dirname, 'results')))
|
||||||
.pipe(tap(function() {
|
.pipe(tap(() => {
|
||||||
try {
|
try {
|
||||||
fs.statSync(path.join(__dirname, 'results', 'empty.css'));
|
fs.statSync(path.join(__dirname, 'results', 'empty.css'));
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
|
||||||
should.fail(false, true, 'Empty file was produced');
|
should.fail(false, true, 'Empty file was produced');
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
Loading…
Reference in a new issue