Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'none' as a literal evaluating to null. #480

Merged
merged 2 commits into from
Sep 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ var Compiler = Object.extend({
val = val.replace(/\t/g, '\\t');
this.emit('"' + val + '"');
}
else if (node.value === null) {
this.emit('null');
}
else {
this.emit(node.value.toString());
}
Expand Down
5 changes: 5 additions & 0 deletions src/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var TOKEN_PIPE = 'pipe';
var TOKEN_INT = 'int';
var TOKEN_FLOAT = 'float';
var TOKEN_BOOLEAN = 'boolean';
var TOKEN_NONE = 'none';
var TOKEN_SYMBOL = 'symbol';
var TOKEN_SPECIAL = 'special';
var TOKEN_REGEX = 'regex';
Expand Down Expand Up @@ -195,6 +196,9 @@ Tokenizer.prototype.nextToken = function() {
else if(tok.match(/^(true|false)$/)) {
return token(TOKEN_BOOLEAN, tok, lineno, colno);
}
else if(tok === 'none') {
return token(TOKEN_NONE, tok, lineno, colno);
}
else if(tok) {
return token(TOKEN_SYMBOL, tok, lineno, colno);
}
Expand Down Expand Up @@ -493,6 +497,7 @@ module.exports = {
TOKEN_INT: TOKEN_INT,
TOKEN_FLOAT: TOKEN_FLOAT,
TOKEN_BOOLEAN: TOKEN_BOOLEAN,
TOKEN_NONE: TOKEN_NONE,
TOKEN_SYMBOL: TOKEN_SYMBOL,
TOKEN_SPECIAL: TOKEN_SPECIAL,
TOKEN_REGEX: TOKEN_REGEX
Expand Down
7 changes: 5 additions & 2 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,7 @@ var Parser = Object.extend({

parsePrimary: function (noPostfix) {
var tok = this.nextToken();
var val = null;
var val;
var node = null;

if(!tok) {
Expand Down Expand Up @@ -919,11 +919,14 @@ var Parser = Object.extend({
tok.colno);
}
}
else if(tok.type === lexer.TOKEN_NONE) {
val = null;
}
else if (tok.type === lexer.TOKEN_REGEX) {
val = new RegExp(tok.value.body, tok.value.flags);
}

if(val !== null) {
if(val !== undefined) {
node = new nodes.Literal(tok.lineno, tok.colno, val);
}
else if(tok.type === lexer.TOKEN_SYMBOL) {
Expand Down
15 changes: 15 additions & 0 deletions tests/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@
finish(done);
});

it('should display none as empty string', function(done) {
equal('{{ none }}', '');
finish(done);
});

it('should compile none as falsy', function(done) {
equal('{% if not none %}yes{% endif %}', 'yes');
finish(done);
});

it('should compile none as null, not undefined', function(done) {
equal('{{ none|default("d", false) }}', '');
finish(done);
});

it('should compile function calls', function(done) {
equal('{{ foo("msg") }}',
{ foo: function(str) { return str + 'hi'; }},
Expand Down
3 changes: 2 additions & 1 deletion tests/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,14 @@
});

it('should parse basic types', function() {
tokens = lexer.lex('{{ 3 4.5 true false foo "hello" \'boo\' r/regex/ }}');
tokens = lexer.lex('{{ 3 4.5 true false none foo "hello" \'boo\' r/regex/ }}');
hasTokens(tokens,
lexer.TOKEN_VARIABLE_START,
lexer.TOKEN_INT,
lexer.TOKEN_FLOAT,
lexer.TOKEN_BOOLEAN,
lexer.TOKEN_BOOLEAN,
lexer.TOKEN_NONE,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_STRING,
lexer.TOKEN_STRING,
Expand Down
5 changes: 5 additions & 0 deletions tests/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@
[nodes.Output,
[nodes.Literal, false]]]);

isAST(parser.parse('{{ none }}'),
[nodes.Root,
[nodes.Output,
[nodes.Literal, null]]]);

isAST(parser.parse('{{ foo }}'),
[nodes.Root,
[nodes.Output,
Expand Down
2 changes: 1 addition & 1 deletion tests/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
it('should allow for undefined macro arguments in the last position', function(done) {
render('{% macro foo(bar, baz) %}' +
'{{ bar }} {{ baz }}{% endmacro %}' +
'{{ foo("hello", none) }}',
'{{ foo("hello", nosuchvar) }}',
{},
{ noThrow: true },
function(err, res) {
Expand Down