mirror of
https://github.com/less/less.js.git
synced 2026-05-01 03:00:22 -04:00
Correct some error inconsistancies. Add browser testing of errors - import missing error fails because of #1117
This commit is contained in:
@@ -290,7 +290,7 @@ function loadStyleSheet(sheet, callback, reload, remaining) {
|
||||
}
|
||||
}
|
||||
}, function (status, url) {
|
||||
throw new(Error)("Couldn't load " + url + " (" + status + ")");
|
||||
callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")\n" });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -420,25 +420,25 @@ function error(e, href) {
|
||||
elem.id = id;
|
||||
elem.className = "less-error-message";
|
||||
|
||||
content = '<h3>' + (e.message || 'There is an error in your .less file') +
|
||||
content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
|
||||
'</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
|
||||
|
||||
var errorline = function (e, i, classname) {
|
||||
if (e.extract[i]) {
|
||||
error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
|
||||
if (e.extract[i] != undefined) {
|
||||
error.push(template.replace(/\{line\}/, (parseInt(e.line) || 0) + (i - 1))
|
||||
.replace(/\{class\}/, classname)
|
||||
.replace(/\{content\}/, e.extract[i]));
|
||||
}
|
||||
};
|
||||
|
||||
if (e.stack) {
|
||||
content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
|
||||
} else if (e.extract) {
|
||||
if (e.extract) {
|
||||
errorline(e, 0, '');
|
||||
errorline(e, 1, 'line');
|
||||
errorline(e, 2, '');
|
||||
content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
|
||||
'<ul>' + error.join('') + '</ul>';
|
||||
} else if (e.stack) {
|
||||
content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
|
||||
}
|
||||
elem.innerHTML = content;
|
||||
|
||||
|
||||
@@ -54,10 +54,14 @@ var less = {
|
||||
error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
|
||||
}
|
||||
|
||||
if (extract[1]) {
|
||||
error.push(ctx.line + ' ' + extract[1].slice(0, ctx.column)
|
||||
+ stylize(stylize(stylize(extract[1][ctx.column], 'bold')
|
||||
+ extract[1].slice(ctx.column + 1), 'red'), 'inverse'));
|
||||
if (typeof(extract[1]) === 'string') {
|
||||
var errorTxt = ctx.line + ' ';
|
||||
if (extract[1]) {
|
||||
errorTxt += extract[1].slice(0, ctx.column) +
|
||||
stylize(stylize(stylize(extract[1][ctx.column], 'bold') +
|
||||
extract[1].slice(ctx.column + 1), 'red'), 'inverse');
|
||||
}
|
||||
error.push(errorTxt);
|
||||
}
|
||||
|
||||
if (typeof(extract[2]) === 'string') {
|
||||
@@ -67,7 +71,7 @@ var less = {
|
||||
|
||||
message += stylize(ctx.type + 'Error: ' + ctx.message, 'red');
|
||||
ctx.filename && (message += stylize(' in ', 'red') + ctx.filename +
|
||||
stylize(':' + ctx.line + ':' + ctx.column, 'grey'));
|
||||
stylize(' on line ' + ctx.line + ', column ' + (ctx.column + 1) + ':', 'grey'));
|
||||
|
||||
message += '\n' + error;
|
||||
|
||||
@@ -184,11 +188,7 @@ less.Parser.importer = function (file, paths, callback, env) {
|
||||
|
||||
if (!pathname) {
|
||||
|
||||
if (typeof(env.errback) === "function") {
|
||||
env.errback(file, paths, callback);
|
||||
} else {
|
||||
callback({ type: 'File', message: "'" + file + "' wasn't found.\n" });
|
||||
}
|
||||
callback({ type: 'File', message: "'" + file + "' wasn't found.\n" });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ less.Parser = function Parser(env) {
|
||||
})([[]]);
|
||||
|
||||
if (error) {
|
||||
return callback(error, env);
|
||||
return callback(new(LessError)(error, env));
|
||||
}
|
||||
|
||||
// Start with the primary rule.
|
||||
@@ -454,7 +454,7 @@ less.Parser = function Parser(env) {
|
||||
|
||||
error = {
|
||||
type: "Parse",
|
||||
message: "Syntax Error on line " + line,
|
||||
message: "Unrecognised input",
|
||||
index: i,
|
||||
filename: env.filename,
|
||||
line: line,
|
||||
@@ -1505,11 +1505,7 @@ if (less.mode === 'browser' || less.mode === 'rhino') {
|
||||
// as we need this to evaluate the current stylesheet.
|
||||
loadStyleSheet(env.toSheet(path),
|
||||
function (e, root, data, sheet, _, path) {
|
||||
if (e && typeof(env.errback) === "function") {
|
||||
env.errback.call(null, path, paths, callback, env);
|
||||
} else {
|
||||
callback.call(null, e, root, path);
|
||||
}
|
||||
callback.call(null, e, root, path);
|
||||
}, true);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ var createTestRunnerPage = function(dir, exclude, testSuiteName, dir2) {
|
||||
|
||||
createTestRunnerPage("", /javascript|urls/, "main");
|
||||
createTestRunnerPage("", null, "legacy", "legacy");
|
||||
createTestRunnerPage("", null, "errors", "errors");
|
||||
createTestRunnerPage("browser", null, "browser");
|
||||
createTestRunnerPage("browser", null, "relative-urls", "relative-urls");
|
||||
createTestRunnerPage("browser", null, "rootpath", "rootpath");
|
||||
|
||||
@@ -10,13 +10,21 @@ console.log = function(msg) {
|
||||
};
|
||||
|
||||
var testLessEqualsInDocument = function() {
|
||||
testLessInDocument(testSheet);
|
||||
};
|
||||
|
||||
var testLessErrorsInDocument = function() {
|
||||
testLessInDocument(testErrorSheet);
|
||||
};
|
||||
|
||||
var testLessInDocument = function(testFunc) {
|
||||
var links = document.getElementsByTagName('link'),
|
||||
typePattern = /^text\/(x-)?less$/;
|
||||
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
|
||||
(links[i].type.match(typePattern)))) {
|
||||
testSheet(links[i]);
|
||||
testFunc(links[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -40,6 +48,40 @@ var testSheet = function(sheet) {
|
||||
});
|
||||
};
|
||||
|
||||
var testErrorSheet = function(sheet) {
|
||||
it(sheet.id + " should match an error", function() {
|
||||
var lessHref = sheet.href,
|
||||
id = sheet.id.replace(/^original-less:/, "less-error-message:"),
|
||||
errorHref = lessHref.replace(/.less$/, ".txt"),
|
||||
errorFile = loadFile(errorHref),
|
||||
actualErrorElement = document.getElementById(id),
|
||||
actualErrorMsg;
|
||||
|
||||
describe("the error", function() {
|
||||
expect(actualErrorElement).not.toBe(null);
|
||||
});
|
||||
|
||||
actualErrorMsg = actualErrorElement.innerText
|
||||
.replace(/\n\d+/g, function(lineNo) { return lineNo + " "; })
|
||||
.replace("\nin ", " in ")
|
||||
.replace("\n\n", "\n");
|
||||
|
||||
waitsFor(function() {
|
||||
return errorFile.loaded;
|
||||
}, "failed to load expected outout", 10000);
|
||||
|
||||
runs(function() {
|
||||
var errorTxt = errorFile.text
|
||||
.replace("{path}", "")
|
||||
.replace("{pathrel}", "");
|
||||
expect(actualErrorMsg).toEqual(errorTxt);
|
||||
if (errorTxt == actualErrorMsg) {
|
||||
actualErrorElement.style.display = "none";
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var loadFile = function(href) {
|
||||
var request = new XMLHttpRequest(),
|
||||
response = { loaded: false, text: ""};
|
||||
|
||||
3
test/browser/runner-errors.js
Normal file
3
test/browser/runner-errors.js
Normal file
@@ -0,0 +1,3 @@
|
||||
describe("less.js error tests", function() {
|
||||
testLessErrorsInDocument();
|
||||
});
|
||||
@@ -1,2 +1,2 @@
|
||||
SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px' and 'em'. in {path}add-mixed-units.less:null:-1
|
||||
SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px' and 'em'. in {path}add-mixed-units.less on line null, column 0:
|
||||
1 error: (1px + 3em);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px*px' and 'em*px'. in C:\git\less.js\test\less\errors\add-mixed-units2.less:null:-1
|
||||
SyntaxError: Incompatible units. Change the units or use the unit function. Bad units: 'px*px' and 'em*px'. in {path}add-mixed-units2.less on line null, column 0:
|
||||
1 error: ((1px * 2px) + (3em * 3px));
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
ParseError: Syntax Error on line 1 in {path}bad-variable-declaration1.less:1:0
|
||||
ParseError: Unrecognised input in {path}bad-variable-declaration1.less on line 1, column 1:
|
||||
1 @@demo: "hi";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
OperationError: Can't substract or divide a color from a number in {path}color-operation-error.less:null:-1
|
||||
OperationError: Can't substract or divide a color from a number in {path}color-operation-error.less on line null, column 0:
|
||||
1 prop: (3 / #fff);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
ParseError: Syntax Error on line 1 in {path}comment-in-selector.less:1:20
|
||||
ParseError: Unrecognised input in {path}comment-in-selector.less on line 1, column 21:
|
||||
1 #gaga /* Comment */ span { color: red }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: px/em in {path}divide-mixed-units.less:null:-1
|
||||
SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: px/em in {path}divide-mixed-units.less on line null, column 0:
|
||||
1 error: (1px / 3em);
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
.a {
|
||||
color: green;
|
||||
// tests line number for import reference is correct
|
||||
}
|
||||
|
||||
@import "file-does-not-exist.less";
|
||||
@@ -1,3 +1,4 @@
|
||||
FileError: 'file-does-not-exist.less' wasn't found.
|
||||
in {path}import-missing.less:1:0
|
||||
1 @import "file-does-not-exist.less";
|
||||
in {path}import-missing.less on line 6, column 1:
|
||||
5
|
||||
6 @import "file-does-not-exist.less";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
ParseError: Syntax Error on line 1 in {path}import-no-semi.less:1:0
|
||||
ParseError: Unrecognised input in {path}import-no-semi.less on line 1, column 1:
|
||||
1 @import "this-statement-is-invalid.less"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
NameError: .mixin-not-defined is undefined in {pathrel}mixin-not-defined.less:11:0
|
||||
NameError: .mixin-not-defined is undefined in {pathrel}mixin-not-defined.less on line 11, column 1:
|
||||
10
|
||||
11 .mixin-not-defined();
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
ParseError: missing opening `{` in {pathrel}parse-error-curly-bracket.less:1:1
|
||||
ParseError: missing opening `{` in {pathrel}parse-error-curly-bracket.less on line 1, column 2:
|
||||
1 }}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SyntaxError: JavaScript evaluation error: 'TypeError: Cannot call method 'toJS' of undefined' in {path}javascript-error.less:2:26
|
||||
SyntaxError: JavaScript evaluation error: 'TypeError: Cannot call method 'toJS' of undefined' in {path}javascript-error.less on line 2, column 27:
|
||||
1 .scope {
|
||||
2 var: `this.foo.toJS()`;
|
||||
3 }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-1.less:5:29
|
||||
SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-1.less on line 5, column 30:
|
||||
4 .mixin-test {
|
||||
5 .mixin(@a: 5; @b: 6, @c: 7);
|
||||
6 }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-2.less:5:25
|
||||
SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-2.less on line 5, column 26:
|
||||
4 .mixin-test {
|
||||
5 .mixin(@a: 5, @b: 6; @c: 7);
|
||||
6 }
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less:11:0
|
||||
NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less on line 11, column 1:
|
||||
10
|
||||
11 .mixin-not-defined();
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
RuntimeError: No matching definition was found for `.mixin(trumpete)` in {path}mixin-not-matched.less:6:0
|
||||
RuntimeError: No matching definition was found for `.mixin(trumpete)` in {path}mixin-not-matched.less on line 6, column 1:
|
||||
5
|
||||
6 .mixin(@saxofon);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
RuntimeError: No matching definition was found for `.mixin(@a:trumpete)` in {path}mixin-not-matched2.less:6:0
|
||||
RuntimeError: No matching definition was found for `.mixin(@a:trumpete)` in {path}mixin-not-matched2.less on line 6, column 1:
|
||||
5
|
||||
6 .mixin(@a: @saxofon);
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: em*px in {path}multiply-mixed-units.less:null:-1
|
||||
SyntaxError: Multiple units in dimension. Correct the units or use the unit function. Bad unit: em*px in {path}multiply-mixed-units.less on line null, column 0:
|
||||
1 error: (1px * 1em);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SyntaxError: expected ')' got '(' in {path}parens-error-1.less:2:17
|
||||
SyntaxError: expected ')' got '(' in {path}parens-error-1.less on line 2, column 18:
|
||||
1 .a {
|
||||
2 something: (12 (13 + 5 -23) + 5);
|
||||
3 }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SyntaxError: expected ')' got '-' in {path}parens-error-2.less:2:27
|
||||
SyntaxError: expected ')' got '-' in {path}parens-error-2.less on line 2, column 28:
|
||||
1 .a {
|
||||
2 something: (12 * (13 + 5 -23));
|
||||
3 }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SyntaxError: expected ')' got '-' in {path}parens-error-3.less:2:28
|
||||
SyntaxError: expected ')' got '-' in {path}parens-error-3.less on line 2, column 29:
|
||||
1 .a {
|
||||
2 something: (12 + (13 + 10 -23));
|
||||
3 }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
ParseError: missing opening `{` in {path}parse-error-curly-bracket.less:1:1
|
||||
ParseError: missing opening `{` in {path}parse-error-curly-bracket.less on line 1, column 2:
|
||||
1 }}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
ParseError: missing closing `}` in {path}parse-error-missing-bracket.less:3:0
|
||||
ParseError: missing closing `}` in {path}parse-error-missing-bracket.less on line 3, column 1:
|
||||
2 background-color: #fff;
|
||||
3
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ParseError: Syntax Error on line 8 in {path}parse-error-with-import.less:8:8
|
||||
ParseError: Unrecognised input in {path}parse-error-with-import.less on line 8, column 9:
|
||||
7
|
||||
8 nonsense;
|
||||
9
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ParseError: Syntax Error on line 2 in {path}property-ie5-hack.less:2:2
|
||||
ParseError: Unrecognised input in {path}property-ie5-hack.less on line 2, column 3:
|
||||
1 .test {
|
||||
2 display/*/: block; /*sorry for IE5*/
|
||||
3 }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
NameError: Recursive variable definition for @bodyColor in {path}recursive-variable.less:1:19
|
||||
NameError: Recursive variable definition for @bodyColor in {path}recursive-variable.less on line 1, column 20:
|
||||
1 @bodyColor: darken(@bodyColor, 30%);
|
||||
|
||||
Reference in New Issue
Block a user