Comparing version 0.3.1 to 0.4.0
0.4.0 / 2011-04-21 | ||
================== | ||
* Added; ported jade's error reporting to ejs. [slaskis] | ||
0.3.1 / 2011-02-23 | ||
@@ -3,0 +8,0 @@ ================== |
@@ -19,3 +19,3 @@ | ||
exports.version = '0.3.0'; | ||
exports.version = '0.4.0'; | ||
@@ -67,2 +67,36 @@ /** | ||
/** | ||
* Re-throw the given `err` in context to the | ||
* `str` of ejs, `filename`, and `lineno`. | ||
* | ||
* @param {Error} err | ||
* @param {String} str | ||
* @param {String} filename | ||
* @param {String} lineno | ||
* @api private | ||
*/ | ||
function rethrow(err, str, filename, lineno){ | ||
var lines = str.split('\n') | ||
, start = Math.max( lineno - 3, 0 ) | ||
, end = Math.min( lines.length - start , lineno + 3 ); | ||
// Error context | ||
var context = lines.slice(start, end).map(function(line, i){ | ||
return (i + 1 != lineno ? ' ' : ' >> ') | ||
+ (i + start + 1) | ||
+ "| " | ||
+ line; | ||
}).join('\n'); | ||
// Alter exception message | ||
err.path = filename; | ||
err.message = (filename || 'ejs') + ':' | ||
+ lineno + '\n' | ||
+ context + '\n\n' | ||
+ err.message; | ||
throw err; | ||
} | ||
/** | ||
* Parse the given `str` of ejs, returning the function body. | ||
@@ -85,2 +119,4 @@ * | ||
]; | ||
var lineno = 1; | ||
@@ -104,3 +140,3 @@ for (var i = 0, len = str.length; i < len; ++i) { | ||
default: | ||
prefix = "'); "; | ||
prefix = "'); __stack.lineno="+lineno+"; "; | ||
postfix = "; buf.push('"; | ||
@@ -117,11 +153,12 @@ } | ||
} else if (str[i] == "\\") { | ||
buf.push("\\\\"); | ||
buf.push("\\\\"); | ||
} else if (str[i] == "'") { | ||
buf.push("\\'"); | ||
buf.push("\\'"); | ||
} else if (str[i] == "\r") { | ||
buf.push(" "); | ||
buf.push(" "); | ||
} else if (str[i] == "\n") { | ||
buf.push("\\n"); | ||
buf.push("\\n"); | ||
lineno++; | ||
} else { | ||
buf.push(str[i]); | ||
buf.push(str[i]); | ||
} | ||
@@ -144,4 +181,21 @@ } | ||
options = options || {}; | ||
if (options.debug) sys.puts(exports.parse(str)); | ||
var fn = new Function('locals, filters, escape', exports.parse(str, options)); | ||
var input = JSON.stringify(str) | ||
, filename = options.filename | ||
? JSON.stringify(options.filename) | ||
: 'undefined'; | ||
// Adds the fancy stack trace meta info | ||
str = [ | ||
'var __stack = { lineno: 1, input: '+input+', filename: '+filename+' };', | ||
rethrow.toString(), | ||
'try {', | ||
exports.parse(str, options), | ||
'} catch (err) {', | ||
' rethrow(err, __stack.input, __stack.filename, __stack.lineno);', | ||
'}' | ||
].join("\n"); | ||
if (options.debug) sys.puts(str); | ||
var fn = new Function('locals, filters, escape', str); | ||
return function(locals){ | ||
@@ -148,0 +202,0 @@ return fn.call(this, locals, filters, utils.escape); |
{ | ||
"name": "ejs", | ||
"description": "Embedded JavaScript templates", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"author": "TJ Holowaychuk <tj@vision-media.ca>", | ||
@@ -6,0 +6,0 @@ "keywords": ["template", "engine", "ejs"], |
@@ -9,218 +9,238 @@ | ||
module.exports = { | ||
'test .version': function(assert){ | ||
assert.ok(/^\d+\.\d+\.\d+$/.test(ejs.version), 'Test .version format'); | ||
}, | ||
'test html': function(assert){ | ||
assert.equal('<p>yay</p>', ejs.render('<p>yay</p>')); | ||
}, | ||
'test buffered code': function(assert){ | ||
var html = '<p>tj</p>', | ||
str = '<p><%= name %></p>', | ||
locals = { name: 'tj' }; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test unbuffered code': function(assert){ | ||
var html = '<p>tj</p>', | ||
str = '<% if (name) { %><p><%= name %></p><% } %>', | ||
locals = { name: 'tj' }; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test `scope` option': function(assert){ | ||
var html = '<p>tj</p>', | ||
str = '<p><%= this %></p>'; | ||
assert.equal(html, ejs.render(str, { scope: 'tj' })); | ||
}, | ||
'test escaping': function(assert){ | ||
assert.equal('<script>', ejs.render('<%= "<script>" %>')); | ||
assert.equal('<script>', ejs.render('<%- "<script>" %>')); | ||
}, | ||
'test newlines': function(assert){ | ||
var html = '\n<p>tj</p>\n<p>tj@sencha.com</p>', | ||
str = '<% if (name) { %>\n<p><%= name %></p>\n<p><%= email %></p><% } %>', | ||
locals = { name: 'tj', email: 'tj@sencha.com' }; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test single quotes': function(assert){ | ||
var html = '<p>WAHOO</p>', | ||
str = "<p><%= up('wahoo') %></p>", | ||
locals = { up: function(str){ return str.toUpperCase(); }}; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test .version': function(assert){ | ||
assert.ok(/^\d+\.\d+\.\d+$/.test(ejs.version), 'Test .version format'); | ||
}, | ||
'test html': function(assert){ | ||
assert.equal('<p>yay</p>', ejs.render('<p>yay</p>')); | ||
}, | ||
'test buffered code': function(assert){ | ||
var html = '<p>tj</p>', | ||
str = '<p><%= name %></p>', | ||
locals = { name: 'tj' }; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test unbuffered code': function(assert){ | ||
var html = '<p>tj</p>', | ||
str = '<% if (name) { %><p><%= name %></p><% } %>', | ||
locals = { name: 'tj' }; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test `scope` option': function(assert){ | ||
var html = '<p>tj</p>', | ||
str = '<p><%= this %></p>'; | ||
assert.equal(html, ejs.render(str, { scope: 'tj' })); | ||
}, | ||
'test escaping': function(assert){ | ||
assert.equal('<script>', ejs.render('<%= "<script>" %>')); | ||
assert.equal('<script>', ejs.render('<%- "<script>" %>')); | ||
}, | ||
'test newlines': function(assert){ | ||
var html = '\n<p>tj</p>\n<p>tj@sencha.com</p>', | ||
str = '<% if (name) { %>\n<p><%= name %></p>\n<p><%= email %></p><% } %>', | ||
locals = { name: 'tj', email: 'tj@sencha.com' }; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test single quotes': function(assert){ | ||
var html = '<p>WAHOO</p>', | ||
str = "<p><%= up('wahoo') %></p>", | ||
locals = { up: function(str){ return str.toUpperCase(); }}; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test single quotes in the html': function(assert){ | ||
var html = '<p>WAHOO that\'s cool</p>', | ||
str = '<p><%= up(\'wahoo\') %> that\'s cool</p>', | ||
locals = { up: function(str){ return str.toUpperCase(); }}; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test single quotes in the html': function(assert){ | ||
var html = '<p>WAHOO that\'s cool</p>', | ||
str = '<p><%= up(\'wahoo\') %> that\'s cool</p>', | ||
locals = { up: function(str){ return str.toUpperCase(); }}; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test multiple single quotes': function(assert) { | ||
var html = "<p>couldn't shouldn't can't</p>", | ||
str = "<p>couldn't shouldn't can't</p>"; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test multiple single quotes': function(assert) { | ||
var html = "<p>couldn't shouldn't can't</p>", | ||
str = "<p>couldn't shouldn't can't</p>"; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test single quotes inside tags': function(assert) { | ||
var html = '<p>string</p>', | ||
str = "<p><%= 'string' %></p>"; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test single quotes inside tags': function(assert) { | ||
var html = '<p>string</p>', | ||
str = "<p><%= 'string' %></p>"; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test back-slashes in the document': function(assert) { | ||
var html = "<p>backslash: '\\'</p>", | ||
str = "<p>backslash: '\\'</p>"; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test double quotes': function(assert){ | ||
var html = '<p>WAHOO</p>', | ||
str = '<p><%= up("wahoo") %></p>', | ||
locals = { up: function(str){ return str.toUpperCase(); }}; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test multiple double quotes': function(assert) { | ||
var html = '<p>just a "test" wahoo</p>', | ||
str = '<p>just a "test" wahoo</p>'; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test whitespace': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p><%="foo"%></p>'; | ||
assert.equal(html, ejs.render(str)); | ||
'test back-slashes in the document': function(assert) { | ||
var html = "<p>backslash: '\\'</p>", | ||
str = "<p>backslash: '\\'</p>"; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test double quotes': function(assert){ | ||
var html = '<p>WAHOO</p>', | ||
str = '<p><%= up("wahoo") %></p>', | ||
locals = { up: function(str){ return str.toUpperCase(); }}; | ||
assert.equal(html, ejs.render(str, { locals: locals })); | ||
}, | ||
'test multiple double quotes': function(assert) { | ||
var html = '<p>just a "test" wahoo</p>', | ||
str = '<p>just a "test" wahoo</p>'; | ||
assert.equal(html, ejs.render(str)); | ||
}, | ||
'test whitespace': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p><%="foo"%></p>'; | ||
assert.equal(html, ejs.render(str)); | ||
var html = '<p>foo</p>', | ||
str = '<p><%=bar%></p>'; | ||
assert.equal(html, ejs.render(str, { locals: { bar: 'foo' }})); | ||
}, | ||
'test custom tags': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p>{{= "foo" }}</p>'; | ||
var html = '<p>foo</p>', | ||
str = '<p><%=bar%></p>'; | ||
assert.equal(html, ejs.render(str, { locals: { bar: 'foo' }})); | ||
}, | ||
'test custom tags': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p>{{= "foo" }}</p>'; | ||
assert.equal(html, ejs.render(str, { | ||
open: '{{', | ||
close: '}}' | ||
})); | ||
assert.equal(html, ejs.render(str, { | ||
open: '{{', | ||
close: '}}' | ||
})); | ||
var html = '<p>foo</p>', | ||
str = '<p><?= "foo" ?></p>'; | ||
var html = '<p>foo</p>', | ||
str = '<p><?= "foo" ?></p>'; | ||
assert.equal(html, ejs.render(str, { | ||
open: '<?', | ||
close: '?>' | ||
})); | ||
}, | ||
assert.equal(html, ejs.render(str, { | ||
open: '<?', | ||
close: '?>' | ||
})); | ||
}, | ||
'test custom tags over 2 chars': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p>{{{{= "foo" }>>}</p>'; | ||
'test custom tags over 2 chars': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p>{{{{= "foo" }>>}</p>'; | ||
assert.equal(html, ejs.render(str, { | ||
open: '{{{{', | ||
close: '}>>}' | ||
})); | ||
assert.equal(html, ejs.render(str, { | ||
open: '{{{{', | ||
close: '}>>}' | ||
})); | ||
var html = '<p>foo</p>', | ||
str = '<p><??= "foo" ??></p>'; | ||
var html = '<p>foo</p>', | ||
str = '<p><??= "foo" ??></p>'; | ||
assert.equal(html, ejs.render(str, { | ||
open: '<??', | ||
close: '??>' | ||
})); | ||
}, | ||
assert.equal(html, ejs.render(str, { | ||
open: '<??', | ||
close: '??>' | ||
})); | ||
}, | ||
'test global custom tags': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p>{{= "foo" }}</p>'; | ||
ejs.open = '{{'; | ||
ejs.close = '}}'; | ||
assert.equal(html, ejs.render(str)); | ||
delete ejs.open; | ||
delete ejs.close; | ||
}, | ||
'test iteration': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<% for (var key in items) { %>' | ||
+ '<p><%= items[key] %></p>' | ||
+ '<% } %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
items: ['foo'] | ||
} | ||
})); | ||
'test global custom tags': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<p>{{= "foo" }}</p>'; | ||
ejs.open = '{{'; | ||
ejs.close = '}}'; | ||
assert.equal(html, ejs.render(str)); | ||
delete ejs.open; | ||
delete ejs.close; | ||
}, | ||
'test iteration': function(assert){ | ||
var html = '<p>foo</p>', | ||
str = '<% for (var key in items) { %>' | ||
+ '<p><%= items[key] %></p>' | ||
+ '<% } %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
items: ['foo'] | ||
} | ||
})); | ||
var html = '<p>foo</p>', | ||
str = '<% items.forEach(function(item){ %>' | ||
+ '<p><%= item %></p>' | ||
+ '<% }) %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
items: ['foo'] | ||
} | ||
})); | ||
}, | ||
'test filter support': function(assert){ | ||
var html = 'Zab', | ||
str = '<%=: items | reverse | first | reverse | capitalize %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
items: ['foo', 'bar', 'baz'] | ||
} | ||
})); | ||
}, | ||
'test filter argument support': function(assert){ | ||
var html = 'tj, guillermo', | ||
str = '<%=: users | map:"name" | join:", " %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
users: [ | ||
{ name: 'tj' }, | ||
{ name: 'guillermo' } | ||
] | ||
} | ||
})); | ||
}, | ||
'test sort_by filter': function(assert){ | ||
var html = 'tj', | ||
str = '<%=: users | sort_by:"name" | last | get:"name" %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
users: [ | ||
{ name: 'guillermo' }, | ||
{ name: 'tj' }, | ||
{ name: 'mape' } | ||
] | ||
} | ||
})); | ||
}, | ||
'test custom filters': function(assert){ | ||
var html = 'Welcome Tj Holowaychuk', | ||
str = '<%=: users | first | greeting %>'; | ||
var html = '<p>foo</p>', | ||
str = '<% items.forEach(function(item){ %>' | ||
+ '<p><%= item %></p>' | ||
+ '<% }) %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
items: ['foo'] | ||
} | ||
})); | ||
}, | ||
'test filter support': function(assert){ | ||
var html = 'Zab', | ||
str = '<%=: items | reverse | first | reverse | capitalize %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
items: ['foo', 'bar', 'baz'] | ||
} | ||
})); | ||
}, | ||
'test filter argument support': function(assert){ | ||
var html = 'tj, guillermo', | ||
str = '<%=: users | map:"name" | join:", " %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
users: [ | ||
{ name: 'tj' }, | ||
{ name: 'guillermo' } | ||
] | ||
} | ||
})); | ||
}, | ||
'test sort_by filter': function(assert){ | ||
var html = 'tj', | ||
str = '<%=: users | sort_by:"name" | last | get:"name" %>'; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
users: [ | ||
{ name: 'guillermo' }, | ||
{ name: 'tj' }, | ||
{ name: 'mape' } | ||
] | ||
} | ||
})); | ||
}, | ||
'test custom filters': function(assert){ | ||
var html = 'Welcome Tj Holowaychuk', | ||
str = '<%=: users | first | greeting %>'; | ||
ejs.filters.greeting = function(user){ | ||
return 'Welcome ' + user.first + ' ' + user.last + ''; | ||
}; | ||
ejs.filters.greeting = function(user){ | ||
return 'Welcome ' + user.first + ' ' + user.last + ''; | ||
}; | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
users: [ | ||
{ first: 'Tj', last: 'Holowaychuk' } | ||
] | ||
} | ||
})); | ||
assert.equal(html, ejs.render(str, { | ||
locals: { | ||
users: [ | ||
{ first: 'Tj', last: 'Holowaychuk' } | ||
] | ||
} | ||
})); | ||
}, | ||
'test useful stack traces': function(assert){ | ||
var str = [ | ||
"A little somethin'", | ||
"somethin'", | ||
"<% if (name) { %>", // Failing line | ||
" <p><%= name %></p>", | ||
" <p><%= email %></p>", | ||
"<% } %>" | ||
].join("\n"); | ||
try { | ||
ejs.render(str) | ||
} catch( err ){ | ||
assert.includes(err.message,"name is not defined"); | ||
assert.eql(err.name,"ReferenceError"); | ||
var lineno = parseInt(err.toString().match(/ejs:(\d+)\n/)[1]); | ||
assert.eql(lineno,3,"Error should been thrown on line 3, was thrown on line "+lineno); | ||
} | ||
} | ||
}; |
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
786
136848
33