Correct some error inconsistancies. Add browser testing of errors - import missing error fails because of #1117

This commit is contained in:
Luke Page
2013-02-05 22:38:43 +00:00
parent d9d959fd21
commit 88f3f02213
32 changed files with 100 additions and 51 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
};
}

View File

@@ -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");

View File

@@ -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: ""};

View File

@@ -0,0 +1,3 @@
describe("less.js error tests", function() {
testLessErrorsInDocument();
});

View File

@@ -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);

View File

@@ -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));

View File

@@ -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";

View File

@@ -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);

View File

@@ -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 }

View File

@@ -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);

View File

@@ -1 +1,6 @@
.a {
color: green;
// tests line number for import reference is correct
}
@import "file-does-not-exist.less";

View File

@@ -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";

View File

@@ -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"

View File

@@ -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();

View File

@@ -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 }}

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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 }}

View File

@@ -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

View File

@@ -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

View File

@@ -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 }

View File

@@ -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%);