jmespath.js
1 var assert = require('assert'); 2 var jmespath = require('../jmespath'); 3 var tokenize = jmespath.tokenize; 4 var compile = jmespath.compile; 5 var strictDeepEqual = jmespath.strictDeepEqual; 6 7 8 describe('tokenize', function() { 9 it('should tokenize unquoted identifier', function() { 10 assert.deepEqual(tokenize('foo'), 11 [{type: "UnquotedIdentifier", 12 value: "foo", 13 start: 0}]); 14 }); 15 it('should tokenize unquoted identifier with underscore', function() { 16 assert.deepEqual(tokenize('_underscore'), 17 [{type: "UnquotedIdentifier", 18 value: "_underscore", 19 start: 0}]); 20 }); 21 it('should tokenize unquoted identifier with numbers', function() { 22 assert.deepEqual(tokenize('foo123'), 23 [{type: "UnquotedIdentifier", 24 value: "foo123", 25 start: 0}]); 26 }); 27 it('should tokenize dotted lookups', function() { 28 assert.deepEqual( 29 tokenize('foo.bar'), 30 [{type: "UnquotedIdentifier", value: "foo", start: 0}, 31 {type: "Dot", value: ".", start: 3}, 32 {type: "UnquotedIdentifier", value: "bar", start: 4}, 33 ]); 34 }); 35 it('should tokenize numbers', function() { 36 assert.deepEqual( 37 tokenize('foo[0]'), 38 [{type: "UnquotedIdentifier", value: "foo", start: 0}, 39 {type: "Lbracket", value: "[", start: 3}, 40 {type: "Number", value: 0, start: 4}, 41 {type: "Rbracket", value: "]", start: 5}, 42 ]); 43 }); 44 it('should tokenize numbers with multiple digits', function() { 45 assert.deepEqual( 46 tokenize("12345"), 47 [{type: "Number", value: 12345, start: 0}]); 48 }); 49 it('should tokenize negative numbers', function() { 50 assert.deepEqual( 51 tokenize("-12345"), 52 [{type: "Number", value: -12345, start: 0}]); 53 }); 54 it('should tokenize quoted identifier', function() { 55 assert.deepEqual(tokenize('"foo"'), 56 [{type: "QuotedIdentifier", 57 value: "foo", 58 start: 0}]); 59 }); 60 it('should tokenize quoted identifier with unicode escape', function() { 61 assert.deepEqual(tokenize('"\\u2713"'), 62 [{type: "QuotedIdentifier", 63 value: "✓", 64 start: 0}]); 65 }); 66 it('should tokenize literal lists', function() { 67 assert.deepEqual(tokenize("`[0, 1]`"), 68 [{type: "Literal", 69 value: [0, 1], 70 start: 0}]); 71 }); 72 it('should tokenize literal dict', function() { 73 assert.deepEqual(tokenize("`{\"foo\": \"bar\"}`"), 74 [{type: "Literal", 75 value: {"foo": "bar"}, 76 start: 0}]); 77 }); 78 it('should tokenize literal strings', function() { 79 assert.deepEqual(tokenize("`\"foo\"`"), 80 [{type: "Literal", 81 value: "foo", 82 start: 0}]); 83 }); 84 it('should tokenize json literals', function() { 85 assert.deepEqual(tokenize("`true`"), 86 [{type: "Literal", 87 value: true, 88 start: 0}]); 89 }); 90 it('should not requiring surrounding quotes for strings', function() { 91 assert.deepEqual(tokenize("`foo`"), 92 [{type: "Literal", 93 value: "foo", 94 start: 0}]); 95 }); 96 it('should not requiring surrounding quotes for numbers', function() { 97 assert.deepEqual(tokenize("`20`"), 98 [{type: "Literal", 99 value: 20, 100 start: 0}]); 101 }); 102 it('should tokenize literal lists with chars afterwards', function() { 103 assert.deepEqual( 104 tokenize("`[0, 1]`[0]"), [ 105 {type: "Literal", value: [0, 1], start: 0}, 106 {type: "Lbracket", value: "[", start: 8}, 107 {type: "Number", value: 0, start: 9}, 108 {type: "Rbracket", value: "]", start: 10} 109 ]); 110 }); 111 it('should tokenize two char tokens with shared prefix', function() { 112 assert.deepEqual( 113 tokenize("[?foo]"), 114 [{type: "Filter", value: "[?", start: 0}, 115 {type: "UnquotedIdentifier", value: "foo", start: 2}, 116 {type: "Rbracket", value: "]", start: 5}] 117 ); 118 }); 119 it('should tokenize flatten operator', function() { 120 assert.deepEqual( 121 tokenize("[]"), 122 [{type: "Flatten", value: "[]", start: 0}]); 123 }); 124 it('should tokenize comparators', function() { 125 assert.deepEqual(tokenize("<"), 126 [{type: "LT", 127 value: "<", 128 start: 0}]); 129 }); 130 it('should tokenize two char tokens without shared prefix', function() { 131 assert.deepEqual( 132 tokenize("=="), 133 [{type: "EQ", value: "==", start: 0}] 134 ); 135 }); 136 it('should tokenize not equals', function() { 137 assert.deepEqual( 138 tokenize("!="), 139 [{type: "NE", value: "!=", start: 0}] 140 ); 141 }); 142 it('should tokenize the OR token', function() { 143 assert.deepEqual( 144 tokenize("a||b"), 145 [ 146 {type: "UnquotedIdentifier", value: "a", start: 0}, 147 {type: "Or", value: "||", start: 1}, 148 {type: "UnquotedIdentifier", value: "b", start: 3} 149 ] 150 ); 151 }); 152 it('should tokenize function calls', function() { 153 assert.deepEqual( 154 tokenize("abs(@)"), 155 [ 156 {type: "UnquotedIdentifier", value: "abs", start: 0}, 157 {type: "Lparen", value: "(", start: 3}, 158 {type: "Current", value: "@", start: 4}, 159 {type: "Rparen", value: ")", start: 5} 160 ] 161 ); 162 }); 163 }); 164 165 166 describe('parsing', function() { 167 it('should parse field node', function() { 168 assert.deepEqual(compile('foo'), 169 {type: 'Field', name: 'foo'}); 170 }); 171 }); 172 173 describe('strictDeepEqual', function() { 174 it('should compare scalars', function() { 175 assert.strictEqual(strictDeepEqual('a', 'a'), true); 176 }); 177 it('should be false for different types', function() { 178 assert.strictEqual(strictDeepEqual('a', 2), false); 179 }); 180 it('should be false for arrays of different lengths', function() { 181 assert.strictEqual(strictDeepEqual([0, 1], [1, 2, 3]), false); 182 }); 183 it('should be true for identical arrays', function() { 184 assert.strictEqual(strictDeepEqual([0, 1], [0, 1]), true); 185 }); 186 it('should be true for nested arrays', function() { 187 assert.strictEqual( 188 strictDeepEqual([[0, 1], [2, 3]], [[0, 1], [2, 3]]), true); 189 }); 190 it('should be true for nested arrays of strings', function() { 191 assert.strictEqual( 192 strictDeepEqual([["a", "b"], ["c", "d"]], 193 [["a", "b"], ["c", "d"]]), true); 194 }); 195 it('should be false for different arrays of the same length', function() { 196 assert.strictEqual(strictDeepEqual([0, 1], [1, 2]), false); 197 }); 198 it('should handle object literals', function() { 199 assert.strictEqual(strictDeepEqual({a: 1, b: 2}, {a: 1, b: 2}), true); 200 }); 201 it('should handle keys in first not in second', function() { 202 assert.strictEqual(strictDeepEqual({a: 1, b: 2}, {a: 1}), false); 203 }); 204 it('should handle keys in second not in first', function() { 205 assert.strictEqual(strictDeepEqual({a: 1}, {a: 1, b: 2}), false); 206 }); 207 it('should handle nested objects', function() { 208 assert.strictEqual( 209 strictDeepEqual({a: {b: [1, 2]}}, 210 {a: {b: [1, 2]}}), true); 211 }); 212 it('should handle nested objects that are not equal', function() { 213 assert.strictEqual( 214 strictDeepEqual({a: {b: [1, 2]}}, 215 {a: {b: [1, 4]}}), false); 216 }); 217 });