webpack/test/Parser.test.js

204 lines
5.7 KiB
JavaScript

var should = require("should");
var Parser = require("../lib/Parser");
describe("Parser", function() {
var testCases = {
"call ident": [
function() {
abc("test");
},
{
abc: ["test"]
}
],
"call member": [
function() {
cde.abc("membertest");
},
{
cdeabc: ["membertest"]
}
],
"call inner member": [
function() {
cde.ddd.abc("inner");
},
{
cdedddabc: ["inner"]
}
],
"expression": [
function() {
fgh;
},
{
fgh: [""]
}
],
"expression sub": [
function() {
fgh.sub;
},
{
fghsub: ["notry"]
}
],
"in function definition": [
function() {
(function(abc, cde, fgh) {
abc("test");
cde.abc("test");
cde.ddd.abc("test");
fgh;
fgh.sub;
})();
},
{}
],
"var definition": [
function() {
var abc, cde, fgh;
abc("test");
cde.abc("test");
cde.ddd.abc("test");
fgh;
fgh.sub;
},
{}
],
"function definition": [
function() {
function abc() {}
function cde() {}
function fgh() {}
abc("test");
cde.abc("test");
cde.ddd.abc("test");
fgh;
fgh.sub;
},
{}
],
"in try": [
function() {
try {
fgh.sub;
fgh;
function test(ttt) {
fgh.sub;
fgh;
}
} catch(e) {
fgh.sub;
fgh;
}
},
{
fghsub: ["try", "notry", "notry"],
fgh: ["", "test ttt", "test e"]
}
],
};
Object.keys(testCases).forEach(function(name) {
it("should parse " + name, function() {
var source = testCases[name][0].toString();
source = source.substr(13, source.length - 14).trim();
var state = testCases[name][1];
var testParser = new Parser({});
testParser.plugin("call abc", function(expr) {
if(!this.state.abc) this.state.abc = []
this.state.abc.push(this.parseString(expr.arguments[0]));
return true;
});
testParser.plugin("call cde.abc", function(expr) {
if(!this.state.cdeabc) this.state.cdeabc = []
this.state.cdeabc.push(this.parseString(expr.arguments[0]));
return true;
});
testParser.plugin("call cde.ddd.abc", function(expr) {
if(!this.state.cdedddabc) this.state.cdedddabc = []
this.state.cdedddabc.push(this.parseString(expr.arguments[0]));
return true;
});
testParser.plugin("expression fgh", function(expr) {
if(!this.state.fgh) this.state.fgh = []
this.state.fgh.push(this.scope.definitions.join(" "));
return true;
});
testParser.plugin("expression fgh.sub", function(expr) {
if(!this.state.fghsub) this.state.fghsub = []
this.state.fghsub.push(this.scope.inTry ? "try" : "notry");
return true;
});
var actual = testParser.parse(source);
should.exist(actual);
actual.should.be.eql(state);
});
});
describe("expression evaluation", function() {
function evaluateInParser(source) {
var parser = new Parser();
parser.plugin("call test", function(expr) {
this.state.result = this.evaluateExpression(expr.arguments[0]);
});
return parser.parse("test(" + source + ");").result;
}
var testCases = {
"\"strrring\"": "string=strrring",
"\"strr\" + \"ring\"": "string=strrring",
"\"s\" + (\"trr\" + \"rin\") + \"g\"": "string=strrring",
"'S' + (\"strr\" + \"ring\") + 'y'": "string=Sstrrringy",
"1": "number=1",
"1 + 3": "number=4",
"'pre' + a": "wrapped=['pre' string=pre]+[string=]",
"a + 'post'": "wrapped=[string=]+['post' string=post]",
"'pre' + a + 'post'": "wrapped=['pre' string=pre]+['post' string=post]",
"1 + a + 2": "",
"1 + a + 'post'": "wrapped=[string=]+['post' string=post]",
"'' + 1 + a + 2": "wrapped=['' + 1 string=1]+[2 string=2]",
"'' + 1 + a + 2 + 3": "wrapped=['' + 1 string=1]+[2 + 3 string=23]",
"'' + 1 + a + (2 + 3)": "wrapped=['' + 1 string=1]+[2 + 3 string=5]",
"'pre' + (1 + a) + (2 + 3)": "wrapped=['pre' string=pre]+[2 + 3 string=5]",
"a ? 'o1' : 'o2'": "options=['o1' string=o1],['o2' string=o2]",
"a ? 'o1' : b ? 'o2' : 'o3'": "options=['o1' string=o1],['o2' string=o2],['o3' string=o3]",
"a ? (b ? 'o1' : 'o2') : 'o3'": "options=['o1' string=o1],['o2' string=o2],['o3' string=o3]",
"a ? (b ? 'o1' : 'o2') : c ? 'o3' : 'o4'": "options=['o1' string=o1],['o2' string=o2],['o3' string=o3],['o4' string=o4]",
"a ? 'o1' : b ? 'o2' : c ? 'o3' : 'o4'": "options=['o1' string=o1],['o2' string=o2],['o3' string=o3],['o4' string=o4]",
"a ? 'o1' : b ? b : c ? 'o3' : c": "options=['o1' string=o1],[b],['o3' string=o3],[c]",
"['i1', 'i2', 3, a, b ? 4 : 5]": "items=['i1' string=i1],['i2' string=i2],[3 number=3],[a],[b ? 4 : 5 options=[4 number=4],[5 number=5]]",
};
Object.keys(testCases).forEach(function(key) {
function evalExprToString(evalExpr) {
if(!evalExpr) {
return "null";
} else {
var result = [];
if(evalExpr.isString()) result.push("string=" + evalExpr.string);
if(evalExpr.isNumber()) result.push("number=" + evalExpr.number);
if(evalExpr.isRegExp()) result.push("regExp=" + evalExpr.regExp);
if(evalExpr.isConditional()) result.push("options=[" + evalExpr.options.map(evalExprToString).join("],[") + "]");
if(evalExpr.isArray()) result.push("items=[" + evalExpr.items.map(evalExprToString).join("],[") + "]");
if(evalExpr.isWrapped()) result.push("wrapped=[" + evalExprToString(evalExpr.prefix) + "]+[" + evalExprToString(evalExpr.postfix) + "]");
if(evalExpr.range) {
var start = evalExpr.range[0] - 5;
var end = evalExpr.range[1] - 5;
return key.substr(start, end - start) + (result.length > 0 ? " " + result.join(" ") : "");
}
return result.join(" ");
}
}
it("should eval " + key, function() {
var evalExpr = evaluateInParser(key);
evalExprToString(evalExpr).should.be.eql(testCases[key] ? key + " " + testCases[key] : key);
});
});
});
});