Repository: mozilla/nunjucks
Pull request #746 (2016-05-05 04:19:07)

Add support for strict type check comparisons
I added support for the `===` and `!==` comparison operators.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ac799f4..2e74908 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ Changelog
 2.x (unreleased)
 ----------------
 
+* Add support for strict type check comparisons (=== and !===)
 * Allow full expressions (incl. filters) in import and from tags. Thanks legutierr.
   Merge of [#710](https://github.com/mozilla/nunjucks/pull/710).
 
diff --git a/docs/cn/templating.md b/docs/cn/templating.md
index a413b9a..31b65c2 100644
--- a/docs/cn/templating.md
+++ b/docs/cn/templating.md
@@ -586,7 +586,9 @@ Nunjucks 支持运算 (但尽量少用，把逻辑放在代码中)，可使用
 ### 比较 (Comparisons)
 
 * `==`
+* `===`
 * `!=`
+* `!==`
 * `>`
 * `>=`
 * `<`
diff --git a/docs/fr/templating.md b/docs/fr/templating.md
index 35a014c..4a1761c 100644
--- a/docs/fr/templating.md
+++ b/docs/fr/templating.md
@@ -699,7 +699,9 @@ Vous pouvez les utiliser ainsi :
 ### Comparaisons
 
 * `==`
+* `===`
 * `!=`
+* `!==`
 * `>`
 * `>=`
 * `<`
diff --git a/docs/templating.md b/docs/templating.md
index 101c746..c61fdd4 100644
--- a/docs/templating.md
+++ b/docs/templating.md
@@ -699,7 +699,9 @@ You can use them like this:
 ### Comparisons
 
 * `==`
+* `===`
 * `!=`
+* `!==`
 * `>`
 * `>=`
 * `<`
diff --git a/src/compiler.js b/src/compiler.js
index 46e8171..1e99875 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -12,7 +12,9 @@ var Frame = require('./runtime').Frame;
 // through
 var compareOps = {
     '==': '==',
+    '===': '===',
     '!=': '!=',
+    '!==': '!==',
     '<': '<',
     '>': '>',
     '<=': '<=',
diff --git a/src/lexer.js b/src/lexer.js
index b1d3867..8988d20 100644
--- a/src/lexer.js
+++ b/src/lexer.js
@@ -163,13 +163,19 @@ Tokenizer.prototype.nextToken = function() {
         else if(delimChars.indexOf(cur) !== -1) {
             // We've hit a delimiter (a special char like a bracket)
             this.forward();
-            var complexOps = ['==', '!=', '<=', '>=', '//', '**'];
+            var complexOps = ['==', '===', '!=', '!==', '<=', '>=', '//', '**'];
             var curComplex = cur + this.current();
             var type;
 
             if(lib.indexOf(complexOps, curComplex) !== -1) {
                 this.forward();
                 cur = curComplex;
+
+                // See if this is a strict equality/inequality comparator
+                if(lib.indexOf(complexOps, curComplex + this.current()) !== -1) {
+                    cur = curComplex + this.current();
+                    this.forward();
+                }
             }
 
             switch(cur) {
diff --git a/src/parser.js b/src/parser.js
index 0f9b950..7a1e7d7 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -760,7 +760,7 @@ var Parser = Object.extend({
     },
 
     parseCompare: function() {
-        var compareOps = ['==', '!=', '<', '>', '<=', '>='];
+        var compareOps = ['==', '===', '!=', '!==', '<', '>', '<=', '>='];
         var expr = this.parseConcat();
         var ops = [];
 


Test patch:
diff --git a/tests/compiler.js b/tests/compiler.js
index 58b9e39..afbddb3 100644
--- a/tests/compiler.js
+++ b/tests/compiler.js
@@ -399,6 +399,12 @@
             equal('{% if 10 != 10 %}yes{% endif %}', '');
             equal('{% if 10 == 10 %}yes{% endif %}', 'yes');
 
+            equal('{% if "0" == 0 %}yes{% endif %}', 'yes');
+            equal('{% if "0" === 0 %}yes{% endif %}', '');
+            equal('{% if "0" !== 0 %}yes{% endif %}', 'yes');
+            equal('{% if 0 == false %}yes{% endif %}', 'yes');
+            equal('{% if 0 === false %}yes{% endif %}', '');
+
             equal('{% if foo(20) > bar %}yes{% endif %}',
                   { foo: function(n) { return n - 1; },
                     bar: 15 },