Comparing version 1.5.2 to 2.0.0-rc
{ | ||
"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)) |
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
108
197
0
7
0
339957
14
7356
2
+ Addedpostcss@^5.0.19
+ Addedpostcss-less@^0.10.0
+ Addedpostcss-values-parser@^0.1.0
+ Addedflatten@1.0.3(transitive)
+ Addedhas-flag@1.0.0(transitive)
+ Addedindexes-of@1.0.1(transitive)
+ Addedjs-base64@2.6.4(transitive)
+ Addedpostcss@5.2.18(transitive)
+ Addedpostcss-less@0.10.0(transitive)
+ Addedpostcss-selector-parser@2.2.3(transitive)
+ Addedpostcss-values-parser@0.1.8(transitive)
+ Addedsource-map@0.5.7(transitive)
+ Addedsupports-color@3.2.3(transitive)
+ Addeduniq@1.0.1(transitive)
- Removedchalk@^1.0.0
- Removedgonzales-pe@gilt/gonzales-pe#dev
- Removedlodash.findindex@^4.0.1
- Removedlodash.findindex@4.6.0(transitive)