Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

lesshint

Package Overview
Dependencies
Maintainers
2
Versions
91
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lesshint - npm Package Compare versions

Comparing version 1.5.2 to 2.0.0-rc

lib/reporters/default.js

1

.eslintrc.json
{
"extends": "eslint:recommended",
"env": {
"es6": true,
"mocha": true,

@@ -5,0 +6,0 @@ "node": true

# Changelog
## 2.0.0-rc1 (2016-05-16)
* Completely new parser back-end, using PostCSS. Please report any issues! ([1894408](https://github.com/lesshint/lesshint/commit/18944083bbd69dc0f3d607f24617732a15093e2e))
* Removed support for old reporter style. ([49a2dba](https://github.com/lesshint/lesshint/commit/49a2dbaede9dd2e73fc035f60a80d09bdbaf25f6))
* Added a `Lesshint.getReporter()` method for loading of reporters using `lesshint`'s logic. ([6fc0041](https://github.com/lesshint/lesshint/commit/6fc0041aa42c8cfac9aadb0d671e88cf37d153b5))
* Fixed an issue where paths would sometimes include double slashes. ([0a197db](https://github.com/lesshint/lesshint/commit/0a197dbaac095b281d5084686bdd87d024cdb151))
## 1.5.2 (2016-03-31)

@@ -3,0 +9,0 @@ * Changed `gonzales-pe` full URL to GitHub pattern. ([e83e665](https://github.com/lesshint/lesshint/commit/e83e665f36e8beba0976b9ee32ad478067a117e5))

2

gulpfile.js

@@ -22,3 +22,3 @@ var gulp = require('gulp');

return gulp.src(['./test/specs/**/*.js'])
return gulp.src(['./test/specs/**/*.js', '!./test/specs/util.js'])
.pipe(mocha())

@@ -25,0 +25,0 @@ .pipe(istanbul.writeReports())

@@ -5,3 +5,2 @@ 'use strict';

var Lesshint = require('./lesshint');
var path = require('path');
var exit = require('exit');

@@ -19,36 +18,2 @@ var Vow = require('vow');

var getReporter = function (reporter) {
var reporterPath;
// stylish is the default
reporter = reporter || 'stylish';
// Check our core reporters first
try {
reporterPath = path.resolve(__dirname, './reporters/' + reporter + '.js');
return require(reporterPath);
} catch (e) {
// Empty
}
// Try to find it somewhere else
try {
reporterPath = path.resolve(process.cwd(), reporter);
return require(reporterPath);
} catch (e) {
// Empty
}
// Try to load it as a module
try {
return require(reporter);
} catch (e) {
// Empty
}
return false;
};
module.exports = function (program) {

@@ -98,11 +63,6 @@ var lesshint = new Lesshint();

reporter = getReporter(program.reporter);
reporter = lesshint.getReporter(program.reporter);
if (reporter) {
if (reporter.report) {
reporter.report(results);
} else {
console.warn('Reporters should expose a report() method. The old usage is deprecated and will be removed in 2.0.');
reporter(results);
}
reporter.report(results);
} else {

@@ -109,0 +69,0 @@ console.error('Could not find reporter "%s".', program.reporter);

@@ -91,2 +91,3 @@ {

],
"invalid": [],
"properties": {}

@@ -105,3 +106,5 @@ },

"disallowUppercase": true,
"disallowUnderscore": true
"disallowUnderscore": true,
"disallowDash": false,
"exclude": []
},

@@ -108,0 +111,0 @@

'use strict';
module.exports.ensureObject = function (obj) {
return obj || {};
};
module.exports.isAbsoluteURL = function (str) {
return /^(?:\w+:)?\/\//.test(str);
};

@@ -18,3 +18,3 @@ 'use strict';

files = files.map(function (file) {
var fullPath = checkPath + '/' + file;
var fullPath = path.join(checkPath, file);

@@ -63,39 +63,24 @@ return fs.stat(fullPath).then(function (stats) {

Lesshint.prototype.checkString = function (input, checkPath) {
var lineNo = 0;
var matches;
var result;
try {
checkPath = checkPath || '';
result = linter.lint(input, checkPath, this.config);
} catch (e) {
if (e.name !== 'Parsing error') {
if (e.name !== 'CssSyntaxError') {
/**
* Unkown error, i.e. not thrown by gonzales-pe.
* Rethrow and let someone else handle it.
*/
* Unkown error, i.e. not thrown by PostCSS.
* Reject and let someone else handle it.
*/
throw e;
}
matches = (e.message || e).match(/\#(\d+)$/);
/**
* lineNo should never be 0, but in the event that gonzales-pe
* throws a different message, let's account for it. I couldn't
* find any instance that this would happen.
*/
if (matches && matches.length > 1) {
lineNo = parseInt(matches[1]);
}
// We just emit parse errors as regular errors
result = [{
/**
* Errors from gonzales-pe only return line number at the moment,
* so we can safely assume column 1, as the entire line is affected.
*/
column: 1,
column: e.column,
file: path.basename(checkPath),
fullPath: checkPath,
line: lineNo,
line: e.line,
linter: 'parse error',
message: e.message || e,
message: e.reason,
severity: linter.resultSeverity.error

@@ -137,2 +122,31 @@ }];

Lesshint.prototype.getReporter = function (reporter) {
var reporterPath;
// Nothing defined, just fall back to our simple default
if (!reporter) {
reporterPath = path.resolve(__dirname, './reporters/default');
return require(reporterPath);
}
// Try to find it somewhere on disk
try {
reporterPath = path.resolve(process.cwd(), reporter);
return require(reporterPath);
} catch (e) {
// Empty
}
// Try to load it as a module
try {
return require(reporter);
} catch (e) {
// Empty
}
return false;
};
module.exports = Lesshint;
'use strict';
var gonzales = require('gonzales-pe');
var postcssLess = require('postcss-less');
var sortBy = require('lodash.sortby');
var merge = require('lodash.merge');
var helpers = require('./helpers');
var postcss = require('postcss');
var path = require('path');

@@ -46,3 +46,3 @@

var parseRules = function (node) {
var rules = node.content.match(/^\s*lesshint\s+(.*)/);
var rules = node.text.match(/^\s*lesshint\s+(.*)/);

@@ -77,5 +77,10 @@ if (!rules) {

node = helpers.ensureObject(node);
start = helpers.ensureObject(node.start);
node = node || {};
if (node.type !== 'comment') {
return {};
}
start = node.source.start;
// Not the first thing in the file, bail

@@ -89,8 +94,3 @@ if (start.line !== 1 && start.column !== 1) {

exports.resultSeverity = {
error: 'error',
warning: 'warning'
};
exports.lint = function (input, fullPath, config) {
var runChecks = function (ast, fullPath, lines, config) {
var filename = path.basename(fullPath);

@@ -100,10 +100,3 @@ var lineOptions = [];

var inlineOptions;
var firstComment;
var lines;
var ast;
input = input.replace(/\r\n|\r|\n/g, '\n'); // Normalize line endings. See #40
lines = input.split('\n');
ast = this.parseAST(input);
// Freeze the AST so linters won't accidentally change it

@@ -113,8 +106,7 @@ Object.freeze(ast);

// Fetch inline options and merge it with whatever passed
firstComment = ast.first('multilineComment') || ast.first('singlelineComment');
inlineOptions = getInlineOptions(firstComment);
inlineOptions = getInlineOptions(ast.root.first);
config = merge(config, inlineOptions);
// Fetch all single line options before we start the actual linting
ast.traverseByTypes(['multilineComment', 'singlelineComment'], function (node) {
ast.root.walkComments(function (node) {
var option = parseRules(node);

@@ -124,3 +116,3 @@ var key = Object.keys(option)[0];

option[key] = merge(option[key], {
line: node.start.line
line: node.source.start.line
});

@@ -131,3 +123,3 @@

ast.traverse(function (node) {
ast.root.walk(function (node) {
linters.forEach(function (linter) {

@@ -148,3 +140,2 @@ var options = config[linter.name];

lint = linter.lint.call(linter, options, node);
if (lint) {

@@ -156,3 +147,3 @@ if (!Array.isArray(lint)) {

lint.forEach(function (piece) {
var line = piece.line || node.start.line;
var line = piece.line || node.source.start.line;
var shouldIgnore = lineOptions.some(function (lineOption) {

@@ -178,3 +169,3 @@ lineOption = lineOption[linter.name];

results.push(merge({
column: node.start.column,
column: node.source.start.column,
file: filename,

@@ -193,12 +184,38 @@ fullPath: fullPath,

results = sortBy(results, 'column');
results = sortBy(results, 'line');
return results;
};
exports.parseAST = function (input) {
return gonzales.parse(input, {
syntax: 'less'
exports.resultSeverity = {
error: 'error',
warning: 'warning'
};
exports.lint = function (input, fullPath, config) {
var results;
var parser;
var lines;
var ast;
input = input.replace(/\r\n|\r|\n/g, '\n'); // Normalize line endings. See #40
lines = input.split('\n');
try {
parser = this.getParser(input);
ast = parser.root.toResult();
results = runChecks(ast, fullPath, lines, config);
results = sortBy(results, 'column');
results = sortBy(results, 'line');
return results;
} catch (e) {
// Just rethrow the exception and let someone else handle it
throw e;
}
};
exports.getParser = function (input) {
return postcss([]).process(input, {
syntax: postcssLess
});
};
'use strict';
var parser = require('postcss-selector-parser');
module.exports = {
name: 'attributeQuotes',
nodeTypes: ['attributeValue'],
nodeTypes: ['rule'],
message: 'Attribute selectors should use quotes.',
lint: function attributeQuotesLinter (config, node) {
var value = node.first('string');
var results = [];
var self = this;
if (!value) {
value = node.last('ident');
if (!node.selector) {
return;
}
return [{
column: value.start.column,
line: value.start.line,
message: this.message
}];
parser(function (selectors) {
selectors.walkAttributes(function (selector) {
var column;
if (selector.operator && !selector.quoted) {
column = selector.source.start.column + selector.attribute.length
+ selector.operator.length + '['.length;
results.push({
column: column,
line: selector.source.start.line,
message: self.message
});
}
});
}).process(node.selector);
if (results.length) {
return results;
}
}
};

@@ -5,3 +5,3 @@ 'use strict';

name: 'borderZero',
nodeTypes: ['declaration'],
nodeTypes: ['decl'],
message: {

@@ -14,20 +14,12 @@ none: 'Border properties should use "none" instead of 0.',

var properties = ['border', 'border-bottom', 'border-left', 'border-right', 'border-top'];
var property;
var content;
var message;
var value;
property = node.first('property').first().content;
// Not a border* property, bail
if (properties.indexOf(property) === -1) {
return null;
if (properties.indexOf(node.prop) === -1) {
return;
}
value = node.first('value');
content = value.first().content;
// Bail if it's an actual border
if (content !== '0' && content !== 'none') {
return null;
if (node.value !== '0' && node.value !== 'none') {
return;
}

@@ -37,3 +29,3 @@

case 'none':
if (content === '0') {
if (node.value === '0') {
message = this.message.none;

@@ -44,3 +36,3 @@ }

case 'zero':
if (content === 'none') {
if (node.value === 'none') {
message = this.message.zero;

@@ -58,4 +50,4 @@ }

return [{
column: value.start.column,
line: value.start.line,
column: node.source.start.column + node.prop.length + node.raws.between.length,
line: node.source.start.line,
message: message

@@ -62,0 +54,0 @@ }];

@@ -5,3 +5,3 @@ 'use strict';

name: 'comment',
nodeTypes: ['multilineComment'],
nodeTypes: ['comment'],
message: "There shouldn't be any multi-line comments.",

@@ -12,2 +12,6 @@

if (node.inline) {
return;
}
if (config.allowed) {

@@ -17,3 +21,3 @@ regexp = new RegExp(config.allowed);

if (!regexp || (regexp && !regexp.test(node.content))) {
if (!regexp || (regexp && !regexp.test(node.text))) {
return [{

@@ -20,0 +24,0 @@ message: this.message

'use strict';
var parser = require('postcss-values-parser');
var util = require('util');

@@ -7,15 +8,20 @@

name: 'decimalZero',
nodeTypes: ['declaration'],
nodeTypes: ['decl'],
message: '%s should be written %s %s zero.',
lint: function decimalZeroLinter (config, node) {
var number;
var result = [];
var ast = parser(node.value).parse();
var results = [];
var self = this;
node.traverseByType('number', function (element) {
ast.walk(function (child) {
var output;
var number;
number = element.content;
if (child.type !== 'number') {
return;
}
number = child.value;
/*

@@ -58,20 +64,18 @@ * Bail if:

default:
throw new Error(
'Invalid setting value for decimalZero: ' + config.style
);
throw new Error('Invalid setting value for decimalZero: ' + config.style);
}
if (output.type) {
result.push({
column: element.start.column,
line: element.start.line,
results.push({
column: node.prop.length + node.raws.between.length + child.source.start.column,
line: child.source.start.line,
message: util.format(self.message, number, output.inclusion, output.type)
});
}
});//traverseByType('number')
});
if (result.length > 0) {
return result;
if (results.length > 0) {
return results;
}
}
};

@@ -5,33 +5,16 @@ 'use strict';

/*Checks how many nested classes have every node*/
var countLevels = function (childNode, i, total) {
var block = childNode.first('block') || {};
total += 1;
block.eachFor('ruleset', function (subchildNode, i) {
total = countLevels(subchildNode, i, total);
});
return total;
};
module.exports = {
name: 'depthLevel',
nodeTypes: ['block'],
nodeTypes: ['rule'],
message: "There shouldn't be more than '%s' levels deep from the style's parent, check the children's depth.",
lint: function deepLevelLinter (config, node) {
var depth = config.depth || 3;
var error = false;
var depth = config.depth;
var levels = 1;
node.eachFor('ruleset', function (childNode, i) {
var levelsTotal = 1;
levelsTotal = countLevels(childNode, i, levelsTotal);
if (levelsTotal > depth) {
error = true;
return;
}
node.walkRules(function () {
levels++;
});
if (error) {
if (levels > depth) {
return [{

@@ -38,0 +21,0 @@ message: util.format(this.message, depth)

'use strict';
var helpers = require('../helpers');
var util = require('util');

@@ -8,3 +7,3 @@

name: 'duplicateProperty',
nodeTypes: ['block'],
nodeTypes: ['rule'],
message: 'Duplicate property: "%s".',

@@ -17,17 +16,22 @@

node.forEach('declaration', function (declaration) {
var property = declaration.first('property');
node.walkDecls(function (decl) {
// walkDecls will walk even those Declaration nodes that are nested
// under other nested Rule nodes
if (decl.parent !== node) {
return true;
}
property = helpers.ensureObject(property.first('ident'));
if (property.content && (properties.indexOf(property.content) !== -1)) {
if (properties.indexOf(decl.prop) >= 0) {
results.push({
message: util.format(self.message, property.content),
column: property.start.column,
line: property.start.line
message: util.format(self.message, decl.prop),
column: decl.source.start.column,
line: decl.source.start.line
});
}
if (config.exclude.indexOf(property.content) === -1) {
properties.push(property.content);
// we let this happen regardless of if the array already
// contains the property name, for debugging purposes. it doesn't
// hurt anything.
if (!config.exclude || config.exclude.indexOf(decl.prop) < 0) {
properties.push(decl.prop);
}

@@ -34,0 +38,0 @@ });

@@ -5,11 +5,29 @@ 'use strict';

name: 'emptyRule',
nodeTypes: ['ruleset'],
nodeTypes: ['rule'],
message: "There shouldn't be any empty rules present.",
lint: function emptyRuleLinter (config, node) {
var block = node.first('block') || {};
var hasDeclarations = false;
block.content = block.content || [];
if (node.ruleWithoutBody) {
return;
}
if (!block.content.length || (block.content.length === 1 && block.content[0].type === 'space')) {
/**
* A tad hacky, just because there's no way to excplictly tell
* if there are any declarations or not.
*/
node.walk(function (child) {
if (child.type === 'decl' ||
(child.type === 'rule' && child.ruleWithoutBody)) {
hasDeclarations = true;
return false;
}
});
if (hasDeclarations) {
return;
}
if (!hasDeclarations || !node.nodes.length) {
return [{

@@ -16,0 +34,0 @@ message: this.message

@@ -5,12 +5,14 @@ 'use strict';

name: 'finalNewline',
nodeTypes: ['stylesheet'],
nodeTypes: ['root'],
message: 'Files should end with a newline.',
lint: function finalNewlineLinter (config, node) {
var maybeLine = node.last();
var source;
if (maybeLine && (maybeLine.type !== 'space' && maybeLine.content !== '\n')) {
if (node.source.input.css.length && node.raws.after !== '\n') {
source = node.source.end ? node.source : node.last.source;
return [{
column: maybeLine.end.column + 1,
line: maybeLine.end.line,
column: source.end.column + 1,
line: source.end.line,
message: this.message

@@ -17,0 +19,0 @@ }];

@@ -7,40 +7,65 @@ 'use strict';

name: 'hexLength',
nodeTypes: ['color'],
nodeTypes: ['decl'],
message: '%s should be written in the %s-form format.',
lint: function hexLengthLinter (config, node) {
var color = '#' + node.content;
var canShorten = false;
var valid = true;
switch (config.style) {
case 'long':
if (color.length === 4 && !/^#[0-9a-f]{6}$/i.test(color)) {
valid = false;
}
var results = [];
var parser = require('postcss-values-parser');
var ast;
var self = this;
break;
case 'short':
// We want to allow longhand form on hex values that can't be shortened
if (color.length === 7) {
canShorten = (color[1] === color[2] && color[3] === color[4] && color[5] === color[6]);
// just in case, since postcss will sometimes include the semicolon
// in declaration values
node.value = node.value.replace(/;$/, '');
if (!/^#[0-9a-f]{3}$/i.test(color) && canShorten) {
ast = parser(node.value).parse();
ast.first.walk(function (node) {
var color;
var canShorten = false;
var valid = true;
if (node.type !== 'word' || !node.isColor) {
return;
}
color = node.value;
switch (config.style) {
case 'long':
if (color.length === 4 && !/^#[0-9a-f]{6}$/i.test(color)) {
valid = false;
}
}
break;
default:
throw new Error(
'Invalid setting value for hexLength: ' + config.style
);
}
break;
case 'short':
// We want to allow longhand form on hex values that can't be shortened
if (color.length === 7) {
canShorten = (color[1] === color[2] && color[3] === color[4] && color[5] === color[6]);
if (!valid) {
return [{
message: util.format(this.message, color, config.style)
}];
if (!/^#[0-9a-f]{3}$/i.test(color) && canShorten) {
valid = false;
}
}
break;
default:
throw new Error(
'Invalid setting value for hexLength: ' + config.style
);
}
if (!valid) {
results.push({
message: util.format(self.message, color, config.style)
});
}
});
if (results.length) {
return results;
}
}
};

@@ -7,38 +7,49 @@ 'use strict';

name: 'hexNotation',
nodeTypes: ['color'],
nodeTypes: ['decl'],
message: '%s should be written in %s.',
lint: function hexNotationLinter (config, node) {
var color = '#' + node.content;
var valid = true;
if (/^#\d+$/.test(color)) {
return null;
}
var results = [];
var parser = require('postcss-values-parser');
var ast;
var styles = {
lowercase: /^#[0-9a-z]+$/,
uppercase: /^#[0-9A-Z]+$/
};
var color;
var self = this;
switch (config.style) {
case 'lowercase':
if (!/^#[0-9a-z]+$/.test(color)) {
valid = false;
}
// just in case, since postcss will sometimes include the semicolon
// in declaration values
node.value = node.value.replace(/;$/, '');
break;
case 'uppercase':
if (!/^#[0-9A-Z]+$/.test(color)) {
valid = false;
}
ast = parser(node.value).parse();
break;
default:
throw new Error(
'Invalid setting value for hexNotation: ' + config.style
);
if (config.style && !styles[config.style]) {
throw new Error('Invalid setting value for hexNotation: ' + config.style);
}
if (!valid) {
return [{
message: util.format(this.message, color, config.style)
}];
ast.first.walk(function (node) {
if (node.type !== 'word' || !/^#/.test(node.value)) {
return;
}
color = node.value;
if (/^#\d+$/.test(color)) {
return;
}
if (!styles[config.style].test(color)) {
results.push({
message: util.format(self.message, color, config.style)
});
}
});
if (results.length) {
return results;
}
}
};

@@ -7,14 +7,35 @@ 'use strict';

name: 'hexValidation',
nodeTypes: ['color'],
nodeTypes: ['decl'],
message: 'Hexadecimal color "%s" should be either three or six characters long.',
lint: function hexValidationLinter (config, node) {
var color = '#' + node.content;
var results = [];
var parser = require('postcss-values-parser');
var ast;
var rHex = /^#([0-9a-f]+)(;?)$/i;
var rColor = /^(#([0-9a-f]{3}|[0-9a-f]{6}))(;?)$/i;
var self = this;
if (!/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(color)) {
return [{
message: util.format(this.message, color)
}];
// just in case, since postcss will sometimes include the semicolon
// in declaration values
node.value = node.value.replace(/;$/, '');
ast = parser(node.value).parse();
ast.first.walk(function (node) {
if (node.type !== 'word') {
return;
}
if (rHex.test(node.value) && !rColor.test(node.value)) {
results.push({
message: util.format(self.message, node.value)
});
}
});
if (results.length) {
return results;
}
}
};
'use strict';
var parser = require('postcss-selector-parser');
module.exports = {
name: 'idSelector',
nodeTypes: ['selector'],
nodeTypes: ['rule'],
message: 'Selectors should not use IDs.',
lint: function idSelectorLinter (config, node) {
var valid = true;
// var valid = true;
var excludes;
var start;
var tree;
var results = [];
var self = this;
parser(function (selectors) {
tree = selectors;
})
.process(node.selector);
excludes = config.exclude.map(function (id) {

@@ -18,23 +27,20 @@ // Remove #

node.content.some(function (element) {
var name = element.first('ident') && element.first('ident').content;
tree.each(function (selector) {
selector.walkIds(function (id) {
if (excludes.indexOf(id.value) >= 0) {
return;
}
if (element.type === 'id' && excludes.indexOf(name) === -1) {
valid = false;
start = element.start;
return true;
}
return false;
results.push({
column: id.source.start.column,
line: id.source.start.line,
message: self.message
});
});
});
if (!valid) {
return [{
column: start.column,
line: start.line,
message: this.message
}];
if (results.length) {
return results;
}
}
};
'use strict';
var parser = require('postcss-values-parser');
var helpers = require('../helpers');

@@ -19,19 +20,21 @@ var path = require('path');

var file;
var ast;
if (node.first('atkeyword').first('ident').content !== 'import') {
return null;
if (node.name !== 'import') {
return;
}
if (node.first('uri')) {
value = node.first('uri');
value = value.first('string') || value.first('raw');
} else {
value = node.first('string');
ast = parser(node.params).parse();
value = ast.first.first;
// Extract the value if it's a url() call
if (value.type === 'func' && value.value === 'url') {
value = value.first.next();
}
file = value.content.replace(/['"]/g, '');
file = value.value.trim().replace(/['"]/g, '');
// Ignore absolute URLs
if (helpers.isAbsoluteURL(file)) {
return null;
return;
}

@@ -41,3 +44,3 @@

if (config.exclude.indexOf(file) !== -1) {
return null;
return;
}

@@ -50,4 +53,4 @@

results.push({
column: value.start.column,
line: value.start.line,
column: node.source.start.column + node.name.length + value.source.start.column + 1,
line: node.source.start.line,
message: util.format(this.message.extension, file, ' not')

@@ -61,4 +64,4 @@ });

results.push({
column: value.start.column,
line: value.start.line,
column: node.source.start.column + node.name.length + value.source.start.column + 1,
line: node.source.start.line,
message: util.format(this.message.extension, file, '')

@@ -76,4 +79,4 @@ });

results.push({
column: value.start.column,
line: value.start.line,
column: node.source.start.column + node.name.length + value.source.start.column + 1,
line: node.source.start.line,
message: util.format(this.message.underscore, file, ' not')

@@ -87,4 +90,4 @@ });

results.push({
column: value.start.column,
line: value.start.line,
column: node.source.start.column + node.name.length + value.source.start.column + 1,
line: node.source.start.line,
message: util.format(this.message.underscore, file, '')

@@ -91,0 +94,0 @@ });

@@ -5,20 +5,23 @@ 'use strict';

name: 'importantRule',
nodeTypes: ['declaration'],
nodeTypes: ['rule'],
message: '!important should not be used.',
lint: function importantRuleLinter (config, node) {
var value;
var results = [];
var self = this;
node.forEach('value', function (element) {
value = element.first('important');
node.walkDecls(function (decl) {
if (decl.important) {
results.push({
column: decl.source.start.column,
line: decl.source.start.line,
message: self.message
});
}
});
if (value) {
return [{
column: value.start.column,
line: value.start.line,
message: this.message
}];
if (results.length) {
return results;
}
}
};

@@ -5,3 +5,3 @@ 'use strict';

name: 'propertyOrdering',
nodeTypes: ['block'],
nodeTypes: ['rule'],
message: 'Property ordering is not alphabetized',

@@ -11,3 +11,3 @@

var previousProp = null;
var results = null;
var results = [];
var self = this;

@@ -17,16 +17,15 @@

if (config.style !== 'alpha') {
throw new Error(
'Invalid setting value for propertyOrdering: ' + config.style
);
throw new Error('Invalid setting value for propertyOrdering: ' + config.style);
}
node.forEach('declaration', function (declaration) {
node.walkDecls(function (declaration) {
var currentProperty;
var property;
if (results) {
if (results.length) {
return;
}
property = declaration.first('property').first('ident');
property = declaration.prop;
if (!property) {

@@ -36,3 +35,3 @@ return;

currentProperty = property.content.toLowerCase();
currentProperty = property.toLowerCase();

@@ -42,4 +41,4 @@ // Check for proper ordering

results = [{
column: property.start.column,
line: property.start.line,
column: declaration.source.start.column,
line: declaration.source.start.line,
message: self.message

@@ -50,6 +49,9 @@ }];

previousProp = currentProperty;
});
return results;
if (results.length) {
return results;
}
}
};
'use strict';
var parser = require('postcss-values-parser');
var util = require('util');

@@ -7,5 +8,4 @@

name: 'propertyUnits',
nodeTypes: ['declaration'],
nodeTypes: ['decl'],
message: {
percentage: 'Percentages are not allowed for "%s".',
unit: 'Unit "%s" is not allowed for "%s".'

@@ -15,14 +15,13 @@ },

lint: function propertyUnitsLinter (config, node) {
var property = node.prop;
var results = [];
var self = this;
var property;
var value;
var ast;
if (!node.contains('property') || !node.first('property').contains('ident')) {
return null;
// Ignore variables
if (property.substring(0, 1) === '@') {
return;
}
property = node.first('property').first('ident').content;
value = node.first('value');
// sanity checking
// Sanity checks
config.valid = Array.isArray(config.valid) ? config.valid : [];

@@ -32,9 +31,15 @@ config.invalid = Array.isArray(config.invalid) ? config.invalid : [];

value.forEach('dimension', function (element) {
ast = parser(node.value).parse();
ast.first.walk(function (value) {
var allowed = config.properties[property];
var unit = element.first('ident').content;
var unit;
// if this unit is marked invalid, then the other checks are moot
if (value.type !== 'number' || !value.unit) {
return;
}
unit = value.unit;
// If this unit is marked invalid, then the other checks are moot
if (config.invalid.indexOf(unit) === -1) {
// Check if the unit is allowed for this property

@@ -52,4 +57,4 @@ if (Array.isArray(allowed) && allowed.indexOf(unit) !== -1) {

results.push({
column: element.start.column,
line: element.start.line,
column: node.raws.between.length + property.length + value.source.start.column,
line: value.source.start.line,
message: util.format(self.message.unit, unit, property)

@@ -59,23 +64,2 @@ });

// Check if percentages are allowed
if (config.valid.indexOf('%') === -1) {
value.forEach('percentage', function (element) {
if (config.invalid.indexOf('%') === -1) {
// Check if the percentages are allowed for this property
if (config.properties[property]) {
if (config.properties[property].indexOf('%') !== -1) {
return;
}
}
}
results.push({
column: element.start.column,
line: element.start.line,
message: util.format(self.message.percentage, property)
});
});
}
if (results.length) {

@@ -82,0 +66,0 @@ return results;

'use strict';
var helpers = require('../helpers');
var parser = require('postcss-selector-parser');
var util = require('util');

@@ -8,46 +8,65 @@

name: 'qualifyingElement',
nodeTypes: ['selector'],
nodeTypes: ['rule'],
message: '%s selectors should not include a qualifying element.',
lint: function qualifyingElementLinter (config, node) {
var nodeTypes = ['parentSelector', 'typeSelector'];
var result;
var selectorTypes = ['nesting', 'tag'];
var results = [];
var self = this;
node.traverseByTypes(nodeTypes, function (selector, index) {
selector = helpers.ensureObject(node.get(index + 1));
parser(function (selectors) {
selectors.each(function (selector) {
var result;
switch (selector.type) {
case 'attributeSelector':
if (config.allowWithAttribute) {
selector.nodes.forEach(function (element, index) {
if (selectorTypes.indexOf(element.type) === -1) {
return;
}
result = selector;
result.type = 'attribute'; // Special case because of node type
break;
case 'class':
if (config.allowWithClass) {
// Fetch the next node to check it
element = selector.at(index + 1);
if (!element) {
return;
}
result = selector;
break;
case 'id':
if (config.allowWithId) {
return;
switch (element.type) {
case 'attribute':
if (config.allowWithAttribute) {
return;
}
result = element;
break;
case 'class':
if (config.allowWithClass) {
return;
}
result = element;
break;
case 'id':
if (config.allowWithId) {
return;
}
result = element;
break;
}
result = selector;
break;
}
});
if (result) {
results.push({
column: result.source.start.column,
line: result.source.start.line,
message: util.format(self.message, result.type.charAt(0).toUpperCase() + result.type.substring(1))
});
}
});
});
}).process(node.selector);
if (result) {
return [{
column: result.start.column,
line: result.start.line,
message: util.format(this.message, result.type.charAt(0).toUpperCase() + result.type.substring(1))
}];
if (results.length) {
return results;
}
}
};
'use strict';
var parser = require('postcss-selector-parser');
var util = require('util');
module.exports = {
name: 'selectorNaming',
nodeTypes: ['selector'],
message: 'Selector should respect naming convention.',
nodeTypes: ['rule'],
message: 'Selector "%s" should follow naming conventions.',
lint: function selectorNamingLinter (config, node) {
var start;
var hasErrors;
var exclude;
var selectorTypes = ['class', 'id'];
var exclude = config.exclude;
var results = [];
var self = this;
config = config || {};
exclude = config.exclude;
parser(function (selectors) {
selectors.walk(function (selector) {
var name = selector.value;
hasErrors = node.content.some(function (element) {
var name = element.first('ident') && element.first('ident').content;
if (selectorTypes.indexOf(selector.type) === -1) {
return;
}
if (name === null) {
return false;
}
if (exclude && exclude.indexOf(name) !== -1) {
return;
}
if (exclude && exclude.indexOf(name) > -1) {
return false;
}
if (
(config.disallowUppercase && name.toLowerCase() !== name) ||
(config.disallowUnderscore && name.indexOf('_') !== -1) ||
(config.disallowDash && name.indexOf('-') !== -1)
) {
results.push({
column: selector.source.start.column,
line: selector.source.start.line,
message: util.format(self.message, name)
});
}
});
}).process(node.selector);
if ((config.disallowUppercase === true && name.toLowerCase() !== name) ||
(config.disallowUnderscore === true && name.indexOf('_') > -1) ||
(config.disallowDash === true && name.indexOf('-') > -1)) {
start = element.start;
return true;
}
return false;
});
if (hasErrors) {
return [{
column: start.column,
line: start.line,
message: this.message
}];
if (results.length) {
return results;
}
}
};
'use strict';
var helpers = require('../helpers');
var isValidAfter = function (node, index) {
var next = node.parent.nodes[index + 1];
if (!next || (next && next.type === 'comment')) {
// Only valid if followed by comment
return true;
}
return false;
};
module.exports = {
name: 'singleLinePerProperty',
nodeTypes: ['block'],
nodeTypes: ['rule'],
message: 'Each property should be on its own line.',
lint: function singleLinePerPropertyLinter (config, node) {
var types = ['decl', 'rule', 'atrule'];
var results = [];
var self = this;
['declaration', 'include', 'extend', 'atrule', 'mixin'].forEach(function (type) {
node.forEach(type, function (element, index) {
var previousValid = self.isPreviousValid(node, index);
var nextValid = self.isNextValid(node, index);
// BOTH previous and next must be valid
if (!(previousValid && nextValid)) {
results.push({
column: element.start.column,
line: element.start.line,
message: self.message
});
}
});
});
if (results.length) {
return results;
if (node.ruleWithoutBody) {
return;
}
},
isPreviousValid: function (node, index) {
var prev = node.get(index - 1);
node.nodes.forEach(function (child, index) {
var validBefore;
var validAfter;
if (!prev || (prev.type === 'space' && !prev.toString().match(/\n/))) {
// Previous sibling not new line
return false;
}
if (types.indexOf(child.type) === -1) {
return;
}
return true;
},
validBefore = /\n/.test(child.raws.before);
validAfter = isValidAfter(node, index);
isNextValid: function (node, index) {
// Check next node first (might be the declaration delimiter (;) but we'll compensate for that later)
var next = helpers.ensureObject(node.get(index + 1));
var isValid = false;
// Check if the closing bracket is on the same line as the last property
if (index === node.nodes.length - 1 &&
child.source.end.line === node.source.end.line) {
validAfter = false;
}
// Now, move forward one node if it's the declaration delimiter (;)
if (next.type === 'declarationDelimiter') {
next = helpers.ensureObject(node.get(index + 2));
} else if (!next.type) {
isValid = true;
}
if (!(validBefore && validAfter)) {
results.push({
column: child.source.start.column,
line: child.source.start.line,
message: this.message
});
}
}, this);
switch (next.type) {
case 'space':
if (next.content.match(/\n/)) {
isValid = true;
} else {
// Sibling is not a new line
next = helpers.ensureObject(node.get(index + 3));
if (next.type === 'multilineComment' || next.type === 'singlelineComment') {
// Only valid if followed by comment
isValid = true;
} else {
isValid = false;
}
}
break;
case 'singlelineComment': // Comment butt up against declaration
case 'multilineComment': // No break
case 'mixin': // "Chained" mixin, i.e. .foo.bar()
isValid = true;
break;
if (results.length) {
return results;
}
return isValid;
}
};
'use strict';
var helpers = require('../helpers');
// var helpers = require('../helpers');
module.exports = {
name: 'singleLinePerSelector',
nodeTypes: ['ruleset'],
nodeTypes: ['rule'],
message: 'Each selector should be on its own line.',
lint: function singleLinePerSelectorLinter (config, node) {
var report = false;
var parser = require('postcss-selector-parser');
var valid = true;
var results = [];
var self = this;
var tree;
node.forEach('delimiter', function (element, index) {
element = helpers.ensureObject(node.get(index + 1));
parser(function (result) {
tree = result;
}).process(node.selector);
// Check if the delimiter is on the next line
if (element.type !== 'space') {
element = helpers.ensureObject(node.get(index - 1));
}
tree.each(function (selector) {
selector.each(function (thing) {
var value = thing.toString().trim();
switch (config.style) {
case '18f':
node.forEach('selector', function (selector) {
selector = helpers.ensureObject(selector.first().first('ident'));
selector = selector.content;
if (selector && selector.length >= 5) {
report = true;
switch (config.style) {
case '18f':
if (value && value.length >= 5) {
valid = false;
return;
}
break;
default:
valid = false;
break;
}
if (!valid && tree.nodes.length > 1 && node.selector.indexOf('\n') === -1) {
results.push({
column: thing.source.start.column,
line: thing.source.start.line,
message: self.message
});
break;
default:
report = true;
break;
}
if (report && element.content.indexOf('\n') === -1) {
results.push({
column: element.start.column,
line: element.start.line,
message: self.message
});
}
}
});
});

@@ -50,0 +46,0 @@

'use strict';
var findIndex = require('lodash.findindex');
var util = require('util');

@@ -8,59 +7,27 @@

name: 'spaceAfterPropertyColon',
nodeTypes: ['declaration'],
nodeTypes: ['decl'],
message: {
noSpace: 'Colon after property name should not be followed by any spaces.',
oneSpace: 'Colon after property name should be followed by one space.',
atLeastOneSpace: 'Colon after property name should be followed by at least one space.'
'no_space': 'Colon after property name should not be followed by any spaces.',
'one_space': 'Colon after property name should be followed by one space.',
'at_least_one_space': 'Colon after property name should be followed by at least one space.'
},
lint: function spaceAfterPropertyColonLinter (config, node) {
var style = config.style;
var valid = true;
var checkIndex;
var maybeSpace;
var message;
// Find the colon (south of the spleen)
checkIndex = findIndex(node.content, function (element) {
return (element.type === 'propertyDelimiter' && element.content === ':');
});
maybeSpace = node.content[checkIndex + 1];
var styles = {
'no_space': /^:$/,
'one_space': /^:\s$/,
'at_least_one_space': /^:\s{1,}$/
};
switch (style) {
case 'no_space':
if (maybeSpace.type === 'space') {
valid = false;
}
message = this.message.noSpace;
break;
case 'one_space':
if (maybeSpace.type !== 'space' || (maybeSpace.type === 'space' && maybeSpace.content !== ' ')) {
valid = false;
}
message = this.message.oneSpace;
break;
case 'at_least_one_space':
if (maybeSpace.type !== 'space') {
valid = false;
}
message = this.message.atLeastOneSpace;
break;
default:
throw new Error(
'Invalid setting value for spaceAfterPropertyColon: ' + config.style
);
if (config.style && !styles[config.style]) {
throw new Error('Invalid setting value for urlFormat: ' + config.style);
}
if (!valid) {
if (!styles[config.style].test(node.raws.between)) {
return [{
column: maybeSpace.start.column,
line: maybeSpace.start.line,
message: util.format(message)
column: node.source.start.column + node.prop.length + 1,
line: node.source.start.line,
message: util.format(this.message[config.style])
}];

@@ -67,0 +34,0 @@ }

'use strict';
var findIndex = require('lodash.findindex');
var util = require('util');

@@ -8,43 +7,25 @@

name: 'spaceAfterPropertyName',
nodeTypes: ['declaration'],
message: 'Colon after property should%s be preceded by any space.',
nodeTypes: ['decl'],
message: 'Colon after property should%s be preceded by %s space.',
lint: function spaceAfterPropertyNameLinter (config, node) {
var style = config.style;
var valid = true;
var checkIndex;
var maybeSpace;
// Find the colon (it's next to the prostate)
checkIndex = findIndex(node.content, function (element) {
return (element.type === 'property');
});
var styles = {
'no_space': /^:/,
'one_space': /^\s:/
};
maybeSpace = node.content[checkIndex + 1];
switch (style) {
case 'no_space':
if (maybeSpace.type === 'space') {
valid = false;
}
break;
case 'one_space':
if (maybeSpace.type !== 'space' || (maybeSpace.type === 'space' && maybeSpace.content !== ' ')) {
valid = false;
this.message = this.message.replace('any', 'one');
}
break;
default:
throw new Error(
'Invalid setting value for spaceAfterPropertyName: ' + config.style
);
if (config.style && !styles[config.style]) {
throw new Error('Invalid setting value for spaceAfterPropertyName: ' + config.style);
}
if (!valid) {
if (!styles[config.style].test(node.raws.between)) {
return [{
column: maybeSpace.start.column,
line: maybeSpace.start.line,
message: util.format(this.message, style === 'no_space' ? ' not' : '')
column: node.source.start.column + node.prop.length,
line: node.source.start.line,
message: util.format(
this.message,
config.style === 'no_space' ? ' not' : '',
config.style === 'no_space' ? 'any' : 'one'
)
}];

@@ -51,0 +32,0 @@ }

@@ -7,3 +7,3 @@ 'use strict';

name: 'spaceAfterPropertyValue',
nodeTypes: ['block'],
nodeTypes: ['decl'],
message: 'Semicolon after property value should%s be preceded by %s space.',

@@ -15,33 +15,27 @@

node.forEach('declarationDelimiter', function (element, index) {
var maybeSpace = node.get(index - 1);
switch (config.style) {
case 'no_space':
if (node.raws.value && /.*\s$/.test(node.raws.value.raw)) {
results.push({
column: node.source.end.column - 1,
line: node.source.end.line,
message: util.format(self.message, ' not', 'any')
});
}
switch (config.style) {
case 'no_space':
if (maybeSpace.type === 'space') {
results.push({
column: maybeSpace.start.column,
line: maybeSpace.start.line,
message: util.format(self.message, ' not', 'any')
});
}
break;
case 'one_space':
if (!node.raws.value) {
results.push({
column: node.source.end.column,
line: node.source.end.line,
message: util.format(self.message, '', 'one')
});
}
break;
case 'one_space':
if (maybeSpace.type !== 'space' || (maybeSpace.type === 'space' && maybeSpace.content !== ' ')) {
results.push({
column: maybeSpace.start.column,
line: maybeSpace.start.line,
message: util.format(self.message, '', 'one')
});
}
break;
default:
throw new Error('Invalid setting value for spaceAfterPropertyValue: ' + config.style);
}
break;
default:
throw new Error(
'Invalid setting value for spaceAfterPropertyValue: ' + config.style
);
}
});
if (results.length) {

@@ -48,0 +42,0 @@ return results;

'use strict';
var parser = require('postcss-values-parser');
var util = require('util');

@@ -7,60 +8,60 @@

name: 'spaceAroundComma',
nodeTypes: ['arguments', 'parentheses'],
nodeTypes: ['decl', 'rule'],
message: 'Commas should%s be %s by %s space.',
lint: function spaceAroundCommaLinter (config, node) {
var column = node.source.start.column;
var results = [];
var self = this;
var ast;
node.forEach('operator', function (element, index) {
var startElement;
var nextElement;
var prevElement;
if (node.params) {
// A bit hacky, we're abusing the values parser for mixins etc.
ast = parser(node.selector).parse();
} else if (node.type === 'decl') {
ast = parser(node.value).parse();
column += node.prop.length + node.raws.between.length;
} else {
return;
}
ast.walk(function (child) {
var message;
var index;
var next;
if (element.content !== ',') {
if (child.type !== 'comma') {
return;
}
nextElement = node.content[index + 1];
prevElement = node.content[index - 1];
index = child.parent.index(child);
next = child.parent.nodes[index + 1];
// setting `startElement` equal to nextElement as the default for
// `style`is `after`
startElement = nextElement;
switch (config.style) {
case 'after':
if (nextElement.type !== 'space' || nextElement.content !== ' ') {
if (next.raws.before !== ' ') {
message = util.format(self.message, '', 'followed', 'one');
}
break;
case 'before':
if (prevElement.type !== 'space' || prevElement.content !== ' ') {
startElement = prevElement;
if (child.raws.before !== ' ') {
message = util.format(self.message, '', 'preceded', 'one');
}
break;
case 'both':
if (nextElement.type !== 'space' || nextElement.content !== ' ' || !/^\s/.test(nextElement.content) ||
(prevElement.type !== 'space' || prevElement.content !== ' ') || !/\s$/.test(prevElement.content)) {
startElement = !/\s$/.test(prevElement.content) ? prevElement : nextElement;
if (child.raws.before !== ' ' || next.raws.before !== ' ') {
message = util.format(self.message, '', 'preceded and followed', 'one');
}
break;
case 'none':
if (nextElement.type === 'space' || prevElement.type === 'space') {
startElement = prevElement.type === 'space' ? prevElement : nextElement;
if (child.raws.before || next.raws.before) {
message = util.format(self.message, ' not', 'preceded nor followed', 'any');
}
break;
default:
throw new Error(
'Invalid setting value for spaceAfterComma: ' + config.style
);
throw new Error('Invalid setting value for spaceAfterComma: ' + config.style);
}

@@ -70,4 +71,3 @@

results.push({
column: startElement.start.column,
line: startElement.start.line,
column: column + child.source.start.column - ','.length,
message: message

@@ -74,0 +74,0 @@ });

'use strict';
var parser = require('postcss-values-parser');
var util = require('util');

@@ -7,11 +8,11 @@

name: 'spaceAroundOperator',
nodeTypes: ['stylesheet'],
nodeTypes: ['decl'],
message: 'Operators should%s be %s by %s space.',
lint: function spaceAroundOperatorLinter (config, node) {
var ignore = [':', ','];
var ast = parser(node.value).parse();
var results = [];
var self = this;
node.traverseByType('operator', function (element, index, parent) {
ast.walk(function (child) {
var startElement;

@@ -21,11 +22,15 @@ var nextElement;

var message;
var index;
if (ignore.indexOf(element.content) !== -1) {
if (child.type !== 'operator') {
return;
}
nextElement = parent.content[index + 1];
prevElement = parent.content[index - 1];
index = child.parent.index(child);
nextElement = child.parent.nodes[index + 1];
prevElement = child.parent.nodes[index - 1];
if (typeof prevElement === 'undefined' || typeof nextElement === 'undefined') {
// Ignore negative numbers
if (child.value === '-' && (child.raws.before || node.raws.between) &&
nextElement.type === 'number' && !nextElement.raws.before) {
return;

@@ -35,19 +40,12 @@ }

// Ignore font-size/line-height shorthand declaration
if ((element.content === '/' && prevElement.type === 'dimension') &&
(nextElement.type === 'dimension' || nextElement.type === 'number')) {
if (node.prop === 'font' && child.value === '/' &&
prevElement.type === 'number' && nextElement.type === 'number') {
return;
}
// Ignore negative numbers/regular shorthand natations
if (element.content === '-' && prevElement.type === 'space' &&
['dimension', 'number', 'percentage'].indexOf(nextElement.type) !== -1) {
return;
}
switch (config.style) {
case 'both':
if (nextElement.type !== 'space' || nextElement.content !== ' ' || !/^\s/.test(nextElement.content) ||
(prevElement.type !== 'space' || prevElement.content !== ' ') || !/\s$/.test(prevElement.content)) {
startElement = !/\s$/.test(prevElement.content) ? prevElement : nextElement;
if (child.raws.before !== ' ' || !/^\s/.test(child.raws.before) ||
nextElement.raws.before !== ' ' || !/\s$/.test(nextElement.raws.before)) {
startElement = !/\s$/.test(child.raws.before) ? child : nextElement;
message = util.format(self.message, '', 'preceded and followed', 'one');

@@ -58,4 +56,4 @@ }

case 'none':
if (nextElement.type === 'space' || prevElement.type === 'space') {
startElement = prevElement.type === 'space' ? prevElement : nextElement;
if (child.raws.before || nextElement.raws.before) {
startElement = child.raws.before ? child : nextElement;
message = util.format(self.message, ' not', 'preceded nor followed', 'any');

@@ -66,5 +64,3 @@ }

default:
throw new Error(
'Invalid setting value for spaceAfterOperator: ' + config.style
);
throw new Error('Invalid setting value for spaceAfterOperator: ' + config.style);
}

@@ -74,4 +70,3 @@

results.push({
column: startElement.start.column,
line: startElement.start.line,
column: node.source.start.column + node.prop.length + node.raws.between.length + startElement.source.start.column + 1,
message: message

@@ -78,0 +73,0 @@ });

'use strict';
var helpers = require('../helpers');
module.exports = {
name: 'spaceBeforeBrace',
nodeTypes: ['atrule', 'mixin', 'ruleset'],
nodeTypes: ['atrule', 'mixin', 'rule'],
message: {
newLine: 'Opening curly brace should be on its own line.',
noSpace: 'Opening curly brace should not be preceded by a space or new line.',
oneSpace: 'Opening curly brace should be preceded by one space.'
'new_line': 'Opening curly brace should be on its own line.',
'no_space': 'Opening curly brace should not be preceded by a space or new line.',
'one_space': 'Opening curly brace should be preceded by one space.'
},
lint: function spaceBeforeBraceLinter (config, node) {
var maybeSpace = helpers.ensureObject(node.content[node.content.length - 2]);
var block = node.first('block');
var message;
var column;
var styles = {
'new_line': /^\n$/,
'no_space': /^$/,
'one_space': /^\s$/
};
// No block, no brace to check
if (!block) {
if (config.style && !styles[config.style]) {
throw new Error('Invalid setting value for spaceBeforeBrace: ' + config.style);
}
if (node.ruleWithoutBody) {
return;
}
switch (config.style) {
case 'no_space':
if (maybeSpace.type === 'space') {
message = this.message.noSpace;
}
if (!styles[config.style].test(node.raws.between)) {
column = node.source.start.column;
break;
case 'one_space':
if (maybeSpace.type !== 'space' || (maybeSpace.type === 'space' && maybeSpace.content !== ' ')) {
message = this.message.oneSpace;
if (node.type === 'rule') {
column += node.selector.length;
} else if (node.type === 'atrule') {
column += 1 + node.name.length + node.raws.afterName.length + node.params.length;
}
// Fetch the position where the space should have been
column = block.start.column;
}
break;
case 'new_line':
if (maybeSpace.type !== 'space' || (maybeSpace.type === 'space' && maybeSpace.content !== '\n')) {
message = this.message.newLine;
}
break;
default:
throw new Error('Invalid setting value for spaceBeforeBrace: ' + config.style);
}
if (message) {
return [{
column: column || maybeSpace.start.column,
line: maybeSpace.start.line,
message: message
column: column,
line: node.source.start.line,
message: this.message[config.style]
}];

@@ -57,0 +42,0 @@ }

'use strict';
var helpers = require('../helpers');
var parser = require('postcss-values-parser');
var util = require('util');

@@ -8,3 +8,3 @@

name: 'spaceBetweenParens',
nodeTypes: ['arguments', 'parentheses'],
nodeTypes: ['decl', 'rule'],
message: {

@@ -16,49 +16,71 @@ opening: 'Opening parenthesis should%s be %s by %s space.',

lint: function spaceBetweenParensLinter (config, node) {
var first = helpers.ensureObject(node.first());
var last = helpers.ensureObject(node.last());
var column = node.source.start.column;
var results = [];
var self = this;
var ast;
switch (config.style) {
case 'no_space':
if (first.type === 'space') {
results.push({
column: first.start.column,
line: first.start.line,
message: util.format(this.message.opening, ' not', 'followed', 'any')
});
}
if (node.params) {
// A bit hacky, we're abusing the values parser for mixins etc.
ast = parser(node.selector).parse();
} else if (node.type === 'decl') {
ast = parser(node.value).parse();
column += node.prop.length + node.raws.between.length;
} else {
return;
}
if (last.type === 'space') {
results.push({
column: last.start.column,
line: last.start.line,
message: util.format(this.message.closing, ' not', 'preceded', 'any')
});
}
ast.walk(function (child) {
var index;
var prev;
var next;
break;
case 'one_space':
if (first.type !== 'space' || first.content !== ' ') {
results.push({
column: first.start.column,
line: first.start.line,
message: util.format(this.message.opening, '', 'followed', 'one')
});
}
if (child.type !== 'paren') {
return;
}
if (last.type !== 'space' || last.content !== ' ') {
results.push({
column: last.start.column,
line: last.start.line,
message: util.format(this.message.closing, '', 'preceded', 'one')
});
}
index = child.parent.index(child);
prev = child.parent.nodes[index - 1];
next = child.parent.nodes[index + 1];
break;
default:
throw new Error(
'Invalid setting value for spaceBetweenParens: ' + config.style
);
}
switch (config.style) {
case 'no_space':
if (child.value === '(' && (next.raws && next.raws.before)) {
results.push({
column: column + child.source.start.column,
line: child.source.start.line,
message: util.format(self.message.opening, ' not', 'followed', 'any')
});
}
if (child.value === ')' && (prev.raws && prev.raws.after)) {
results.push({
column: column + prev.source.end.column,
line: prev.source.end.line,
message: util.format(self.message.closing, ' not', 'preceded', 'any')
});
}
break;
case 'one_space':
if (child.value === '(' && (next.raws && next.raws.before !== ' ')) {
results.push({
column: column + child.source.start.column,
line: child.source.start.line,
message: util.format(self.message.opening, '', 'followed', 'one')
});
}
if (child.value === ')' && (prev.raws && prev.raws.after !== ' ')) {
results.push({
column: column + prev.source.end.column,
line: prev.source.end.line,
message: util.format(self.message.closing, '', 'preceded', 'one')
});
}
break;
default:
throw new Error('Invalid setting value for spaceBetweenParens: ' + config.style);
}
});
if (results.length) {

@@ -65,0 +87,0 @@ return results;

'use strict';
var selectorParser = require('postcss-selector-parser');
var valuesParser = require('postcss-values-parser');
var util = require('util');

@@ -7,3 +9,3 @@

name: 'stringQuotes',
nodeTypes: ['stylesheet'],
nodeTypes: ['decl', 'rule'],
message: 'Strings should use %s quotes.',

@@ -14,37 +16,53 @@

var self = this;
var ast;
var quotes = {
double: /"/,
single: /'/
};
node.traverse(function (element) {
var valid = true;
if (config.style && !quotes[config.style]) {
throw new Error('Invalid setting value for stringQuotes: ' + config.style);
}
if (element.type !== 'string') {
return;
}
if (node.type === 'decl') {
ast = valuesParser(node.value).parse();
ast.first.walk(function (decl) {
var column;
switch (config.style) {
case 'double':
if (!/".*"/.test(element.content)) {
valid = false;
}
if (decl.type !== 'string') {
return;
}
break;
case 'single':
if (!/'.*'/.test(element.content)) {
valid = false;
}
if (!quotes[config.style].test(decl.raws.quote)) {
column = (node.raws.between ? node.raws.between.length : 0) +
node.source.start.column +
node.prop.length +
decl.source.start.column -
decl.raws.quote.length;
break;
default:
throw new Error(
'Invalid setting value for stringQuotes: ' + config.style
);
}
results.push({
column: column,
line: decl.source.start.line,
message: util.format(self.message, config.style)
});
}
});
} else {
selectorParser(function (selectors) {
selectors.walkAttributes(function (selector) {
var column;
if (!valid) {
results.push({
column: element.start.column,
line: element.start.line,
message: util.format(self.message, config.style)
if (selector.quoted && !quotes[config.style].test(selector.value)) {
column = selector.source.start.column + selector.attribute.length
+ selector.operator.length + '['.length;
results.push({
column: column,
line: selector.source.start.line,
message: util.format(self.message, config.style)
});
}
});
}
});
}).process(node.selector);
}

@@ -51,0 +69,0 @@ if (results.length) {

'use strict';
var findIndex = require('lodash.findindex');
module.exports = {
name: 'trailingSemicolon',
nodeTypes: ['block'],
nodeTypes: ['rule', 'atrule'],
message: 'All property declarations should end with a semicolon.',
lint: function trailingSemicolonLinter (config, node) {
var checkIndex;
var start;
var others = 0;
// Find declarations
checkIndex = findIndex(node.content, function (element) {
return element.type === 'declaration';
});
if (node.ruleWithoutBody || (node.nodes && !node.nodes.length)) {
return;
}
if (checkIndex !== -1 && !node.first('declarationDelimiter')) {
start = node.last().start;
if (!node.raws.semicolon) {
node.walk(function (n) {
if (n.type !== 'decl') {
others++;
}
});
return [{
column: start.column,
line: start.line,
message: this.message
}];
/**
* If the node contains child nodes that aren't Declarations,
* then PostCSS will report raws.semicolon: false. in that case
* we should wait until lesshint walks to that Rule/AtRule, and
* let the linter handle that one.
*/
if (others === 0) {
return [{
column: node.source.start.column,
line: node.source.start.line,
message: this.message
}];
}
}
}
};

@@ -5,16 +5,20 @@ 'use strict';

name: 'trailingWhitespace',
nodeTypes: ['stylesheet'],
nodeTypes: ['root'],
message: "There should't be any trailing whitespace.",
lint: function trailingWhitespaceLinter (config, node) {
var results = [];
var self = this;
// PostCSS has a few whitespace inconsistencies.
// tracking in: https://github.com/postcss/postcss/issues/775
// once those are resolved, we won't have to reparse the file.
//Ignore empty files
if (node.content.length === 0) {
if (node.source.input.css.length === 0) {
return;
}
// We'll convert the AST to the Less source and just loop through each line
node = node.toString('less') || '';
node = node.source.input.css;

@@ -21,0 +25,0 @@ node.split('\n').forEach(function (line, index) {

@@ -8,46 +8,39 @@ 'use strict';

name: 'urlFormat',
nodeTypes: ['declaration'],
nodeTypes: ['decl'],
message: 'URL "%s" should be %s.',
lint: function urlFormatLinter (config, node) {
var valid = true;
var value;
var url;
lint: function urlFormatLinter (config, decl) {
node.forEach('value', function (element) {
value = element.first('uri');
});
var parser = require('postcss-values-parser');
var ast = parser(decl.params || decl.value).parse();
var style = {
absolute: helpers.isAbsoluteURL,
relative: function (url) {
return !helpers.isAbsoluteURL(url);
}
};
var uri = ast.first.first;
var column;
// No URLs found, bail
if (!value) {
return null;
if (config.style && !style[config.style]) {
throw new Error('Invalid setting value for urlFormat: ' + config.style);
}
url = value.first('string') || value.first('raw');
url = url.content.replace(/['"]/g, '');
if (uri.type !== 'func' || uri.value !== 'url') {
return;
}
switch (config.style) {
case 'absolute':
if (!helpers.isAbsoluteURL(url)) {
valid = false;
}
uri = uri.first.next();
break;
case 'relative':
if (helpers.isAbsoluteURL(url)) {
valid = false;
}
if (!style[config.style](uri.value)) {
break;
default:
throw new Error(
'Invalid setting value for urlFormat: ' + config.style
);
}
column = (decl.raws.between ? decl.raws.between.length : 0) +
decl.source.start.column +
decl.prop.length +
uri.source.start.column - 1;
if (!valid) {
return [{
column: value.start.column,
line: value.start.line,
message: util.format(this.message, url, config.style)
column: column,
line: decl.source.start.line,
message: util.format(this.message, uri.value, config.style)
}];

@@ -54,0 +47,0 @@ }

@@ -5,28 +5,37 @@ 'use strict';

name: 'urlQuotes',
nodeTypes: ['declaration', 'atrule'],
nodeTypes: ['decl', 'atrule'],
message: 'URLs should be enclosed in quotes.',
lint: function urlQuotesLinter (config, node) {
var parser = require('postcss-values-parser');
var ast = parser(node.params || node.value).parse();
var uri = ast.first.first;
var column;
var value;
var url;
var rSingle = /^\'(.+)\'$/;
var rDouble = /^\"(.+)\"$/;
if (node.is('declaration')) {
node.forEach('value', function (element) {
value = element.first('uri');
});
} else if (node.is('atrule')) {
value = node.first('uri');
if (uri.type !== 'func' || uri.value !== 'url') {
return;
}
// No URLs found, bail
if (!value) {
return null;
}
uri = uri.first.next();
value = uri.value.trim();
url = value.first('string');
// postcss-values-parser has a bug with url string params surrounded by
// spaces. so account for that here.
// tracking: https://github.com/lesshint/postcss-values-parser/issues/1
if ((uri.type === 'word' &&
!(rSingle.test(value) || rDouble.test(value))) &&
uri.type !== 'string') {
if (!url) {
column = (node.raws.between ? node.raws.between.length : 0) +
node.source.start.column +
(node.prop || node.name).length +
uri.source.start.column - 1;
return [{
column: value.start.column,
line: value.start.line,
column: column,
line: node.source.start.line,
message: this.message

@@ -33,0 +42,0 @@ }];

'use strict';
var parser = require('postcss-values-parser');
var util = require('util');

@@ -7,3 +8,3 @@

name: 'zeroUnit',
nodeTypes: ['declaration'],
nodeTypes: ['decl'],
message: 'Unit should %sbe omitted on zero values.',

@@ -14,9 +15,7 @@

var units = ['em', 'ex', 'ch', 'rem', 'vw', 'vh', 'vmin', 'vmax', 'cm', 'mm', 'in', 'pt', 'pc', 'px'];
var valid = true;
var number;
var value;
var unit;
var excludedProperties = ['opacity', 'z-index'];
var excludedUnits = [];
var property = node.first('property').first('ident');
var results = [];
var self = this;
var ast;

@@ -33,62 +32,57 @@ if (config) {

// No property, or it shouldn't be checked for units
if (!property || (property.content && excludedProperties.indexOf(property.content) !== -1)) {
// This property shouldn't be checked for units
if (excludedProperties.indexOf(node.prop) !== -1) {
return;
}
node.forEach('value', function (element) {
value = element.first('dimension');
ast = parser(node.value).parse();
if (value) {
number = value.first('number');
unit = value.first('ident');
} else {
value = element.first('number'); // For use in errors
ast.walk(function (child) {
var unit = child.unit;
var valid = true;
number = value;
if (child.type !== 'number' || child.value !== '0') {
return;
}
});
// Nothing to lint found, bail
if (!number || parseFloat(number.content) !== 0) {
return;
}
// Unit is excluded, nothing to do
if (excludedUnits.indexOf(unit) !== -1) {
return;
}
// Unit is excluded, nothing to do
if (unit && excludedUnits.indexOf(unit.content) > -1) {
return;
}
// Unit is always required by the CSS spec, nothing to do
if (unit && units.indexOf(unit) === -1) {
return;
}
// Unit is always required by the CSS spec, nothing to do
if (unit && units.indexOf(unit.content) === -1) {
return;
}
switch (config.style) {
case 'keep_unit':
if (!unit) {
valid = false;
}
number = number.content;
break;
case 'no_unit':
if (unit) {
valid = false;
}
switch (config.style) {
case 'keep_unit':
if (!unit) {
valid = false;
}
break;
default:
throw new Error('Invalid setting value for zeroUnit: ' + config.style);
}
break;
case 'no_unit':
if (unit) {
valid = false;
}
if (!valid) {
results.push({
column: node.prop.length + node.raws.between.length + child.source.start.column,
line: node.source.start.line,
message: util.format(self.message, config.style === 'keep_unit' ? 'not ' : '')
});
}
});
break;
default:
throw new Error('Invalid setting value for zeroUnit: ' + config.style);
if (results.length) {
return results;
}
if (!valid) {
return [{
column: value.start.column,
line: value.start.line,
message: util.format(this.message, config.style === 'keep_unit' ? 'not ' : '')
}];
}
}
};
{
"name": "lesshint",
"description": "A tool to aid you in writing clean and consistent Less.",
"version": "1.5.2",
"version": "2.0.0-rc",
"main": "./lib/lesshint.js",

@@ -20,10 +20,11 @@ "author": {

"dependencies": {
"chalk": "^1.0.0",
"commander": "^2.8.0",
"exit": "^0.1.2",
"gonzales-pe": "gilt/gonzales-pe#dev",
"lodash.findindex": "^4.0.1",
"lodash.merge": "^4.0.1",
"lodash.sortby": "^4.0.1",
"minimatch": "^3.0.0",
"postcss": "^5.0.19",
"postcss-less": "^0.10.0",
"postcss-selector-parser": "^2.0.0",
"postcss-values-parser": "^0.1.0",
"rcfinder": "^0.1.8",

@@ -30,0 +31,0 @@ "strip-bom": "^2.0.0",

@@ -18,3 +18,3 @@ # lesshint

## Requirements
[Node.js](https://nodejs.org/) 0.10 (or later) or [io.js](https://iojs.org/) 1.0 (or later).
[Node.js](https://nodejs.org/) 0.12 (or later) or [io.js](https://iojs.org/) 1.0 (or later).

@@ -137,18 +137,39 @@ ## Installation

## Reporters
As of `0.8.0` the ability to specify custom reporters has been added. These can do anything from just printing something to the terminal to generate custom reports.
Reporters can be used to perform actions with the lint results, for example printing something to the terminal or generate custom reports.
There are three ways to load a reporter.
### The reporter loading steps
1. Pass the name of a core reporter. See below for a complete listing.
1. If nothing is passed, a simple, default reporter will be used. This will just print all the warnings/errors found.
2. Pass the name of a Node module. If `lesshint` is installed globally only globally installed reporters are available (the normal Node module loading rules apply).
3. Pass a absolute or relative path to a custom reporter anywhere on the disk. Relative paths will be resolved against [`process.cwd()`](https://nodejs.org/api/process.html#process_process_cwd).
### Core reporters
* `stylish` - Colored print of all errors to the console.
These steps always apply, no matter whether you're using the CLI or calling `lesshint` from code.
### Using reporters from the CLI
```bash
lesshint --reporter my-super-awesome-reporter file.less
lesshint --reporter /path/to/my/super/awesome/reporter.js file.less
```
### Using reporters from code
If you're writing code which utilizes `lesshint`, for example a Gulp plugin you can use the `getReporter` method on the `lesshint` object to load a reporter using the same logic as `lesshint` does.
Pass the name of a module or a path to the `getReporter` method like this:
```js
var Lesshint = require('lesshint');
var lesshint = new Lesshint();
var reporter = lesshint.getReporter('my-super-awesome-reporter');
var errors = lesshint.checkFile('file.less');
reporter.report(errors);
```
### Writing your own reporter
In it's simplest form, a reporter is just a function accepting some input. The most basic reporter possible:
In its simplest form, a reporter is just a function accepting some input. The most basic reporter possible:
```js
module.exports = {
name: 'my-super-awesome-reporter', // Not required, but recommended
report: function (errors) {

@@ -158,7 +179,2 @@ console.log(errors.length ? 'Errors found' : 'No errors');

};
// Old usage, deprecated as of 1.2.0:
module.exports = function (errors) {
console.log(errors.length ? 'Errors found' : 'No errors');
};
```

@@ -181,4 +197,4 @@

It's then up to the reporter to do something with the errors. No `return`s or anything is needed. `lesshint` will handle everything like exit codes etc.
It's then up to the reporter to do something with the errors. No `return`s or anything is needed. If running from the CLI, `lesshint` will handle the setting of correct exit codes.
Take a look at the [default reporter](https://github.com/lesshint/lesshint/blob/master/lib/reporters/stylish.js) for more information.
Take a look at the [default reporter](https://github.com/lesshint/lesshint/blob/master/lib/reporters/default.js) for more information.

@@ -22,2 +22,13 @@ 'use strict';

it('should strip trailing slashes from directory names', function () {
var testPath = path.dirname(__dirname) + '/data/files/sub/';
var lesshint = new Lesshint();
lesshint.configure();
return lesshint.checkDirectory(testPath).then(function (result) {
expect(result[0].fullPath).to.equal(testPath + 'file.less');
});
});
it('should ignore dotfiles', function () {

@@ -176,2 +187,25 @@ var testPath = path.dirname(__dirname) + '/data/ignored-files';

});
describe('getReporter', function () {
it('should load the specified reporter', function () {
var lesshint = new Lesshint();
var reporter = lesshint.getReporter(path.resolve(process.cwd() + '/lib/reporters/default.js'));
expect(reporter.name).to.equal('default');
});
it('should load the default when nothing is passed', function () {
var lesshint = new Lesshint();
var reporter = lesshint.getReporter();
expect(reporter.name).to.equal('default');
});
it('should return false when no reporter was found', function () {
var lesshint = new Lesshint();
var reporter = lesshint.getReporter('invalid');
expect(reporter).to.be.false;
});
});
});

@@ -370,10 +370,10 @@ 'use strict';

describe('parseAST', function () {
it('should return an AST', function () {
describe('getParser', function () {
it('should return a parser promise', function () {
var source = '.foo { color: red; }';
var ast = linter.parseAST(source);
var parser = linter.getParser(source);
expect(ast).to.have.property('toString'); // If the returned object has the 'toString' method, we'll consider it a success
expect(parser).to.have.property('then'); // If the returned object has a 'then' method, we'll consider it a success
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#attributeQuotes()', function () {
it('should have the proper node types', function () {
var source = 'input[type="text"] {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow single quotes', function () {
var source = "input[type='text'] {}";
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('selector').first('attributeSelector').first('attributeValue');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -25,11 +28,8 @@

var source = 'input[type="text"] {}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('selector').first('attributeSelector').first('attributeValue');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -39,5 +39,2 @@

var source = 'input[type=text] {}';
var result;
var ast;
var expected = [{

@@ -49,10 +46,51 @@ column: 12,

ast = parseAST(source);
ast = ast.first().first('selector').first('attributeSelector').first('attributeValue');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.deep.equal(expected);
it('should not check attribute selectors without an operator', function () {
var source = 'input[required] {}';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should not check selectors without attributes', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should check all selectors in a selector group', function () {
var source = 'input[type=text], input[type=text] {}';
var expected = [
{
column: 12,
line: 1,
message: 'Attribute selectors should use quotes.'
},
{
column: 30,
line: 1,
message: 'Attribute selectors should use quotes.'
}
];
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.deep.equal(expected);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#borderZero()', function () {
it('should have the proper node types', function () {
var source = '.foo { border: none; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.first.type);
});
});
it('should allow "none" as a value when "style" is "none" and the property is "border"', function () {
var source = '.foo { border: none; }';
var result;
var ast;
var options = {

@@ -19,8 +22,7 @@ style: 'none'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -30,5 +32,2 @@

var source = '.foo { border: 0; }';
var result;
var ast;
var options = {

@@ -38,8 +37,7 @@ style: 'zero'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -49,5 +47,2 @@

var source = '.foo { border: 0; }';
var result;
var ast;
var expected = [{

@@ -63,15 +58,11 @@ column: 16,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
//
it('should not allow "none" as a value when "style" is "zero" and the property is "border"', function () {
var source = '.foo { border: none; }';
var result;
var ast;
var expected = [{

@@ -87,8 +78,7 @@ column: 16,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -98,5 +88,2 @@

var source = '.foo { border-bottom: none; }';
var result;
var ast;
var options = {

@@ -106,8 +93,7 @@ style: 'none'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -117,5 +103,2 @@

var source = '.foo { border-left: none; }';
var result;
var ast;
var options = {

@@ -125,8 +108,7 @@ style: 'none'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -136,5 +118,2 @@

var source = '.foo { border-right: none; }';
var result;
var ast;
var options = {

@@ -144,8 +123,7 @@ style: 'none'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -155,5 +133,2 @@

var source = '.foo { border-top: none; }';
var result;
var ast;
var options = {

@@ -163,8 +138,7 @@ style: 'none'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -174,5 +148,2 @@

var source = '.foo { border: 1px solid #000000; }';
var result;
var ast;
var options = {

@@ -182,8 +153,7 @@ style: 'none'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -193,5 +163,2 @@

var source = '.foo { border: 0; }';
var lint;
var ast;
var options = {

@@ -201,10 +168,10 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var node = ast.root.first.first;
var lint = spec.linter.lint.bind(null, options, node);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#comment()', function () {
it('should have the proper node types', function () {
var source = '/* Hello world */';
// returning a promise allows mocha to handle the promise natively
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow single-line comments', function () {
var source = '// Hello world';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should not allow multi-line comments', function () {
var source = '/* Hello world */';
var result;
var ast;
var expected = [{
message: "There shouldn't be any multi-line comments."
message: 'There shouldn\'t be any multi-line comments.'
}];
ast = parseAST(source);
ast = ast.first('multilineComment');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -29,5 +42,2 @@

var source = '/*! Hello world */';
var result;
var ast;
var options = {

@@ -37,10 +47,9 @@ allowed: '^!'

ast = parseAST(source);
ast = ast.first('multilineComment');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#decimalZero()', function () {
var result;
var ast;
var options;
var expected;
it('should have the proper node types', function () {
var source = 'margin-right: 1.5px;';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
describe('when "style" is "leading"', function () {

@@ -23,48 +26,45 @@ beforeEach(function () {

it('should allow "0.0"', function () {
ast = parseAST('.foo { font-size: 0.0em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 0.0em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow number without decimal zero', function () {
ast = parseAST('.foo { font-size: 1em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 1em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow number with leading decimal zero', function () {
ast = parseAST('.foo { font-size: 0.5em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 0.5em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow decimal number greater than 1 without leading zero', function () {
ast = parseAST('.foo { font-size: 1.25em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 1.25em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not allow number without leading decimal zero', function () {
expected = [{
column: 19,
var source = 'font-size: .5em;';
var expected = [{
column: 12,
line: 1,

@@ -74,15 +74,13 @@ message: '.5 should be written with leading zero.'

ast = parseAST('.foo { font-size: .5em; }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number without leading decimal zero in a function', function () {
expected = [{
column: 29,
var source = 'color: rgba(0, 0, 0, .5);';
var expected = [{
column: 22,
line: 1,

@@ -92,12 +90,9 @@ message: '.5 should be written with leading zero.'

ast = parseAST('.foo { color: rgba(0, 0, 0, .5); }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});//"leading"
}); //"leading"

@@ -112,37 +107,35 @@ describe('when "style" is "trailing"', function () {

it('should allow "0.0"', function () {
ast = parseAST('.foo { font-size: 0.0em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 0.0em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow number without decimal', function () {
ast = parseAST('.foo { font-size: 1em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 1em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow number with trailing decimal zero', function () {
ast = parseAST('.foo { font-size: 1.0em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 1.0em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not allow number without trailing decimal zero', function () {
expected = [{
column: 19,
var source = 'font-size: 1.5em;';
var expected = [{
column: 12,
line: 1,

@@ -152,15 +145,13 @@ message: '1.5 should be written with trailing zero.'

ast = parseAST('.foo { font-size: 1.5em; }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number without trailing decimal zero in a function', function () {
expected = [{
column: 29,
var source = 'color: rgba(0, 0, 0, 0.1);';
var expected = [{
column: 22,
line: 1,

@@ -170,12 +161,9 @@ message: '0.1 should be written with trailing zero.'

ast = parseAST('.foo { color: rgba(0, 0, 0, 0.1); }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});//"trailing"
}); //"trailing"

@@ -190,26 +178,25 @@ describe('when "style" is "both"', function () {

it('should allow "0.0"', function () {
ast = parseAST('.foo { font-size: 0.0em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 0.0em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow decimal number greater than 1 without leading zero', function () {
ast = parseAST('.foo { font-size: 1.250em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 1.250em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not allow number without trailing decimal zero', function () {
expected = [{
column: 19,
var source = 'font-size: 1.5em;';
var expected = [{
column: 12,
line: 1,

@@ -219,15 +206,13 @@ message: '1.5 should be written with leading and trailing zero.'

ast = parseAST('.foo { font-size: 1.5em; }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number without trailing decimal zero in a function', function () {
expected = [{
column: 29,
var source = 'color: rgba(0, 0, 0, 1.5);';
var expected = [{
column: 22,
line: 1,

@@ -237,15 +222,13 @@ message: '1.5 should be written with leading and trailing zero.'

ast = parseAST('.foo { color: rgba(0, 0, 0, 1.5); }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number without leading decimal zero', function () {
expected = [{
column: 19,
var source = 'font-size: .50em;';
var expected = [{
column: 12,
line: 1,

@@ -255,15 +238,13 @@ message: '.50 should be written with leading and trailing zero.'

ast = parseAST('.foo { font-size: .50em; }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number without leading decimal zero in a function', function () {
expected = [{
column: 29,
var source = 'color: rgba(0, 0, 0, .50);';
var expected = [{
column: 22,
line: 1,

@@ -273,12 +254,9 @@ message: '.50 should be written with leading and trailing zero.'

ast = parseAST('.foo { color: rgba(0, 0, 0, .50); }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});//"both"
}); //"both"

@@ -293,15 +271,15 @@ describe('when "style" is "none"', function () {

it('should allow "0.0"', function () {
ast = parseAST('.foo { font-size: 0.0em; }')
.first()
.first('block')
.first('declaration');
var source = 'font-size: 0.0em;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not allow number with trailing decimal zero', function () {
expected = [{
column: 19,
var source = 'font-size: .50em;';
var expected = [{
column: 12,
line: 1,

@@ -311,15 +289,13 @@ message: '.50 should be written without leading and trailing zero.'

ast = parseAST('.foo { font-size: .50em; }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number with trailing decimal zero in a function', function () {
expected = [{
column: 29,
var source = 'color: rgba(0, 0, 0, .50);';
var expected = [{
column: 22,
line: 1,

@@ -329,15 +305,13 @@ message: '.50 should be written without leading and trailing zero.'

ast = parseAST('.foo { color: rgba(0, 0, 0, .50); }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number with leading decimal zero', function () {
expected = [{
column: 19,
var source = 'font-size: 0.5em;';
var expected = [{
column: 12,
line: 1,

@@ -347,15 +321,13 @@ message: '0.5 should be written without leading and trailing zero.'

ast = parseAST('.foo { font-size: 0.5em; }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow number with trailing decimal zero in a function', function () {
expected = [{
column: 29,
var source = 'color: rgba(0, 0, 0, 0.5);';
var expected = [{
column: 22,
line: 1,

@@ -365,12 +337,9 @@ message: '0.5 should be written without leading and trailing zero.'

ast = parseAST('.foo { color: rgba(0, 0, 0, 0.5); }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});//"none"
}); //"none"

@@ -385,15 +354,13 @@ describe('with invalid "style" value', function () {

it('should throw an error', function () {
var lint;
var source = 'font-size: 1.0em;';
ast = parseAST('.foo { font-size: 1.0em; }')
.first()
.first('block')
.first('declaration');
return spec.parse(source, function (ast) {
var node = ast.root.first.first;
var lint = spec.linter.lint.bind(null, options, node);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});//"invalid"
}); //"invalid"
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#depthLevel()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; .foo-2 { color: red; .foo-3 { width: 100%; } } }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should not allow styles nested with more than 3 levels of depth.', function () {
var source = '.foo { color: red; .foo-2 { color: red; .foo-3 { width: 100%; .foo-4 { height: 100%; } } } }';
var result;
var ast;
var expected = [{

@@ -23,7 +26,7 @@ message: "There shouldn't be more than '3' levels deep from the style's parent, check the children's depth."

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -33,5 +36,2 @@

var source = '.foo { color: red; .foo-2 { color: red; .foo-3 { width: 100%; } } }';
var result;
var ast;
var options = {

@@ -41,7 +41,7 @@ depth: 3

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -48,0 +48,0 @@ });

'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#duplicateProperty()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow single instances of each property', function () {
var source = '.foo { color: red; }';
var result;
var ast;
var options = {

@@ -19,8 +23,7 @@ exclude: []

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -30,5 +33,2 @@

var source = '.foo { color: red; color: blue; }';
var result;
var ast;
var expected = [{

@@ -44,8 +44,7 @@ column: 20,

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -55,5 +54,2 @@

var source = '.foo { color: red; color: green; }';
var result;
var ast;
var options = {

@@ -63,8 +59,7 @@ exclude: ['color']

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -74,5 +69,2 @@

var source = '.foo { color: red; color: green; }';
var result;
var ast;
var expected = [{

@@ -88,8 +80,7 @@ column: 20,

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -99,5 +90,15 @@

var source = '.foo { @a: red; @b: 3px; }';
var result;
var ast;
var options = {
exclude: []
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should ignore nested properties', function () {
var source = '.foo { color: red; .bar { color: blue; } }';
var options = {

@@ -107,10 +108,9 @@ exclude: []

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#emptyRule()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow rules with declarations', function () {
var source = '.foo { color: red; }';
var result;
var ast;
ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -25,5 +28,2 @@

var source = '.foo {}';
var result;
var ast;
var expected = [{

@@ -33,8 +33,7 @@ message: "There shouldn't be any empty rules present."

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -44,5 +43,2 @@

var source = '.foo { }';
var result;
var ast;
var expected = [{

@@ -52,8 +48,7 @@ message: "There shouldn't be any empty rules present."

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -63,13 +58,20 @@

var source = '.foo { .mixin(); }';
var result;
var ast;
ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
});
});
expect(result).to.be.undefined;
it('should not check mixin calls', function () {
var source = '.mixin();';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#finalNewline()', function () {
it('should have the proper node types', function () {
var source = '.foo { }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.type);
});
});
it('should allow files with final new lines', function () {
var source = '.foo {}\n';
var result;
var ast;
ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -24,5 +28,2 @@

var source = '.foo {}';
var result;
var ast;
var expected = [{

@@ -34,7 +35,7 @@ column: 8,

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -44,48 +45,32 @@

var source = '';
var result;
var ast;
ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should report the correct line number even for large files. #123', function () {
var source = '';
var result;
var ast;
var source = '@import "something";\n';
var i;
var expected = [{
column: 26,
line: 17,
line: 16,
message: 'Files should end with a newline.'
}];
source += '@import "something";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
source += '@import "something-else";\n';
for (i = 0; i < 14; i++) {
source += '@import "something-else";\n';
}
source += '@import "something-else";';
ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#hexLength()', function () {
it('should have the proper node types', function () {
var source = 'color: #ABC;';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should not allow short hand hex values when "style" is "long"', function () {
var source = 'color: #ABC;';
var result;
var ast;
var expected = [{

@@ -23,8 +26,7 @@ message: '#ABC should be written in the long-form format.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -34,5 +36,2 @@

var source = 'color: #AABBCC;';
var result;
var ast;
var options = {

@@ -42,8 +41,7 @@ style: 'long'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -53,5 +51,2 @@

var source = 'color: #AABBCC;';
var result;
var ast;
var expected = [{

@@ -65,8 +60,7 @@ message: '#AABBCC should be written in the short-form format.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -76,5 +70,2 @@

var source = 'color: #ABC;';
var result;
var ast;
var options = {

@@ -84,8 +75,7 @@ style: 'short'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -95,5 +85,2 @@

var source = 'color: #4B7A19;';
var result;
var ast;
var options = {

@@ -103,8 +90,7 @@ style: 'short'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -114,5 +100,2 @@

var source = 'background: url(test.png) no-repeat #AABBCC;';
var result;
var ast;
var expected = [{

@@ -126,8 +109,7 @@ message: '#AABBCC should be written in the short-form format.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -137,5 +119,2 @@

var source = '@color: #ABC;';
var result;
var ast;
var expected = [{

@@ -149,8 +128,7 @@ message: '#ABC should be written in the long-form format.'

ast = parseAST(source);
ast = ast.first().first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -160,5 +138,2 @@

var source = '@color: #AABBCC;';
var result;
var ast;
var expected = [{

@@ -172,8 +147,7 @@ message: '#AABBCC should be written in the short-form format.'

ast = parseAST(source);
ast = ast.first().first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -183,5 +157,2 @@

var source = 'color: #abc1;';
var result;
var ast;
var options = {

@@ -191,8 +162,7 @@ style: 'long'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -202,5 +172,2 @@

var source = 'color: #aabbcc;';
var lint;
var ast;
var options = {

@@ -210,10 +177,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#hexNotation()', function () {
it('should have the proper node types', function () {
var source = 'color: #AABBCC;';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should not allow uppercase hex values when "style" is "lowercase"', function () {
var source = 'color: #AABBCC;';
var result;
var ast;
var expected = [{

@@ -23,8 +26,7 @@ message: '#AABBCC should be written in lowercase.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -34,5 +36,2 @@

var source = 'color: #aabbcc;';
var result;
var ast;
var options = {

@@ -42,8 +41,7 @@ style: 'lowercase'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -53,5 +51,2 @@

var source = 'color: #aabbcc;';
var result;
var ast;
var expected = [{

@@ -65,8 +60,7 @@ message: '#aabbcc should be written in uppercase.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -76,5 +70,2 @@

var source = 'color: #AABBCC;';
var result;
var ast;
var options = {

@@ -84,8 +75,7 @@ style: 'uppercase'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -95,5 +85,2 @@

var source = 'background: url(test.png) no-repeat #AABBCC;';
var result;
var ast;
var expected = [{

@@ -107,8 +94,7 @@ message: '#AABBCC should be written in lowercase.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -118,5 +104,2 @@

var source = '@color: #AABBCC;';
var result;
var ast;
var expected = [{

@@ -130,8 +113,7 @@ message: '#AABBCC should be written in lowercase.'

ast = parseAST(source);
ast = ast.first().first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -141,5 +123,2 @@

var source = '@color: #aabbcc;';
var result;
var ast;
var expected = [{

@@ -153,8 +132,7 @@ message: '#aabbcc should be written in uppercase.'

ast = parseAST(source);
ast = ast.first().first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -164,5 +142,2 @@

var source = 'color: #123456;';
var result;
var ast;
var options = {

@@ -172,8 +147,7 @@ style: 'lowercase'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -183,5 +157,2 @@

var source = 'color: #abc1;';
var result;
var ast;
var options = {

@@ -191,8 +162,7 @@ style: 'lowercase'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -202,5 +172,2 @@

var source = 'color: #abck;';
var result;
var ast;
var options = {

@@ -210,8 +177,7 @@ style: 'lowercase'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -221,5 +187,2 @@

var source = 'color: #aabbcc;';
var lint;
var ast;
var options = {

@@ -229,10 +192,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#hexValidation()', function () {
it('should have the proper node types', function () {
var source = 'color: #AABBCC;';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow valid hex values', function () {
var source = 'color: #AABBCC;';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -25,5 +28,2 @@

var source = 'color: #AABBC;';
var result;
var ast;
var expected = [{

@@ -33,8 +33,7 @@ message: 'Hexadecimal color "#AABBC" should be either three or six characters long.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -44,5 +43,2 @@

var source = 'background: url(test.png) no-repeat #AABBC;';
var result;
var ast;
var expected = [{

@@ -52,8 +48,7 @@ message: 'Hexadecimal color "#AABBC" should be either three or six characters long.'

ast = parseAST(source);
ast = ast.first('declaration').first('value').first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -63,5 +58,2 @@

var source = '@color: #AABBC;';
var result;
var ast;
var expected = [{

@@ -71,10 +63,9 @@ message: 'Hexadecimal color "#AABBC" should be either three or six characters long.'

ast = parseAST(source);
ast = ast.first().first('color');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#idSelector()', function () {
it('should have the proper node types', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow selectors without IDs', function () {
var source = '.foo {}';
var result;
var ast;
var options = {

@@ -19,8 +22,7 @@ exclude: []

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -30,5 +32,2 @@

var source = '.foo #bar {}';
var result;
var ast;
var expected = [{

@@ -44,8 +43,33 @@ column: 6,

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.deep.equal(expected);
it('should not allow IDs in multiple selectors for a rule', function () {
var source = '.foo #bar, .baz #qux {}';
var expected = [
{
column: 6,
line: 1,
message: 'Selectors should not use IDs.'
},
{
column: 17,
line: 1,
message: 'Selectors should not use IDs.'
}
];
var options = {
exclude: []
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
});

@@ -55,5 +79,2 @@

var source = '#foo {}';
var result;
var ast;
var options = {

@@ -63,8 +84,7 @@ exclude: ['foo']

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -74,5 +94,2 @@

var source = '#foo {}';
var result;
var ast;
var options = {

@@ -82,8 +99,7 @@ exclude: ['#foo']

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -93,5 +109,2 @@

var source = '.foo #bar {}';
var result;
var ast;
var expected = [{

@@ -107,10 +120,9 @@ column: 6,

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#importPath()', function () {
it('should have the proper node types', function () {
var source = '@import "foo";';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow filename without extension when "filenameExtension" is "false"', function () {
var source = '@import "foo";';
var result;
var ast;
var options = {

@@ -20,8 +23,7 @@ filenameExtension: false,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -31,5 +33,2 @@

var source = '@import "foo.css";';
var result;
var ast;
var options = {

@@ -40,8 +39,7 @@ filenameExtension: false,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -51,5 +49,2 @@

var source = '@import "foo.less";';
var result;
var ast;
var expected = [{

@@ -66,8 +61,7 @@ column: 9,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -77,5 +71,2 @@

var source = '@import "foo.less";';
var result;
var ast;
var options = {

@@ -86,8 +77,7 @@ filenameExtension: true,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -97,5 +87,2 @@

var source = '@import "foo";';
var result;
var ast;
var expected = [{

@@ -112,8 +99,7 @@ column: 9,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -123,5 +109,2 @@

var source = '@import "foo";';
var result;
var ast;
var options = {

@@ -132,8 +115,7 @@ leadingUnderscore: false,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -143,5 +125,2 @@

var source = '@import "_foo";';
var result;
var ast;
var expected = [{

@@ -158,8 +137,7 @@ column: 9,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -169,5 +147,2 @@

var source = '@import "_foo";';
var result;
var ast;
var options = {

@@ -178,8 +153,7 @@ leadingUnderscore: true,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -189,5 +163,2 @@

var source = '@import "foo";';
var result;
var ast;
var expected = [{

@@ -204,8 +175,7 @@ column: 9,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -215,5 +185,2 @@

var source = '@import "_foo.less";';
var result;
var ast;
var expected = [

@@ -238,8 +205,7 @@ {

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -249,5 +215,2 @@

var source = '@import "_foo.less";';
var result;
var ast;
var options = {

@@ -259,8 +222,7 @@ filenameExtension: true,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -270,5 +232,2 @@

var source = '@import url("foo.less");';
var result;
var ast;
var expected = [{

@@ -285,8 +244,7 @@ column: 13,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -296,5 +254,2 @@

var source = '@import url(foo.less);';
var result;
var ast;
var expected = [{

@@ -311,8 +266,7 @@ column: 13,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -322,4 +276,2 @@

var source = '@import "http://example.com/foo.css";';
var result;
var ast;
var options = {

@@ -332,8 +284,7 @@ importPath: {

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -343,5 +294,2 @@

var source = '@import url("http://example.com/foo.css");';
var result;
var ast;
var options = {

@@ -352,8 +300,7 @@ filenameExtension: false,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -363,5 +310,2 @@

var source = '@import "foo.less";';
var result;
var ast;
var options = {

@@ -372,8 +316,7 @@ filenameExtension: false,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -383,13 +326,10 @@

var source = '@charset "UTF-8";';
var result;
var ast;
ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#importantRule()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should not do anything when there is no !important present', function () {
var source = '.foo { color: red; }';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -25,7 +28,4 @@

var source = '.foo { color: red !important; }';
var result;
var ast;
var expected = [{
column: 19,
column: 8,
line: 1,

@@ -35,10 +35,9 @@ message: '!important should not be used.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#propertyOrdering()', function () {
it('should have the proper node types', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow blocks with only one property', function () {
var source = '.foo { color: red; }';
var result;
var ast;
var options = {

@@ -19,8 +22,7 @@ style: 'alpha'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -30,5 +32,2 @@

var source = '.foo { color: red; padding-top: 4px; right: 5px}';
var result;
var ast;
var options = {

@@ -38,8 +37,7 @@ style: 'alpha'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -49,5 +47,2 @@

var source = '.foo { padding-top: 4px; color: red; right: 5px}';
var result;
var ast;
var expected = [{

@@ -63,8 +58,7 @@ column: 26,

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -74,5 +68,2 @@

var source = '.foo { color: red; color: blue; }';
var result;
var ast;
var options = {

@@ -82,8 +73,7 @@ style: 'alpha'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -93,5 +83,2 @@

var source = '.foo { @var: auto; }';
var result;
var ast;
var options = {

@@ -101,8 +88,7 @@ style: 'alpha'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -112,5 +98,2 @@

var source = '.foo { @var: auto; }';
var result;
var ast;
var options = {

@@ -120,8 +103,7 @@ style: 'alpha'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});

@@ -131,5 +113,2 @@

var source = '.foo { color: red; color: blue; }';
var lint;
var ast;
var options = {

@@ -139,10 +118,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#propertyUnits()', function () {
it('should have the proper node types', function () {
var source = 'font-size: 1rem;';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow allowed valid unit', function () {
var source = '.foo { font-size: 1rem; }';
var result;
var ast;
var source = 'font-size: 1rem;';
var options = {

@@ -20,15 +23,11 @@ properties: {},

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow valid property unit', function () {
var source = '.foo { font-size: 1rem; }';
var result;
var ast;
var source = 'font-size: 1rem;';
var options = {

@@ -41,17 +40,13 @@ properties: {

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not allow an unspecified unit', function () {
var source = '.foo { font-size: 1rem; }';
var result;
var ast;
var source = 'font-size: 1rem;';
var expected = [{
column: 19,
column: 12,
line: 1,

@@ -66,17 +61,13 @@ message: 'Unit "rem" is not allowed for "font-size".'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow an unspecified property unit', function () {
var source = '.foo { font-size: 1rem; }';
var result;
var ast;
var source = 'font-size: 1rem;';
var expected = [{
column: 19,
column: 12,
line: 1,

@@ -93,17 +84,13 @@ message: 'Unit "rem" is not allowed for "font-size".'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow any units when no valid units are passed', function () {
var source = '.foo { line-height: 24px; }';
var result;
var ast;
var source = 'line-height: 24px;';
var expected = [{
column: 21,
column: 14,
line: 1,

@@ -118,17 +105,13 @@ message: 'Unit "px" is not allowed for "line-height".'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow any units when no property units are passed', function () {
var source = '.foo { line-height: 24px; }';
var result;
var ast;
var source = 'line-height: 24px;';
var expected = [{
column: 21,
column: 14,
line: 1,

@@ -145,15 +128,11 @@ message: 'Unit "px" is not allowed for "line-height".'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should allow percentages when set as a valid unit', function () {
var source = '.foo { font-size: 100%; }';
var result;
var ast;
var source = 'font-size: 100%;';
var options = {

@@ -164,15 +143,11 @@ properties: {},

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should allow percentages when set as a valid property unit', function () {
var source = '.foo { font-size: 100%; }';
var result;
var ast;
var source = 'font-size: 100%;';
var options = {

@@ -185,19 +160,15 @@ properties: {

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not allow percentages when set as an invalid unit', function () {
var source = '.foo { font-size: 100%; }';
var result;
var ast;
var source = 'font-size: 100%;';
var expected = [{
column: 19,
column: 12,
line: 1,
message: 'Percentages are not allowed for "font-size".'
message: 'Unit "%" is not allowed for "font-size".'
}];

@@ -210,19 +181,15 @@

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow percentages when set as an invalid property unit', function () {
var source = '.foo { font-size: 100%; }';
var result;
var ast;
var source = 'font-size: 100%;';
var expected = [{
column: 19,
column: 12,
line: 1,
message: 'Percentages are not allowed for "font-size".'
message: 'Unit "%" is not allowed for "font-size".'
}];

@@ -237,17 +204,13 @@

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow an invalid unit', function () {
var source = '.foo { font-size: 1px; }';
var result;
var ast;
var source = 'font-size: 1px;';
var expected = [{
column: 19,
column: 12,
line: 1,

@@ -262,17 +225,13 @@ message: 'Unit "px" is not allowed for "font-size".'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow an invalid unit that overrides a valid unit', function () {
var source = '.foo { font-size: 1px; }';
var result;
var ast;
var source = 'font-size: 1px;';
var expected = [{
column: 19,
column: 12,
line: 1,

@@ -288,17 +247,13 @@ message: 'Unit "px" is not allowed for "font-size".'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow an invalid unit that has been specified valid for a property', function () {
var source = '.foo { font-size: 1px; }';
var result;
var ast;
var source = 'font-size: 1px;';
var expected = [{
column: 19,
column: 12,
line: 1,

@@ -315,23 +270,29 @@ message: 'Unit "px" is not allowed for "font-size".'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.deep.equal(expected);
it('should not check properties without a unit', function () {
var source = 'line-height: 1.5;';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should return null on variable declaration', function () {
var source = '.foo { @var-name: 12px; }';
var result;
var ast;
it('should return undefined on variable declaration', function () {
var source = '@var-name: 12px;';
ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.equal(null);
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#qualifyingElement()', function () {
it('should have the proper node types', function () {
var source = 'input[type="text"] {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow selectors without any qualifying element', function () {
var source = '.foo {}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -25,5 +28,2 @@

var source = 'div#foo {}';
var result;
var ast;
var expected = [{

@@ -35,8 +35,7 @@ column: 4,

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -46,5 +45,2 @@

var source = 'div.foo {}';
var result;
var ast;
var expected = [{

@@ -56,8 +52,7 @@ column: 4,

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -67,5 +62,2 @@

var source = 'div[foo="bar"] {}';
var result;
var ast;
var expected = [{

@@ -77,8 +69,7 @@ column: 4,

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -88,5 +79,2 @@

var source = 'div#foo {}';
var result;
var ast;
var options = {

@@ -96,8 +84,7 @@ allowWithId: true

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -107,5 +94,2 @@

var source = 'div.foo {}';
var result;
var ast;
var options = {

@@ -115,8 +99,7 @@ allowWithClass: true

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -126,5 +109,2 @@

var source = 'div[foo="bar"] {}';
var result;
var ast;
var options = {

@@ -134,8 +114,7 @@ allowWithAttribute: true

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -145,5 +124,2 @@

var source = '.foo div.bar {}';
var result;
var ast;
var expected = [{

@@ -155,8 +131,7 @@ column: 9,

ast = parseAST(source);
ast = ast.first().first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -166,7 +141,4 @@

var source = 'a { &.active { color: red; } }';
var result;
var ast;
var expected = [{
column: 6,
column: 2,
line: 1,

@@ -176,10 +148,9 @@ message: 'Class selectors should not include a qualifying element.'

ast = parseAST(source);
ast = ast.first().first('block').first('ruleset').first('selector');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#selectorNaming()', function () {
var result;
var ast;
var options;
it('should have the proper node types', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should skip selector without name', function () {
ast = parseAST('[type="text"] {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
var source = '[type="text"] {}';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should check for lowercase', function () {
options = {
var source = '.fooBar {}';
var expected = [{
column: 1,
line: 1,
message: 'Selector "fooBar" should follow naming conventions.'
}];
var options = {
disallowUppercase: true
};
ast = parseAST('.fooBar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
});
it('should check for underscore', function () {
options = {
var source = '.foo_bar {}';
var expected = [{
column: 1,
line: 1,
message: 'Selector "foo_bar" should follow naming conventions.'
}];
var options = {
disallowUnderscore: true
};
ast = parseAST('.foo_bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
});
it('should check for dash', function () {
options = {
var source = '.foo-bar {}';
var expected = [{
column: 1,
line: 1,
message: 'Selector "foo-bar" should follow naming conventions.'
}];
var options = {
disallowDash: true
};
ast = parseAST('.foo-bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
});
it('should allow exceptions with exclude', function () {
options = {
var source = '.foo-bar {}';
var options = {
disallowDash: true,

@@ -60,96 +89,46 @@ exclude: ['foo-bar']

ast = parseAST('.foo-bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
describe('combinations', function () {
it('should approximate "camelCase" style', function () {
options = {
disallowDash: true,
disallowUnderscore: true
};
ast = parseAST('.foo-bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
ast = parseAST('.foo_bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
ast = parseAST('.fooBar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
ast = parseAST('.FooBar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
});
it('should approximate "snake_case" style', function () {
options = {
disallowDash: true
};
it('should handle approximate "camelCase" style', function () {
var source = '.foo-bar {}';
var expected = [{
column: 1,
line: 1,
message: 'Selector "foo-bar" should follow naming conventions.'
}];
ast = parseAST('.foo-bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
var options = {
disallowDash: true,
disallowUnderscore: true
};
ast = parseAST('.foo_bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
options = {
disallowDash: true,
disallowUppercase: true
};
ast = parseAST('.foo_Bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
ast = parseAST('.foo_bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.deep.equal(expected);
});
});
it('should approximate "train-case" style', function () {
options = {
disallowDash: true
};
it('should handle approximate "snake_case" style', function () {
var source = '.fooBar {}';
var expected = [{
column: 1,
line: 1,
message: 'Selector "fooBar" should follow naming conventions.'
}];
ast = parseAST('.foo-bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
var options = {
disallowDash: true,
disallowUppercase: true
};
ast = parseAST('.foo_bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
options = {
disallowDash: true,
disallowUppercase: true
};
ast = parseAST('.foo_Bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result.length).to.equal(1);
ast = parseAST('.foo_bar {}');
ast = ast.first().first('selector');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.deep.equal(expected);
});

@@ -156,0 +135,0 @@ });

'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#singleLinePerProperty()', function () {
it('should have the proper node types', function () {
var source = '.foo {\n color: red; \n margin-right: 10px; \n}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow properties on separate lines', function () {
var source = '.foo {\n color: red; \n margin-right: 10px; \n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -25,24 +28,13 @@

var source = '.foo {\n color: red; margin-right: 10px; \n}';
var result;
var ast;
var expected = [{
column: 14,
line: 2,
message: 'Each property should be on its own line.'
}];
var expected = [
{
column: 2,
line: 2,
message: 'Each property should be on its own line.'
},
{
column: 14,
line: 2,
message: 'Each property should be on its own line.'
}
];
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -52,5 +44,2 @@

var source = '.foo { color: red; }';
var result;
var ast;
var expected = [{

@@ -62,8 +51,7 @@ column: 8,

ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -73,5 +61,2 @@

var source = '.foo {color: red;}';
var result;
var ast;
var expected = [{

@@ -83,8 +68,7 @@ column: 7,

ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -94,11 +78,8 @@

var source = '.foo {\n.mixin(); \n.mixin2(); \n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -108,5 +89,2 @@

var source = '.foo {.mixin();}';
var result;
var ast;
var expected = [{

@@ -118,8 +96,7 @@ column: 7,

ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -129,11 +106,8 @@

var source = '.foo {\n@var1: 10px; \n@var2: 20px; \n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -143,5 +117,2 @@

var source = '.foo {@var1: 10px;}';
var result;
var ast;
var expected = [{

@@ -153,8 +124,7 @@ column: 7,

ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -164,11 +134,8 @@

var source = '.foo {\n@ruleset1(); \n@ruleset2(); \n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -178,5 +145,2 @@

var source = '.foo {@ruleset();}';
var result;
var ast;
var expected = [{

@@ -188,8 +152,7 @@ column: 7,

ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -199,5 +162,2 @@

var source = '.foo { color: red; \n margin-right: 10px; \n}';
var result;
var ast;
var expected = [{

@@ -209,8 +169,7 @@ column: 8,

ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -220,5 +179,2 @@

var source = '.foo {\n color: red; \n margin-right: 10px; }';
var result;
var ast;
var expected = [{

@@ -230,8 +186,7 @@ column: 2,

ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -241,11 +196,8 @@

var source = '.foo {\n color: red;\n margin-right: 10px; // inline comment\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -255,11 +207,8 @@

var source = '.foo {\n color: red;\n margin-right: 10px;// inline comment\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -269,11 +218,8 @@

var source = '.foo {\n color: red;\n margin-right: 10px; /* inline comment */\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -283,11 +229,8 @@

var source = '.foo {\n color: red;\n margin-right: 10px;/* inline comment */\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -297,24 +240,13 @@

var source = '.foo {\n color: red; margin-right: 10px; // inline comment\n}';
var result;
var ast;
var expected = [{
column: 14,
line: 2,
message: 'Each property should be on its own line.'
}];
var expected = [
{
column: 2,
line: 2,
message: 'Each property should be on its own line.'
},
{
column: 14,
line: 2,
message: 'Each property should be on its own line.'
}
];
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -324,24 +256,13 @@

var source = '.foo {\n color: red; margin-right: 10px; /* inline comment */\n}';
var result;
var ast;
var expected = [{
column: 14,
line: 2,
message: 'Each property should be on its own line.'
}];
var expected = [
{
column: 2,
line: 2,
message: 'Each property should be on its own line.'
},
{
column: 14,
line: 2,
message: 'Each property should be on its own line.'
}
];
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -351,11 +272,8 @@

var source = 'section {\n@media (min-width: 300px) {\nfont-size: inherit;\n}\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -365,11 +283,8 @@

var source = '.foo {\ncolor: red\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -379,45 +294,30 @@

var source = '.foo {\n.bar.baz();\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not allow closing brace on the same line as a property', function () {
var source = '.foo {\n color: red;}';
var result;
var ast;
it('should not report mixins without a trailing semicolon. #132', function () {
var source = '.foo {\n .bar\n}';
var expected = [{
column: 2,
line: 2,
message: 'Each property should be on its own line.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.be.undefined;
});
});
it('should not report mixins without a trailing semicolon. #132', function () {
var source = '.foo {\n .bar\n}';
var result;
var ast;
it('should not check mixin calls', function () {
var source = '.mixin();';
ast = parseAST(source);
ast = ast.first('ruleset').first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#singleLinePerSelector()', function () {
it('should have the proper node types', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow selectors on separate lines', function () {
var source = '.foo, \n.bar {}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -25,17 +28,20 @@

var source = '.foo, .bar {}';
var result;
var ast;
var expected = [
{
column: 1,
line: 1,
message: 'Each selector should be on its own line.'
},
{
column: 7,
line: 1,
message: 'Each selector should be on its own line.'
}
];
var expected = [{
column: 6,
line: 1,
message: 'Each selector should be on its own line.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
ast = parseAST(source);
ast = ast.first('ruleset');
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -45,11 +51,8 @@

var source = '.foo\n,.bar {}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first('ruleset');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -59,5 +62,2 @@

var source = '.foo, .bar {}';
var result;
var ast;
var options = {

@@ -67,8 +67,7 @@ style: '18f'

ast = parseAST(source);
ast = ast.first('ruleset');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -78,5 +77,2 @@

var source = '.foobar, .bar {}';
var result;
var ast;
var options = {

@@ -87,3 +83,3 @@ style: '18f'

var expected = [{
column: 9,
column: 10,
line: 1,

@@ -93,10 +89,19 @@ message: 'Each selector should be on its own line.'

ast = parseAST(source);
ast = ast.first('ruleset');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.deep.equal(expected);
it('should not report single selectors', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#spaceAfterPropertyColon()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.first.type);
});
});
it('should allow one space when "style" is "at_least_one_space"', function () {
var source = '.foo { color: red; }';
var result;
var ast;
var options = {

@@ -19,8 +22,7 @@ style: 'at_least_one_space'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -30,5 +32,2 @@

var source = '.foo { color:red; }';
var result;
var ast;
var expected = [{

@@ -44,8 +43,7 @@ column: 14,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -55,5 +53,2 @@

var source = '.foo { color: red; }';
var result;
var ast;
var options = {

@@ -63,8 +58,7 @@ style: 'at_least_one_space'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -74,5 +68,2 @@

var source = '.foo { color: red; }';
var result;
var ast;
var options = {

@@ -82,8 +73,7 @@ style: 'one_space'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -93,5 +83,2 @@

var source = '.foo { color:red; }';
var result;
var ast;
var expected = [{

@@ -107,8 +94,7 @@ column: 14,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -118,5 +104,2 @@

var source = '.foo { color: red; }';
var result;
var ast;
var expected = [{

@@ -132,8 +115,7 @@ column: 14,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -143,5 +125,2 @@

var source = '.foo { color:red; }';
var result;
var ast;
var options = {

@@ -151,8 +130,7 @@ style: 'no_space'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -162,5 +140,2 @@

var source = '.foo { color: red; }';
var result;
var ast;
var expected = [{

@@ -176,8 +151,7 @@ column: 14,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -187,5 +161,2 @@

var source = '.foo { color: red; }';
var result;
var ast;
var expected = [{

@@ -201,8 +172,7 @@ column: 14,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -212,5 +182,2 @@

var source = '.foo { color:red; }';
var lint;
var ast;
var options = {

@@ -220,10 +187,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#spaceAfterPropertyName()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.first.type);
});
});
it('should allow a missing space when "style" is "no_space"', function () {
var source = '.foo { color: red; }';
var result;
var ast;
var options = {

@@ -19,8 +22,8 @@ style: 'no_space'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
expect(result).to.be.undefined;
});

@@ -30,5 +33,2 @@

var source = '.foo { color : red; }';
var result;
var ast;
var expected = [{

@@ -44,8 +44,7 @@ column: 13,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -55,5 +54,2 @@

var source = '.foo { color : red; }';
var result;
var ast;
var options = {

@@ -63,8 +59,7 @@ style: 'one_space'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -74,5 +69,2 @@

var source = '.foo { color: red; }';
var result;
var ast;
var expected = [{

@@ -88,8 +80,7 @@ column: 13,

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -99,5 +90,2 @@

var source = '.foo { color:red; }';
var lint;
var ast;
var options = {

@@ -107,10 +95,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#spaceAfterPropertyValue()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.first.type);
});
});
it('should allow a missing space when "style" is "no_space"', function () {
var source = '.foo { color: red; }';
var result;
var ast;
var options = {

@@ -19,8 +22,7 @@ style: 'no_space'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -30,5 +32,2 @@

var source = '.foo { color: red ; }';
var result;
var ast;
var expected = [{

@@ -44,8 +43,7 @@ column: 18,

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -55,5 +53,2 @@

var source = '.foo { color: red ; }';
var result;
var ast;
var options = {

@@ -63,8 +58,7 @@ style: 'one_space'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -74,7 +68,4 @@

var source = '.foo { color: red; }';
var result;
var ast;
var expected = [{
column: 8,
column: 18,
line: 1,

@@ -88,75 +79,12 @@ message: 'Semicolon after property value should be preceded by one space.'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not allow any space on multiple property values when "style" is "no_space"', function () {
var source = '.foo { color: red ; margin-right: 10px ; }';
var result;
var ast;
var expected = [
{
column: 18,
line: 1,
message: 'Semicolon after property value should not be preceded by any space.',
},
{
column: 39,
line: 1,
message: 'Semicolon after property value should not be preceded by any space.'
}
];
var options = {
style: 'no_space'
};
ast = parseAST(source);
ast = ast.first().first('block');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow a missing space on multiple property values when "style" is "one_space"', function () {
var source = '.foo { color: red; margin-right: 10px; }';
var result;
var ast;
var expected = [
{
column: 8,
line: 1,
message: 'Semicolon after property value should be preceded by one space.'
},
{
column: 20,
line: 1,
message: 'Semicolon after property value should be preceded by one space.'
}
];
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first().first('block');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should throw on invalid "style" value', function () {
var source = '.foo { color: red ; }';
var lint;
var ast;
var options = {

@@ -166,10 +94,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#spaceAroundComma', function () {
it('should allow one space after comma when "style" is "after"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
var options;
var options = {
style: 'after'
};
it('should have the proper node types', function () {
var source = 'color: rgb(255, 255, 255);';
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should not allow missing space after comma when "style" is "after"', function () {
var source = '.foo { color: rgb(255,255,255); }';
var result;
var ast;
describe('when "style" is "after"', function () {
beforeEach(function () {
options = {
style: 'after'
};
});
var expected = [
{
column: 23,
line: 1,
message: 'Commas should be followed by one space.'
},
{
column: 27,
line: 1,
message: 'Commas should be followed by one space.'
}
];
it('should allow one space after comma', function () {
var source = 'color: rgb(255, 255, 255);';
var options = {
style: 'after'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.be.undefined;
});
});
result = linter.lint(options, ast);
it('should not allow missing space after comma', function () {
var source = 'color: rgb(255,255,255);';
var expected = [
{
column: 15,
message: 'Commas should be followed by one space.'
},
{
column: 19,
message: 'Commas should be followed by one space.'
}
];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should allow one space after comma in mixins when "style" is "after"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var options = {
style: 'after'
};
it('should allow one space after comma in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
});
expect(result).to.be.undefined;
});
it('should not allow missing space after comma in mixins', function () {
var source = '.mixin(@margin,@padding) {}';
var expected = [{
column: 15,
message: 'Commas should be followed by one space.'
}];
it('should not allow missing space after comma in mixins when "style" is "after"', function () {
var source = '.mixin(@margin,@padding) {}';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var expected = [{
column: 16,
line: 1,
message: 'Commas should be followed by one space.'
}];
expect(result).to.deep.equal(expected);
});
});
}); // "after"
var options = {
style: 'after'
};
describe('when "style" is "before"', function () {
beforeEach(function () {
options = {
style: 'before'
};
});
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
it('should allow one space before comma', function () {
var source = 'color: rgb(255 ,255 ,255);';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
expect(result).to.be.undefined;
});
});
it('should not report on operators other than commas when "style" is "after". See #49', function () {
var source = '@var: (4 /2);';
var result;
var ast;
it('should not allow missing space before comma', function () {
var source = 'color: rgb(255, 255, 255);';
var expected = [
{
column: 15,
message: 'Commas should be preceded by one space.'
},
{
column: 20,
message: 'Commas should be preceded by one space.'
}
];
var options = {
style: 'after'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('atrule').first('parentheses');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should allow one space before comma in mixins', function () {
var source = '.mixin(@margin ,@padding) {}';
expect(result).to.be.undefined;
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should allow one space before comma when "style" is "before"', function () {
var source = '.foo { color: rgb(255 ,255 ,255); }';
var result;
var ast;
expect(result).to.be.undefined;
});
});
var options = {
style: 'before'
};
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not allow missing space before comma when "style" is "before"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
var expected = [
{
column: 19,
line: 1,
it('should not allow missing space before comma in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
var expected = [{
column: 15,
message: 'Commas should be preceded by one space.'
},
{
column: 24,
line: 1,
message: 'Commas should be preceded by one space.'
}
];
}];
var options = {
style: 'before'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
}); // "before"
result = linter.lint(options, ast);
describe('when "style" is "both"', function () {
beforeEach(function () {
options = {
style: 'both'
};
});
expect(result).to.deep.equal(expected);
});
it('should allow one space before and after comma', function () {
var source = 'color: rgb(255 , 255 , 255);';
it('should allow one space before comma in mixins when "style" is "before"', function () {
var source = '.mixin(@margin ,@padding) {}';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'before'
};
expect(result).to.be.undefined;
});
});
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
it('should not allow missing space before comma', function () {
var source = 'color: rgb(255, 255, 255);';
var expected = [
{
column: 15,
message: 'Commas should be preceded and followed by one space.'
},
{
column: 20,
message: 'Commas should be preceded and followed by one space.'
}
];
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
expect(result).to.deep.equal(expected);
});
});
it('should not allow missing space before comma in mixins when "style" is "before"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
it('should not allow missing space after comma', function () {
var source = 'color: rgb(255 ,255 ,255);';
var expected = [
{
column: 16,
message: 'Commas should be preceded and followed by one space.'
},
{
column: 21,
message: 'Commas should be preceded and followed by one space.'
}
];
var expected = [{
column: 8,
line: 1,
message: 'Commas should be preceded by one space.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'before'
};
expect(result).to.deep.equal(expected);
});
});
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
it('should not allow missing space before and after comma', function () {
var source = 'color: rgb(255,255,255);';
var expected = [
{
column: 15,
message: 'Commas should be preceded and followed by one space.'
},
{
column: 19,
message: 'Commas should be preceded and followed by one space.'
}
];
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
expect(result).to.deep.equal(expected);
});
});
it('should not report on operators other than commas when "style" is "before". See #49', function () {
var source = '@var: (4/ 2);';
var result;
var ast;
it('should allow one space before and after comma in mixins', function () {
var source = '.mixin(@margin , @padding) {}';
var options = {
style: 'before'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('atrule').first('parentheses');
expect(result).to.be.undefined;
});
});
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should allow one space before and after comma when "style" is "both"', function () {
var source = '.foo { color: rgb(255 , 255 , 255); }';
var result;
var ast;
var options = {
style: 'both'
};
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not allow missing space before comma when "style" is "both"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
var expected = [
{
column: 19,
line: 1,
it('should not allow missing space before comma in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
var expected = [{
column: 15,
message: 'Commas should be preceded and followed by one space.'
},
{
column: 24,
line: 1,
message: 'Commas should be preceded and followed by one space.'
}
];
}];
var options = {
style: 'both'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow missing space after comma when "style" is "both"', function () {
var source = '.foo { color: rgb(255 ,255 ,255); }';
var result;
var ast;
var expected = [
{
column: 24,
line: 1,
it('should not allow missing space after comma in mixins', function () {
var source = '.mixin(@margin ,@padding) {}';
var expected = [{
column: 16,
message: 'Commas should be preceded and followed by one space.'
},
{
column: 29,
line: 1,
message: 'Commas should be preceded and followed by one space.'
}
];
}];
var options = {
style: 'both'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
}); // "both"
result = linter.lint(options, ast);
describe('when "style" is "none"', function () {
beforeEach(function () {
options = {
style: 'none'
};
});
expect(result).to.deep.equal(expected);
});
it('should allow a missing space after comma', function () {
var source = 'color: rgb(255,255,255);';
it('should allow one space before and after comma in mixins when "style" is "both"', function () {
var source = '.mixin(@margin , @padding) {}';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'both'
};
expect(result).to.be.undefined;
});
});
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
it('should not allow one space after comma', function () {
var source = 'color: rgb(255, 255, 255);';
var expected = [
{
column: 15,
message: 'Commas should not be preceded nor followed by any space.'
},
{
column: 20,
message: 'Commas should not be preceded nor followed by any space.'
}
];
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
expect(result).to.deep.equal(expected);
});
});
it('should not allow missing space before comma in mixins when "style" is "both"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
it('should not allow one space before comma', function () {
var source = 'color: rgb(255 ,255 ,255);';
var expected = [
{
column: 16,
message: 'Commas should not be preceded nor followed by any space.'
},
{
column: 21,
message: 'Commas should not be preceded nor followed by any space.'
}
];
var expected = [{
column: 8,
line: 1,
message: 'Commas should be preceded and followed by one space.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'both'
};
expect(result).to.deep.equal(expected);
});
});
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
it('should not allow one space before and after comma', function () {
var source = 'color: rgb(255 , 255 , 255);';
var expected = [
{
column: 16,
message: 'Commas should not be preceded nor followed by any space.'
},
{
column: 22,
message: 'Commas should not be preceded nor followed by any space.'
}
];
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
expect(result).to.deep.equal(expected);
});
});
it('should not allow missing space after comma in mixins when "style" is "both"', function () {
var source = '.mixin(@margin ,@padding) {}';
var result;
var ast;
it('should allow a missing space after comma in mixins', function () {
var source = '.mixin(@margin,@padding) {}';
var expected = [{
column: 17,
line: 1,
message: 'Commas should be preceded and followed by one space.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'both'
};
expect(result).to.be.undefined;
});
});
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not report on operators other than commas when "style" is "both". See #49', function () {
var source = '@var: (4 / 2);';
var result;
var ast;
var options = {
style: 'both'
};
ast = parseAST(source);
ast = ast.first('atrule').first('parentheses');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not allow a missing space before comma when "style" is "none"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
var options = {
style: 'none'
};
var expected = [
{
column: 23,
line: 1,
it('should not allow one space after comma in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
var expected = [{
column: 15,
message: 'Commas should not be preceded nor followed by any space.'
},
{
column: 28,
line: 1,
message: 'Commas should not be preceded nor followed by any space.'
}
];
}];
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.deep.equal(expected);
});
it('should not allow one space before comma when "style" is "none"', function () {
var source = '.foo { color: rgb(255 ,255 ,255); }';
var result;
var ast;
var expected = [
{
column: 22,
line: 1,
it('should not allow one space before comma in mixins', function () {
var source = '.mixin(@margin ,@padding) {}';
var expected = [{
column: 16,
message: 'Commas should not be preceded nor followed by any space.'
},
{
column: 27,
line: 1,
message: 'Commas should not be preceded nor followed by any space.'
}
];
}];
var options = {
style: 'none'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
}); // "none"
result = linter.lint(options, ast);
describe('with invalid "style" value', function () {
beforeEach(function () {
options = {
style: 'invalid'
};
});
expect(result).to.deep.equal(expected);
});
it('should throw an error', function () {
var source = 'color: rgb(255 , 255 , 255);';
it('should not allow a missing space before comma in mixins when "style" is "none"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
return spec.parse(source, function (ast) {
var node = ast.root.first;
var lint = spec.linter.lint.bind(null, options, node);
var options = {
style: 'none'
};
var expected = [{
column: 16,
line: 1,
message: 'Commas should not be preceded nor followed by any space.'
}];
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow one space before comma in mixins when "style" is "none"', function () {
var source = '.mixin(@margin ,@padding) {}';
var result;
var ast;
var expected = [{
column: 15,
line: 1,
message: 'Commas should not be preceded nor followed by any space.'
}];
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not report on operators other than commas when "style" is "none". See #49', function () {
var source = '@var: (4 / 2);';
var result;
var ast;
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first('atrule').first('parentheses');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not report on operators other than commas when "style" is "one_space". See #49', function () {
var source = '@var: (4/ 2);';
var result;
var ast;
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first('atrule').first('parentheses');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should allow a missing space after comma when "style" is "none"', function () {
var source = '.foo { color: rgb(255,255,255); }';
var result;
var ast;
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not allow one space after comma when "style" is "none"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
var expected = [
{
column: 23,
line: 1,
message: 'Commas should not be preceded nor followed by any space.'
},
{
column: 28,
line: 1,
message: 'Commas should not be preceded nor followed by any space.'
}
];
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should allow a missing space after comma in mixins when "style" is "none"', function () {
var source = '.mixin(@margin,@padding) {}';
var result;
var ast;
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not allow one space after comma in mixins when "style" is "none"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
var expected = [{
column: 16,
line: 1,
message: 'Commas should not be preceded nor followed by any space.'
}];
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not report on operators other than commas when "style" is "none". See #49', function () {
var source = '@var: (4 / 2);';
var result;
var ast;
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first('atrule').first('parentheses');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should throw on invalid "style" value', function () {
var source = '.foo { color: rgb(255 , 255 , 255); }';
var lint;
var ast;
var options = {
style: 'invalid'
};
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
});
expect(lint).to.throw(Error);
});
});
}); // "invalid"
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#spaceAroundOperator', function () {
it('should allow one space before and after operator when "style" is "both"', function () {
var source = '.foo { height: calc(10px + 10px); }';
var result;
var ast;
var options;
var options = {
style: 'both'
};
it('should have the proper node types', function () {
var source = 'height: calc(10px + 10px);';
ast = parseAST(source);
ast = ast.first();
result = linter.lint(options, ast);
expect(result).to.be.undefined;
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should not allow missing space before operator when "style" is "both"', function () {
var source = '.foo { height: calc(10px+ 10px); }';
var result;
var ast;
describe('when "style" is "both"', function () {
beforeEach(function () {
options = {
style: 'both'
};
});
var expected = [{
column: 21,
line: 1,
message: 'Operators should be preceded and followed by one space.'
}];
it('should allow one space before and after operator', function () {
var source = 'height: calc(10px + 10px);';
var options = {
style: 'both'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first();
expect(result).to.be.undefined;
});
});
result = linter.lint(options, ast);
it('should not allow missing space before operator', function () {
var source = 'height: calc(10px+ 10px);';
var expected = [{
column: 20,
message: 'Operators should be preceded and followed by one space.'
}];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should not allow missing space after operator when "style" is "both"', function () {
var source = '.foo { height: calc(10px +10px); }';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var expected = [{
column: 27,
line: 1,
message: 'Operators should be preceded and followed by one space.'
}];
it('should not allow missing space after operator', function () {
var source = 'height: calc(10px +10px);';
var expected = [{
column: 22,
message: 'Operators should be preceded and followed by one space.'
}];
var options = {
style: 'both'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first();
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should not allow missing space before and after operator', function () {
var source = 'height: calc(10px+10px);';
var expected = [{
column: 20,
message: 'Operators should be preceded and followed by one space.'
}];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should allow a missing space before operator when "style" is "none"', function () {
var source = '.foo { height: calc(10px+10px); }';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var options = {
style: 'none'
};
it('should not report on negative values', function () {
var source = 'margin-left: -10px;';
ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
});
expect(result).to.be.undefined;
});
it('should not report on negative values in shorthands', function () {
var source = 'margin: -10px -1px 0px 20px;';
it('should not allow one space before operator when "style" is "none"', function () {
var source = '.foo { height: calc(10px + 10px); }';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var expected = [{
column: 25,
line: 1,
message: 'Operators should not be preceded nor followed by any space.'
}];
expect(result).to.be.undefined;
});
});
var options = {
style: 'none'
};
it('should not report on negative number at the end of the value', function () {
var source = '@foo: (@bar / 3) * -1;';
ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
});
expect(result).to.deep.equal(expected);
});
it('should not report on negative number at the end of brackets', function () {
var source = '@b: spin(@a, -2%);';
it('should allow a missing space after operator when "style" is "none"', function () {
var source = '.foo { height: calc(10px+10px); }';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'none'
};
expect(result).to.be.undefined;
});
});
ast = parseAST(source);
ast = ast.first();
it('should not report on font-size/line-height shorthand declaration', function () {
var source = 'font: 12px/1.5 Arial;';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
expect(result).to.be.undefined;
});
});
}); // "both"
it('should not allow one space after operator when "style" is "none"', function () {
var source = '.foo { height: calc(10px+ 10px); }';
var result;
var ast;
var expected = [{
column: 26,
line: 1,
message: 'Operators should not be preceded nor followed by any space.'
}];
var options = {
style: 'none'
};
ast = parseAST(source);
ast = ast.first();
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not report on commas', function () {
var source = '@var: rgb(255,255,255);';
var result;
var ast;
var options = {
style: 'both'
};
ast = parseAST(source);
ast = ast.first();
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
describe('negative numbers when calculating', function () {
it('should not report on negative number in the end of whole value', function () {
var source = '@foo: (@bar / 3) * -1;';
var result;
var ast;
var options = {
style: 'both'
describe('when "style" is "none"', function () {
beforeEach(function () {
options = {
style: 'none'
};
});
ast = parseAST(source);
ast = ast.first();
it('should allow missing space before and after operator', function () {
var source = 'height: calc(10px+10px);';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not report on negative number in the end of brackets', function () {
var source = '@b: spin(@a, -2%);';
var result;
var ast;
it('should not allow one space before operator', function () {
var source = 'height: calc(10px +10px);';
var expected = [{
column: 21,
message: 'Operators should not be preceded nor followed by any space.'
}];
var options = {
style: 'both'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first();
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.deep.equal(expected);
});
});
});
it('should not report on minus values', function () {
var source = '.foo { margin-left: -10px; }';
var result;
var ast;
it('should not allow one space after operator', function () {
var source = 'height: calc(10px+ 10px);';
var expected = [{
column: 22,
message: 'Operators should not be preceded nor followed by any space.'
}];
var options = {
style: 'both'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first();
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
describe('shorthands', function () {
it('should not allow when there is space after operator', function () {
var source = '.foo { margin: 10px - 1px 0px 20px; }';
var result;
var ast;
it('should not allow a space after operator in shorthand values', function () {
var source = 'margin: 10px - 1px 0px 20px;';
var expected = [{
column: 20,
line: 1,
column: 16,
message: 'Operators should not be preceded nor followed by any space.'
}];
var options = {
style: 'none'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first();
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
}); // "none"
it('should not report on minus shorthand values', function () {
var source = '.foo { margin:-10px -1px 0px 20px; }';
var result;
var ast;
var options = {
style: 'both'
describe('with invalid "style" value', function () {
beforeEach(function () {
options = {
style: 'invalid'
};
ast = parseAST(source);
ast = ast.first();
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not report on font-size/line-height shorthand declaration', function () {
var source = '.foo { font: 12px/1.5 Arial; }';
var result;
var ast;
it('should throw an error', function () {
var source = 'height: calc(10px+10px);';
var options = {
style: 'both'
};
return spec.parse(source, function (ast) {
var node = ast.root.first;
var lint = spec.linter.lint.bind(null, options, node);
ast = parseAST(source);
ast = ast.first();
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(lint).to.throw(Error);
});
});
});
it('should throw on invalid "style" value', function () {
var source = '.foo { height: calc(10px+10px); }';
var lint;
var ast;
var options = {
style: 'invalid'
};
ast = parseAST(source);
ast = ast.first();
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
});
}); // "invalid"
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#spaceBeforeBrace()', function () {
it('should have the proper node types', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow no space when "style" is "no_space"', function () {
var source = '.foo{}';
var result;
var ast;
var options = {

@@ -19,8 +22,7 @@ style: 'no_space'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -30,5 +32,2 @@

var source = '.foo {}';
var result;
var ast;
var expected = [{

@@ -44,8 +43,7 @@ column: 5,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -55,5 +53,2 @@

var source = '.foo {}';
var result;
var ast;
var expected = [{

@@ -69,8 +64,7 @@ column: 5,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -80,5 +74,2 @@

var source = '.foo\n{}';
var result;
var ast;
var expected = [{

@@ -94,8 +85,7 @@ column: 5,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -105,5 +95,2 @@

var source = '.foo\n\n{}';
var result;
var ast;
var expected = [{

@@ -119,8 +106,7 @@ column: 5,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -130,5 +116,2 @@

var source = '.foo {}';
var result;
var ast;
var options = {

@@ -138,8 +121,7 @@ style: 'one_space'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -149,5 +131,2 @@

var source = '.foo{}';
var result;
var ast;
var expected = [{

@@ -163,8 +142,7 @@ column: 5,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -174,5 +152,2 @@

var source = '.foo, .bar {}';
var result;
var ast;
var options = {

@@ -182,8 +157,7 @@ style: 'one_space'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -193,5 +167,2 @@

var source = '.foo, .bar{}';
var result;
var ast;
var expected = [{

@@ -207,8 +178,7 @@ column: 11,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -218,7 +188,4 @@

var source = '.foo {}';
var result;
var ast;
var expected = [{
column: 7,
column: 5,
line: 1,

@@ -232,8 +199,7 @@ message: 'Opening curly brace should be preceded by one space.'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -243,7 +209,4 @@

var source = '.foo, .bar {}';
var result;
var ast;
var expected = [{
column: 13,
column: 11,
line: 1,

@@ -257,8 +220,7 @@ message: 'Opening curly brace should be preceded by one space.'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -268,5 +230,2 @@

var source = '.foo\n{}';
var result;
var ast;
var options = {

@@ -276,8 +235,7 @@ style: 'new_line'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -287,5 +245,2 @@

var source = '.foo, .bar\n{}';
var result;
var ast;
var options = {

@@ -295,8 +250,7 @@ style: 'new_line'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -306,5 +260,2 @@

var source = '.foo\n\n{}';
var result;
var ast;
var expected = [{

@@ -320,8 +271,7 @@ column: 5,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -331,5 +281,2 @@

var source = '.foo, .bar\n\n{}';
var result;
var ast;
var expected = [{

@@ -345,8 +292,7 @@ column: 11,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -356,5 +302,2 @@

var source = '.foo(){}';
var result;
var ast;
var expected = [{

@@ -370,8 +313,7 @@ column: 7,

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -381,5 +323,2 @@

var source = '@media screen and (max-width: 480px){}';
var result;
var ast;
var expected = [{

@@ -395,8 +334,7 @@ column: 37,

ast = parseAST(source);
ast = ast.first('atrule');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -406,5 +344,2 @@

var source = '.class { color: red; @media screen and (max-width: 480px){} }';
var result;
var ast;
var expected = [{

@@ -420,8 +355,7 @@ column: 58,

ast = parseAST(source);
ast = ast.first().first('block').first('atrule');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first.next());
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -431,5 +365,2 @@

var source = '.foo();';
var result;
var ast;
var options = {

@@ -439,8 +370,7 @@ style: 'one_space'

ast = parseAST(source);
ast = ast.first('mixin');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -450,5 +380,2 @@

var source = '.foo{}';
var lint;
var ast;
var options = {

@@ -458,10 +385,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first();
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#spaceBetweenParens()', function () {
it('should allow missing space after opening parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
var options;
var options = {
style: 'no_space'
};
it('should have the proper node types', function () {
var source = 'color: rgb(255, 255, 255);';
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow missing space before closing parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
it('should not check other rules than mixins', function () {
var source = '.foo {}';
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.be.undefined;
});
});
result = linter.lint(options, ast);
describe('when "style" is "no_space"', function () {
beforeEach(function () {
options = {
style: 'no_space'
};
});
expect(result).to.be.undefined;
});
it('should allow missing space after opening parenthesis', function () {
var source = 'color: rgb(255, 255, 255);';
it('should allow missing space after opening parenthesis and before closing parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'no_space'
};
expect(result).to.be.undefined;
});
});
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
it('should allow missing space before closing parenthesis', function () {
var source = 'color: rgb(255, 255, 255);';
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
expect(result).to.be.undefined;
});
});
it('should not allow one space after opening parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255); }';
var result;
var ast;
it('should allow missing space after opening parenthesis and before closing parenthesis', function () {
var source = 'color: rgb(255, 255, 255);';
var expected = [{
column: 19,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'no_space'
};
expect(result).to.be.undefined;
});
});
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
it('should not allow one space after opening parenthesis', function () {
var source = 'color: rgb( 255, 255, 255);';
var expected = [{
column: 12,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
}];
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
expect(result).to.deep.equal(expected);
});
});
it('should not allow one space before closing parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb(255, 255, 255 ); }';
var result;
var ast;
it('should not allow one space before closing parenthesis', function () {
var source = 'color: rgb(255, 255, 255 );';
var expected = [{
column: 25,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
var expected = [{
column: 32,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'no_space'
};
expect(result).to.deep.equal(expected);
});
});
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
it('should not allow one space after opening parenthesis and before closing parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
var expected = [
{
column: 12,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
column: 26,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
expect(result).to.deep.equal(expected);
});
});
it('should not allow one space after opening parenthesis and before closing parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
var expected = [
{
column: 19,
it('should not allow multiple spaces after opening parenthesis', function () {
var source = 'color: rgb( 255, 255, 255);';
var expected = [{
column: 12,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
column: 33,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
}];
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should not allow multiple spaces before closing parenthesis', function () {
var source = 'color: rgb(255, 255, 255 );';
var expected = [{
column: 25,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should not allow multiple spaces after opening parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255); }';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var expected = [{
column: 19,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
}];
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
var expected = [
{
column: 12,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
column: 27,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should allow missing space after opening parenthesis in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should not allow multiple spaces before closing parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb(255, 255, 255 ); }';
var result;
var ast;
expect(result).to.be.undefined;
});
});
var expected = [{
column: 32,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
it('should allow missing space before closing parenthesis in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.be.undefined;
});
});
result = linter.lint(options, ast);
it('should allow missing space after opening parenthesis and before closing parenthesis in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis when "style" is "no_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
expect(result).to.be.undefined;
});
});
var expected = [
{
column: 19,
it('should not allow one space after opening parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding) {}';
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
column: 34,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
}];
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should not allow one space before closing parenthesis in mixins', function () {
var source = '.mixin(@margin, @padding ) {}';
var expected = [{
column: 25,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should allow one space after opening parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var options = {
style: 'one_space'
};
it('should not allow one space after opening parenthesis and before closing parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
var expected = [
{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
column: 26,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.be.undefined;
});
it('should not allow multiple spaces after opening parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding) {}';
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
}];
it('should allow one space before closing parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var options = {
style: 'one_space'
};
expect(result).to.deep.equal(expected);
});
});
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
it('should not allow multiple spaces before closing parenthesis in mixins', function () {
var source = '.mixin(@margin, @padding ) {}';
var expected = [{
column: 25,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
result = linter.lint(options, ast);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
expect(result).to.deep.equal(expected);
});
});
it('should allow one space after opening parenthesis and before closing parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
var expected = [
{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
column: 27,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
var options = {
style: 'one_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
}); // "no_space"
result = linter.lint(options, ast);
describe('when "style" is "one_space"', function () {
beforeEach(function () {
options = {
style: 'one_space'
};
});
expect(result).to.be.undefined;
});
it('should allow one space after opening parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
it('should not allow missing space after opening parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb(255, 255, 255 ); }';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var expected = [{
column: 19,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
}];
expect(result).to.be.undefined;
});
});
var options = {
style: 'one_space'
};
it('should allow one space before closing parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
});
expect(result).to.deep.equal(expected);
});
it('should allow one space after opening parenthesis and before closing parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
it('should not allow missing space before closing parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255); }';
var result;
var ast;
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
var expected = [{
column: 30,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}];
expect(result).to.be.undefined;
});
});
var options = {
style: 'one_space'
};
it('should not allow missing space after opening parenthesis', function () {
var source = 'color: rgb(255, 255, 255 );';
var expected = [{
column: 12,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
}];
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.deep.equal(expected);
});
it('should not allow missing space after opening parenthesis and before closing parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb(255, 255, 255); }';
var result;
var ast;
var expected = [
{
column: 19,
it('should not allow missing space before closing parenthesis', function () {
var source = 'color: rgb( 255, 255, 255);';
var expected = [{
column: 26,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 29,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
}];
var options = {
style: 'one_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should not allow missing space after opening parenthesis and before closing parenthesis', function () {
var source = 'color: rgb(255, 255, 255);';
var expected = [
{
column: 12,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 25,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should not allow multiple spaces after opening parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var expected = [{
column: 19,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
}];
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow multiple spaces before closing parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
var expected = [{
column: 33,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}];
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis when "style" is "one_space"', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var result;
var ast;
var expected = [
{
column: 19,
it('should not allow multiple spaces after opening parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
var expected = [{
column: 12,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 34,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
}];
var options = {
style: 'one_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should allow missing space after opening parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
var options = {
style: 'no_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should allow missing space before closing parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
var options = {
style: 'no_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should allow missing space after opening parenthesis and before closing parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
var options = {
style: 'no_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not allow one space after opening parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin( @margin, @padding) {}';
var result;
var ast;
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
}];
var options = {
style: 'no_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow one space before closing parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin(@margin, @padding ) {}';
var result;
var ast;
var expected = [{
column: 25,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
var options = {
style: 'no_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow one space after opening parenthesis and before closing parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
var expected = [
{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
it('should not allow multiple spaces before closing parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
var expected = [{
column: 26,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
message: 'Closing parenthesis should be preceded by one space.'
}];
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis', function () {
var source = 'color: rgb( 255, 255, 255 );';
var expected = [
{
column: 12,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 27,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should not allow multiple spaces after opening parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin( @margin, @padding) {}';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
}];
it('should allow one space after opening parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
expect(result).to.be.undefined;
});
});
result = linter.lint(options, ast);
it('should allow one space before closing parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should not allow multiple spaces before closing parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin(@margin, @padding ) {}';
var result;
var ast;
expect(result).to.be.undefined;
});
});
var expected = [{
column: 25,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}];
it('should allow one space after opening parenthesis and before closing parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
expect(result).to.be.undefined;
});
});
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis in mixins when "style" is "no_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
var expected = [
{
it('should not allow missing space after opening parenthesis in mixins', function () {
var source = '.mixin(@margin, @padding ) {}';
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should not be followed by any space.'
},
{
column: 27,
line: 1,
message: 'Closing parenthesis should not be preceded by any space.'
}
];
message: 'Opening parenthesis should be followed by one space.'
}];
var options = {
style: 'no_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should not allow missing space before closing parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding) {}';
var expected = [{
column: 26,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should allow one space after opening parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
expect(result).to.deep.equal(expected);
});
});
var options = {
style: 'one_space'
};
it('should not allow missing space after opening parenthesis and before closing parenthesis in mixins', function () {
var source = '.mixin(@margin, @padding) {}';
var expected = [
{
column: 8,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 25,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.be.undefined;
});
it('should allow one space before closing parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should allow one space after opening parenthesis and before closing parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
it('should not allow missing space after opening parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin(@margin, @padding ) {}';
var result;
var ast;
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
}];
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow missing space before closing parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin( @margin, @padding) {}';
var result;
var ast;
var expected = [{
column: 18,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}];
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow missing space after opening parenthesis and before closing parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin(@margin, @padding) {}';
var result;
var ast;
var expected = [
{
it('should not allow multiple spaces after opening parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 17,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
}];
var options = {
style: 'one_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow multiple spaces after opening parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
var expected = [{
column: 8,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
}];
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow multiple spaces before closing parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
var expected = [{
column: 26,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}];
var options = {
style: 'one_space'
};
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis in mixins when "style" is "one_space"', function () {
var source = '.mixin( @margin, @padding ) {}';
var result;
var ast;
var expected = [
{
column: 8,
it('should not allow multiple spaces before closing parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
var expected = [{
column: 26,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 27,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
}];
var options = {
style: 'one_space'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
ast = parseAST(source);
ast = ast.first('mixin').first('arguments');
expect(result).to.deep.equal(expected);
});
});
result = linter.lint(options, ast);
it('should not allow multiple spaces after opening parenthesis and before closing parenthesis in mixins', function () {
var source = '.mixin( @margin, @padding ) {}';
var expected = [
{
column: 8,
line: 1,
message: 'Opening parenthesis should be followed by one space.'
},
{
column: 27,
line: 1,
message: 'Closing parenthesis should be preceded by one space.'
}
];
expect(result).to.deep.equal(expected);
});
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
it('should throw on invalid "style" value', function () {
var source = '.foo { color: rgb( 255, 255, 255 ); }';
var lint;
var ast;
expect(result).to.deep.equal(expected);
});
});
}); // "one_space"
var options = {
style: 'invalid'
};
describe('with invalid "style" value', function () {
beforeEach(function () {
options = {
style: 'invalid'
};
});
ast = parseAST(source);
ast = ast.first().first('block').first('declaration').first('value').first('function').first('arguments');
it('should throw an error', function () {
var source = 'color: rgb( 255, 255, 255 );';
lint = linter.lint.bind(null, options, ast);
return spec.parse(source, function (ast) {
var node = ast.root.first;
var lint = spec.linter.lint.bind(null, options, node);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#stringQuotes()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: #fff; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.first.type);
});
});
it('should allow single quotes when "style" is "single"', function () {
var source = ".foo { content: 'Hello world'; }";
var result;
var ast;
var options = {

@@ -19,7 +22,7 @@ style: 'single'

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -29,5 +32,2 @@

var source = '.foo { content: "Hello world"; }';
var result;
var ast;
var expected = [{

@@ -43,7 +43,7 @@ column: 17,

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -53,5 +53,2 @@

var source = '.foo { content: "Hello world"; }';
var result;
var ast;
var options = {

@@ -61,7 +58,7 @@ style: 'double'

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -71,5 +68,2 @@

var source = ".foo { content: 'Hello world'; }";
var result;
var ast;
var expected = [{

@@ -85,7 +79,7 @@ column: 17,

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -95,5 +89,2 @@

var source = ".foo { background-image: url('img/image.jpg'); }";
var result;
var ast;
var options = {

@@ -103,7 +94,25 @@ style: 'single'

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
});
});
expect(result).to.be.undefined;
it('should not allow single quotes in functions when style is "double"', function () {
var source = ".foo { background-image: url('img/image.jpg'); }";
var options = {
style: 'double'
};
var expected = [{
column: 30,
line: 1,
message: 'Strings should use double quotes.'
}];
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
expect(result).to.deep.equal(expected);
});
});

@@ -113,5 +122,2 @@

var source = ".foo { content: ' (' attr(id) ')'; }";
var result;
var ast;
var options = {

@@ -121,7 +127,7 @@ style: 'single'

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -131,5 +137,2 @@

var source = "@foo: 'Hello world';";
var result;
var ast;
var options = {

@@ -139,7 +142,7 @@ style: 'single'

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -149,5 +152,2 @@

var source = '@foo: "Hello world";';
var result;
var ast;
var expected = [{

@@ -163,7 +163,7 @@ column: 7,

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -173,5 +173,2 @@

var source = '@foo: "Hello world";';
var result;
var ast;
var options = {

@@ -181,7 +178,7 @@ style: 'double'

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -191,5 +188,2 @@

var source = "@foo: 'Hello world';";
var result;
var ast;
var expected = [{

@@ -205,14 +199,75 @@ column: 7,

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
});
});
expect(result).to.deep.equal(expected);
it('should allow single quotes in attribute selectors when "style" is "single"', function () {
var source = "input[type='text'] {}";
var options = {
style: 'single'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should not allow double quotes in attribute selectors when "style" is "single"', function () {
var source = 'input[type="text"] {}';
var expected = [{
column: 12,
line: 1,
message: 'Strings should use single quotes.'
}];
var options = {
style: 'single'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
});
it('should allow double quotes in attribute selectors when "style" is "double"', function () {
var source = 'input[type="text"] {}';
var options = {
style: 'double'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.be.undefined;
});
});
it('should not allow single quotes in attribute selectors when "style" is "double"', function () {
var source = "input[type='text'] {}";
var expected = [{
column: 12,
line: 1,
message: 'Strings should use double quotes.'
}];
var options = {
style: 'double'
};
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
expect(result).to.deep.equal(expected);
});
});
it('should throw on invalid "style" value', function () {
var source = ".foo { content: 'Hello world' }";
var lint;
var ast;
var options = {

@@ -222,9 +277,9 @@ style: 'invalid'

ast = parseAST(source);
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#trailingSemicolon()', function () {
it('should have the proper node types', function () {
var source = '.foo { color: red; }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should not allow missing semicolons', function () {
var source = '.foo { color: red }';
var result;
var ast;
var expected = [{
column: 18,
column: 1,
line: 1,

@@ -21,8 +24,7 @@ message: 'All property declarations should end with a semicolon.'

ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -32,11 +34,8 @@

var source = '.foo { color: red; }';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -46,11 +45,8 @@

var source = '.foo {}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -60,11 +56,8 @@

var source = '.foo {\n}';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -74,26 +67,30 @@

var source = '@media screen and (max-width: 768px) { @color: red; .div { color: @color; } }';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it("should not report a missing semicolon when there's a space before the it", function () {
it('should not report a missing semicolon when there is a space before the it', function () {
var source = '.foo { color: red ; }';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
});
});
expect(result).to.be.undefined;
it('should not try to check mixins without a body', function () {
var source = '.foo { .mixin(); }';
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#trailingWhitespace()', function () {
it('should have the proper node types', function () {
var source = '.foo {}';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.type);
});
});
it('should allow lines with no trailing whitespace', function () {
var source = '.foo {}';
var result;
var ast;
ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -24,10 +28,8 @@

var source = '.foo {}\n';
var result;
var ast;
ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -37,5 +39,2 @@

var source = '.foo {} ';
var result;
var ast;
var expected = [{

@@ -47,7 +46,7 @@ column: 9,

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -57,5 +56,2 @@

var source = '.foo {} \t';
var result;
var ast;
var expected = [{

@@ -67,7 +63,7 @@ column: 9,

ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -77,12 +73,10 @@

var source = '';
var result;
var ast;
ast = parseAST(source);
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#urlFormat()', function () {
it('should have the proper node types', function () {
var source = '.foo { background-image: url(img/image.jpg); }';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.first.type);
});
});
it('should allow relative URLs when "style" is "relative"', function () {
var source = '.foo { background-image: url(img/image.jpg); }';
var result;
var ast;
var options = {

@@ -19,8 +22,7 @@ style: 'relative'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -30,7 +32,4 @@

var source = '.foo { background-image: url(http://example.com/img/image.jpg); }';
var result;
var ast;
var expected = [{
column: 26,
column: 30,
line: 1,

@@ -44,8 +43,7 @@ message: 'URL "http://example.com/img/image.jpg" should be relative.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -55,5 +53,2 @@

var source = '.foo { background-image: url(http://example.com/img/image.jpg); }';
var result;
var ast;
var options = {

@@ -63,8 +58,7 @@ style: 'absolute'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -74,7 +68,4 @@

var source = '.foo { background-image: url(img/image.jpg); }';
var result;
var ast;
var expected = [{
column: 26,
column: 30,
line: 1,

@@ -88,8 +79,7 @@ message: 'URL "img/image.jpg" should be absolute.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -99,7 +89,4 @@

var source = '.foo { background-image: url(//example.com/img/image.jpg); }';
var result;
var ast;
var expected = [{
column: 26,
column: 30,
line: 1,

@@ -113,8 +100,7 @@ message: 'URL "//example.com/img/image.jpg" should be relative.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -124,5 +110,2 @@

var source = '.foo { background-image: url(//example.com/img/image.jpg); }';
var result;
var ast;
var options = {

@@ -132,8 +115,7 @@ style: 'absolute'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -143,5 +125,2 @@

var source = ".foo { background-image: url('img/image.jpg'); }";
var result;
var ast;
var options = {

@@ -151,8 +130,7 @@ style: 'relative'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -162,5 +140,2 @@

var source = '.foo { background-image: url("img/image.jpg"); }';
var result;
var ast;
var options = {

@@ -170,8 +145,7 @@ style: 'relative'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -181,5 +155,2 @@

var source = ".foo { background-image: url('http://example.com/img/image.jpg'); }";
var result;
var ast;
var options = {

@@ -189,8 +160,7 @@ style: 'absolute'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -200,5 +170,2 @@

var source = '.foo { background-image: url("http://example.com/img/image.jpg"); }';
var result;
var ast;
var options = {

@@ -208,8 +175,7 @@ style: 'absolute'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -219,5 +185,2 @@

var source = ".foo { background-image: url( 'img/image.jpg' ); }";
var result;
var ast;
var options = {

@@ -227,8 +190,7 @@ style: 'relative'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -238,5 +200,2 @@

var source = '.foo { background-image: url( img/image.jpg ); }';
var result;
var ast;
var options = {

@@ -246,8 +205,7 @@ style: 'relative'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -257,5 +215,2 @@

var source = '.foo { background-image: url(img/image.jpg); }';
var lint;
var ast;
var options = {

@@ -265,10 +220,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#urlQuotes()', function () {
it('should allow single quotes', function () {
it('should have the proper node types', function () {
var source = ".foo { background-image: url('img/image.jpg'); }";
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.first.type);
});
});
result = linter.lint({}, ast);
it('should have the proper node types', function () {
var source = '@import url(http://example.com)';
expect(result).to.be.undefined;
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should allow single quotes', function () {
var source = ".foo { background-image: url('img/image.jpg'); }";
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first.first);
expect(result).to.be.undefined;
});
});
it('should allow double quotes', function () {
var source = '.foo { background-image: url("img/image.jpg"); }';
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -38,7 +46,4 @@

var source = '.foo { background-image: url(img/image.jpg); }';
var result;
var ast;
var expected = [{
column: 26,
column: 30,
line: 1,

@@ -48,8 +53,7 @@ message: 'URLs should be enclosed in quotes.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -59,7 +63,4 @@

var source = '@import url(http://example.com)';
var result;
var ast;
var expected = [{
column: 9,
column: 11,
line: 1,

@@ -69,8 +70,7 @@ message: 'URLs should be enclosed in quotes.'

ast = parseAST(source);
ast = ast.first('atrule');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});

@@ -80,11 +80,8 @@

var source = "@import url('http://example.com')";
var result;
var ast;
ast = parseAST(source);
ast = ast.first('atrule');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -94,11 +91,8 @@

var source = ".foo { background-image: url( 'img/image.jpg' ); }";
var result;
var ast;
ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first.first);
result = linter.lint({}, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});

@@ -108,7 +102,4 @@

var source = '.foo { background-image: url( img/image.jpg ); }';
var result;
var ast;
var expected = [{
column: 26,
column: 30,
line: 1,

@@ -118,10 +109,9 @@ message: 'URLs should be enclosed in quotes.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint({}, ast.root.first.first);
result = linter.lint({}, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
});
});
'use strict';
var path = require('path');
var expect = require('chai').expect;
var linter = require('../../../lib/linters/' + path.basename(__filename));
var parseAST = require('../../../lib/linter').parseAST;
var spec = require('../util.js').setup();
describe('lesshint', function () {
describe('#zeroUnit()', function () {
it('should have the proper node types', function () {
var source = 'margin-right: 0px;';
return spec.parse(source, function (ast) {
expect(spec.linter.nodeTypes).to.include(ast.root.first.type);
});
});
it('should report units on zero values when "style" is "no_unit"', function () {
var source = '.foo { margin-right: 0px; }';
var result;
var ast;
var source = 'margin-right: 0px;';
var expected = [{
column: 22,
column: 15,
line: 1,

@@ -25,15 +28,11 @@ message: 'Unit should be omitted on zero values.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not report anything on zero values without units when "style" is "no_unit"', function () {
var source = '.foo { margin-right: 0; }';
var result;
var ast;
var source = 'margin-right: 0;';
var options = {

@@ -43,15 +42,11 @@ style: 'no_unit'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not report units on zero values when "style" is "keep_unit"', function () {
var source = '.foo { margin-right: 0px; }';
var result;
var ast;
var source = 'margin-right: 0px;';
var options = {

@@ -61,17 +56,13 @@ style: 'keep_unit'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should report missing units on zero values when "style" is "keep_unit"', function () {
var source = '.foo { margin-right: 0; }';
var result;
var ast;
var source = 'margin-right: 0;';
var expected = [{
column: 22,
column: 15,
line: 1,

@@ -85,15 +76,11 @@ message: 'Unit should not be omitted on zero values.'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.deep.equal(expected);
expect(result).to.deep.equal(expected);
});
});
it('should not report units on zero values when the unit is an angle and "style" is "no_unit"', function () {
var source = '.foo { transform: rotate(90deg); }';
var result;
var ast;
var source = 'transform: rotate(90deg);';
var options = {

@@ -103,15 +90,11 @@ style: 'no_unit'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not report units on zero values when the unit is a time and "style" is "no_unit"', function () {
var source = '.foo { transition: all 0s; }';
var result;
var ast;
var source = 'transition: all 0s;';
var options = {

@@ -121,15 +104,11 @@ style: 'no_unit'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not report units on zero values when the unit is configured and "style" is "no_unit"', function () {
var source = '.foo { margin-left: 0zz; }';
var result;
var ast;
var source = 'margin-left: 0zz;';
var options = {

@@ -140,15 +119,11 @@ style: 'no_unit',

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not report units on zero values when the the property does not have units and "style" is "no_unit"', function () {
var source = '.bar { z-index: 0; }';
var result;
var ast;
var source = 'z-index: 0;';
var options = {

@@ -158,15 +133,11 @@ style: 'no_unit'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should not report units on zero values when the the property does not have units and "style" is "no_unit"', function () {
var source = '.bar { margin-left: 0; }';
var result;
var ast;
var source = 'margin-left: 0;';
var options = {

@@ -177,15 +148,11 @@ style: 'no_unit',

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var result = spec.linter.lint(options, ast.root.first);
result = linter.lint(options, ast);
expect(result).to.be.undefined;
expect(result).to.be.undefined;
});
});
it('should throw on invalid "style" value', function () {
var source = '.foo { margin-right: 0; }';
var lint;
var ast;
var source = 'margin-right: 0;';
var options = {

@@ -195,10 +162,9 @@ style: 'invalid'

ast = parseAST(source);
ast = ast.first().first('block').first('declaration');
return spec.parse(source, function (ast) {
var lint = spec.linter.lint.bind(null, options, ast.root.first);
lint = linter.lint.bind(null, options, ast);
expect(lint).to.throw(Error);
expect(lint).to.throw(Error);
});
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc