---
section: Initial Minimal Subset
---
title: Identity
context: {}
template: {key: [1,2,{key2: 'val', key3: 1}, true], f: false}
result: {key: [1,2,{key2: 'val', key3: 1}, true], f: false}
---
title: fromNow
context: {}
template: {$fromNow: ''}
result: '2017-01-19T16:27:20.974Z'
---
title: fromNow 2 days 3 hours
context: {}
template: {$fromNow: '2 days 3 hours'}
result: '2017-01-21T19:27:20.974Z'
---
title: $eval without context
context: {}
template: {$eval: '1 + 2'}
result: 3
---
title: $eval
context: {key: ['value', 1, 2, true, {}]}
template: {$eval: 'key'}
result: ['value', 1, 2, true, {}]
---
title: $json
context: {}
template: {$json: [1,2,true,{},[]]}
result: '[1,2,true,{},[]]'
---
title: $json alphabetical
context: {}
template: {$json: {'Z':null,'q':1,'a':{'c':45,'b':['9',8,{}]},'r':true}}
result: '{"Z":null,"a":{"b":["9",8,{}],"c":45},"q":1,"r":true}'
---
title: string interpolation
context: {key: 'world', num: 1}
template: {message: 'hello ${key}', 'k-${num}': true}
result: {message: 'hello world', 'k-1': true}
---
title: string interpolation with object evaluation
context: {key: 'world', num: 1}
template: {message: 'hello ${{a: "world"}.a}', 'k-${{a: 1}.a + {a: 0}.a}': true}
result: {message: 'hello world', 'k-1': true}
---
title: multiple string interpolation (1)
context: {a: 'hello', b: 'world'}
template: {message: '${a} ${b}'}
result: {message: 'hello world'}
---
title: multiple string interpolation (2)
context: {a: 'hello', b: 'world'}
template: {message: '${a}$$${b}'}
result: {message: 'hello$${b}'}
---
title: multiple string interpolation (3)
context: {a: 'hello', b: 'world'}
template: {message: '${a}##${b}'}
result: {message: 'hello##world'}
---
title: string interpolation escapes
context: {}
template: {message: 'a literal $${in a string}'}
result: {message: 'a literal ${in a string}'}
---
title: string interpolation escapes with more $
context: {x: 'a'}
template: ['${x}', '$${x}', '$$${x}', '$$$${x}', '$$$$${x}']
result: ['a', '${x}', '$${x}', '$$${x}', '$$$${x}']
---
title: string interpolation of keys
context: {name: 'foo', value: 'bar'}
template: {"tc_${name}": "${value}"}
result: {"tc_foo": "bar"}
---
title: string interpolation with unbalanced }
context: {}
template: {message: 'tricky ${"}}}}"}'}
result: {message: 'tricky }}}}'}
---
title: can't interpolate arrays
context: {key: [1,2,3]}
template: {message: 'hello ${key}'}
error: "TemplateError at template.message: interpolation of 'key' produced an array or object"
---
title: can't interpolate objects
context: {key: {}}
template: 'hello ${key}'
error: "TemplateError: interpolation of 'key' produced an array or object"
---
title: booleans interpolate
context: {t: true, f: false}
template: '${t} or ${f}: yeast is a bacterium'
result: 'true or false: yeast is a bacterium'
---
title: numbers interpolate
context: {round: 3, decimal: 3.75}
template: '${round}, really ${decimal}'
result: '3, really 3.75'
---
title: nulls interpolate
context: {nothing: null}
template: 'big pile of ${nothing}'
result: 'big pile of '
---
title: invalid context
context: {'a b c': 1}
template: {}
error: 'TemplateError: top level keys of context must follow /[a-zA-Z_][a-zA-Z0-9_]*/'
---
title: operator nested in an object
context: {}
template: { key: {$reverse: [1,2,3]}}
result: {key: [3,2,1]}
---
section: $if operator
---
title: $if-then-else, true
context: {cond: true}
template: {$if: 'cond', then: 1, else: 2}
result: 1
---
title: $if-then-else, false
context: {cond: false}
template: {$if: 'cond', then: 1, else: 2}
result: 2
---
title: $if-then in array, true
context: {cond: true}
template: [0, {$if: 'cond', then: 1}]
result: [0, 1]
---
title: $if-then in array, false
context: {cond: false}
template: [0, {$if: 'cond', then: 1}]
result: [0] ---
title: $if-then in object, true
context: {cond: true}
template: {key: {$if: 'cond', then: 1}, k2: 3}
result: {key: 1, k2: 3}
---
title: $if-then in object, false
context: {cond: false}
template: {key: {$if: 'cond', then: 1}, k2: 3}
result: {k2: 3} ---
title: $if -> delete-marker, true
context: {cond: true}
template: {key: {$if: 'cond'}, k2: 3}
result: {k2: 3} ---
title: $if -> delete-marker, false
context: {cond: false}
template: {key: {$if: 'cond'}, k2: 3}
result: {k2: 3} ---
title: $if->then, then => $eval, true
context: {key: {b: 1}}
template: {$if: 'true', then: {$eval: 'key'}}
result: {b: 1}
---
title: $if->else, else => $eval, false
context: {key: {b: 1}}
template: {$if: 'false', else: {$eval: 'key'}}
result: {b: 1}
---
title: $if->then, then => ${}, true
context: {key: 'one'}
template: {$if: 'true', then: '${key}'}
result: 'one'
---
title: $if->else, else => ${}, false
context: {key: 'one'}
template: {$if: 'false', else: '${key}'}
result: 'one'
---
title: $if->then, then => object, true
context: {cond: true}
template: {$if: 'cond', then: {key: 'hello world'}}
result: {key: 'hello world'}
---
title: $if->else, else => object, false
context: {cond: false}
template: {$if: 'cond', else: {key: 'hello world'}}
result: {key: 'hello world'}
---
title: $if->then, then => object, $eval, true
context: {cond: true, key: 'hello world'}
template: {$if: 'cond', then: {key: {$eval: 'key'}}}
result: {key: 'hello world'}
---
title: $if->else, else => object, $eval, false
context: {cond: false, key: 'hello world'}
template: {$if: 'cond', else: {key: {$eval: 'key'}}}
result: {key: 'hello world'}
---
title: $if->then, then => object, interpolation, true
context: {cond: true, key: 'world'}
template: {$if: 'cond', then: {key: 'hello ${key}'}}
result: {key: 'hello world'}
---
title: $if->else, else => object, interpolation, false
context: {cond: false, key: 'world'}
template: {$if: 'cond', else: {key: 'hello ${key}'}}
result: {key: 'hello world'}
---
title: $if->then->else, empty string
context: {cond: "", key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: f
---
title: $if->then->else, nonempty string
context: {cond: "stuff", key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: t
---
title: $if->then->else, string "0" context: {cond: "0", key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: t
---
title: $if->then->else, zero
context: {cond: 0, key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: f
---
title: $if->then->else, one
context: {cond: 1, key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: t
---
title: $if->then->else, null
context: {cond: null, key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: f
---
title: $if->then->else, empty array
context: {cond: [], key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: f
---
title: $if->then->else, nonempty array
context: {cond: [1, 2], key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: t
---
title: $if->then->else, empty object
context: {cond: {}, key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: f
---
title: $if->then->else, nonempty object
context: {cond: {a: 2}, key: 'world'}
template: {$if: 'cond', then: "t", else: "f"}
result: t
---
title: $if->then->else, function
context: {}
template: {$if: 'min', then: "t", else: "f"}
result: t
---
title: $if->then evaluating to nothing at the top level is null
context: {cond: false}
template: {$if: 'cond', then: "t"}
result: null
---
title: $if-then-else with undefined properties
context: {cond: true}
template: {$if: 'cond', then: 1, foo: 'bar', else: 2, bing: 'baz'}
error: 'TemplateError: $if has undefined properties: bing foo'
---
section: escape operators
---
title: escape $eval
context: {}
template: {$$eval: "1+2"}
result: {$eval: "1+2"}
---
title: escape $flatten
context: {}
template: {$$flatten: [[1, 2], [3, 4], [5]]}
result: {$flatten: [[1, 2], [3, 4], [5]]}
---
title: escape $fromNow
context: {}
template: {$$fromNow: "2 days"}
result: {$fromNow: "2 days"}
---
title: escape $if
context: {}
template: {$$if: false}
result: {$if: false}
---
title: escape $json
context: {}
template: {$$json: [1, 2, 3]}
result: {$json: [1, 2, 3]}
---
title: escape $let
context: {}
template: {$$let: {ts: 100, foo: 200}, in: [{$$eval: "ts+foo"}]}
result: {$let: {ts: 100, foo: 200}, in: [{$eval: "ts+foo"}]}
---
title: escape $map
context: {}
template: {$$map: [2, 4, 6], each(x): {$$eval: "x + a"}}
result: {$map: [2, 4, 6], each(x): {$eval: "x + a"}}
---
title: escape $match
context: {x: 1}
template: {$$match: [{'x == 1': 2}]}
result: {$match: [{'x == 1': 2}]}
---
title: escape $switch
context: {x: 1}
template: {$$switch: [{'x == 1': 2}]}
result: {$switch: [{'x == 1': 2}]}
---
title: escape $merge
context: {}
template: {$$merge: [{a: 1}, {a: 2}]}
result: {$merge: [{a: 1}, {a: 2}]}
---
title: escape $reverse
context: {}
template: {$$reverse: [3, 2, 1]}
result: {$reverse: [3, 2, 1]}
---
title: escape $sort
context: {}
template: {$$sort: [3, 2, 1]}
result: {$sort: [3, 2, 1]}
---
title: reserved $-keywords
context: {}
template: {$nothing: 1}
error: 'TemplateError: $<identifier> is reserved; use $$<identifier>'
---
title: escape non-json-e operator
context: {}
template: {$$nothing: 1}
result: {$nothing: 1}
---
title: two escaped operators
context: {}
template: {$$map: 1, $$let: 2}
result: {$map: 1, $let: 2}
---
section: $flatten
---
title: simple flatten
context: {}
template: {$flatten: [[1, 2], [3, 4], [5]]}
result: [1, 2, 3, 4, 5]
---
title: flatten empty array
context: {}
template: {$flatten: []}
result: []
---
title: flatten empty array of arrays
context: {}
template: {$flatten: [[]]}
result: []
---
title: flatten evaluated value
context: {}
template: {$flatten: {$eval: '[[1], [2, 3]]'}}
result: [1, 2, 3]
---
title: flatten null
context: {}
template: {$flatten: null}
error: 'TemplateError: $flatten value must evaluate to an array'
---
title: flatten an object
context: {}
template: {$flatten: {a: 1, b: 2}}
error: 'TemplateError: $flatten value must evaluate to an array'
---
title: flatten an array of strings
context: {}
template: {$flatten: ["a", "b"]}
result: ["a", "b"]
---
title: flatten an array of numbers
context: {}
template: {$flatten: [1, 2]}
result: [1, 2]
---
title: flatten mixed types
context: {}
template: {$flatten: [[1, 2], [['a', 'b']], [{}], [[]]]}
result: [1, 2, ['a', 'b'], {}, []]
---
title: flatten mixed levels
context: {}
template: {$flatten: [[1, [2, 3]], [4], 5]}
result: [1, [2, 3], 4, 5]
---
title: flatten with undefined properties
context: {}
template: {$flatten: {$eval: '[[1], [2, 3]]'}, foo: 'bar'}
error: 'TemplateError: $flatten has undefined properties: foo'
---
section: $flattenDeep
---
title: simple flattenDeep
context: {}
template: {$flattenDeep: [[1, [2, [3]]]]}
result: [1, 2, 3]
---
title: flattenDeep empty array
context: {}
template: {$flattenDeep: []}
result: []
---
title: evaluated value
context: {}
template: {$flattenDeep: {$eval: '[[1], [2, [3]]]'}}
result: [1, 2, 3]
---
title: flattenDeep empty array of arrays
context: {}
template: {$flattenDeep: [[]]}
result: []
---
title: flattenDeep null
context: {}
template: {$flattenDeep: null}
error: 'TemplateError: $flattenDeep value must evaluate to an array'
---
title: flattenDeep an object
context: {}
template: {$flattenDeep: {a: 1, b: 2}}
error: 'TemplateError: $flattenDeep value must evaluate to an array'
---
title: flattenDeep an array of strings
context: {}
template: {$flattenDeep: ["a", "b"]}
result: ["a", "b"]
---
title: flattenDeep an array of numbers
context: {}
template: {$flattenDeep: [1, 2]}
result: [1, 2]
---
title: flattenDeep mixed types
context: {}
template: {$flattenDeep: [[1, 2], [['a', 'b']], [{}], [[]]]}
result: [1, 2, 'a', 'b', {}]
---
title: flattenDeep mixed levels
context: {}
template: {$flattenDeep: [[1, [2, 3]], [4], 5]}
result: [1, 2, 3, 4, 5]
---
title: flattenDeep with undefined properties
context: {}
template: {$flattenDeep: [[1, [2, 3]], [4], 5], foo: 'bar'}
error: 'TemplateError: $flattenDeep has undefined properties: foo'
---
section: $fromNow
---
title: $fromNow 1 years
context: {}
template: {$fromNow: '1 years'}
result: '2018-01-19T16:27:20.974Z'
---
title: $fromNow 1 year
context: {}
template: {$fromNow: '1 year'}
result: '2018-01-19T16:27:20.974Z'
---
title: $fromNow 1 yr
context: {}
template: {$fromNow: '1 yr'}
result: '2018-01-19T16:27:20.974Z'
---
title: $fromNow 1 y
context: {}
template: {$fromNow: '1 y'}
result: '2018-01-19T16:27:20.974Z'
---
title: $fromNow 1 months
context: {}
template: {$fromNow: '1 months'}
result: '2017-02-18T16:27:20.974Z'
---
title: $fromNow 1 month
context: {}
template: {$fromNow: '1 month'}
result: '2017-02-18T16:27:20.974Z'
---
title: $fromNow 30 mo
context: {}
template: {$fromNow: '30 mo'}
result: '2019-07-08T16:27:20.974Z'
---
title: $fromNow -30 mo
context: {}
template: {$fromNow: '-30 mo'}
result: '2014-08-03T16:27:20.974Z'
---
title: $fromNow 1 weeks
context: {}
template: {$fromNow: '1 weeks'}
result: '2017-01-26T16:27:20.974Z'
---
title: $fromNow 1 week
context: {}
template: {$fromNow: '1 week'}
result: '2017-01-26T16:27:20.974Z'
---
title: $fromNow 1 wk
context: {}
template: {$fromNow: '1 wk'}
result: '2017-01-26T16:27:20.974Z'
---
title: $fromNow 1 w
context: {}
template: {$fromNow: '1 w'}
result: '2017-01-26T16:27:20.974Z'
---
title: $fromNow 2 days
context: {}
template: {$fromNow: '2 days'}
result: '2017-01-21T16:27:20.974Z'
---
title: $fromNow 2 day
context: {}
template: {$fromNow: '2 day'}
result: '2017-01-21T16:27:20.974Z'
---
title: $fromNow 2 d
context: {}
template: {$fromNow: '2 d'}
result: '2017-01-21T16:27:20.974Z'
---
title: $fromNow 2 hours
context: {}
template: {$fromNow: '2 hours'}
result: '2017-01-19T18:27:20.974Z'
---
title: $fromNow -1 hour
context: {}
template: {$fromNow: '-1 hour'}
result: '2017-01-19T15:27:20.974Z'
---
title: $fromNow 1 hour
context: {}
template: {$fromNow: '1 hour'}
result: '2017-01-19T17:27:20.974Z'
---
title: $fromNow 3h
context: {}
template: {$fromNow: '3h'}
result: '2017-01-19T19:27:20.974Z'
---
title: $fromNow 1 minutes
context: {}
template: {$fromNow: '1 minutes'}
result: '2017-01-19T16:28:20.974Z'
---
title: $fromNow 1 m
context: {}
template: {$fromNow: '1 minute'}
result: '2017-01-19T16:28:20.974Z'
---
title: $fromNow 1 m
context: {}
template: {$fromNow: '1 minute'}
result: '2017-01-19T16:28:20.974Z'
---
title: $fromNow 12 min
context: {}
template: {$fromNow: '12 min'}
result: '2017-01-19T16:39:20.974Z'
---
title: $fromNow 12min
context: {}
template: {$fromNow: '12min'}
result: '2017-01-19T16:39:20.974Z'
---
title: $fromNow 1m
context: {}
template: {$fromNow: '1m'}
result: '2017-01-19T16:28:20.974Z'
---
title: $fromNow 11m
context: {}
template: {$fromNow: '11m'}
result: '2017-01-19T16:38:20.974Z'
---
title: $fromNow 11 m
context: {}
template: {$fromNow: '11 m'}
result: '2017-01-19T16:38:20.974Z'
---
title: $fromNow 1 seconds
context: {}
template: {$fromNow: '1 seconds'}
result: '2017-01-19T16:27:21.974Z'
---
title: $fromNow 1 second
context: {}
template: {$fromNow: '1 second'}
result: '2017-01-19T16:27:21.974Z'
---
title: $fromNow 1 sec
context: {}
template: {$fromNow: '1 sec'}
result: '2017-01-19T16:27:21.974Z'
---
title: $fromNow 1 s
context: {}
template: {$fromNow: '1 s'}
result: '2017-01-19T16:27:21.974Z'
---
title: $fromNow multiple units
context: {}
template: {$fromNow: '1y2mo3w4d5h6m7s'}
result: '2018-04-14T21:33:27.974Z'
---
title: $fromNow multiple units with whitespace
context: {}
template: {$fromNow: '1 y 2 mo 3 w 4 d 5 h 6 m 7 s'}
result: '2018-04-14T21:33:27.974Z'
---
title: $fromNow multiple units positive
context: {}
template: {$fromNow: '+1y2mo3w4d5h6m7s'}
result: '2018-04-14T21:33:27.974Z'
---
title: $fromNow multiple units negative
context: {}
template: {$fromNow: '-1y2mo3w4d5h6m7s'}
result: '2015-10-27T11:21:13.974Z'
---
title: $fromNow multiple units out of order
context: {}
template: {$fromNow: '1s 1 y'}
error: true
---
title: $fromNow of non-string
context: {}
template: {$fromNow: 13}
error: 'TemplateError: $fromNow expects a string'
---
title: $fromNow with eval
context: {ttl: 24}
template: {$fromNow: {$eval: 'str(ttl) + " hours"'}}
result: '2017-01-20T16:27:20.974Z'
---
title: $fromNow with redefined `now`
context: {}
template: {$let: {now: '2019-01-01T01:00:00.123Z'}, in: {$fromNow: '3 mo'}}
result: '2019-04-01T01:00:00.123Z'
---
title: $fromNow with reference
context: {when: '2019-01-01T01:00:00.123Z'}
template: {$fromNow: '3 mo', from: {$eval: when}}
result: '2019-04-01T01:00:00.123Z'
---
title: $fromNow with undefined properties
context: {now: '2019-01-01T01:00:00.123Z'}
template: {$fromNow: '3 mo', from: {$eval: now}, foo: 'bar'}
error: 'TemplateError: $fromNow has undefined properties: foo'
---
section: $json
---
title: wrap expressions with $eval
context: {a: 1, b: 2}
template: {$json: {$eval: 'a + b + 7'}}
result: '10'
---
title: unwrap expressions not evaluated
context: {a: 1, b: 2}
template: {$json: 'a + b + 7'}
result: '"a + b + 7"'
---
title: $eval inside array
context: {a: 1, b: 2}
template: {$json: [2, 5, {$eval: 'a + b + 7'}]}
result: '[2,5,10]'
---
title: ASCII non-printable character is u-escaped
context: {}
template: {$json: ["\x10"]}
result: "[\"\\u0010\"]"
---
title: ASCII printable character is not escaped
context: {}
template: {$json: ["Z"]}
result: "[\"Z\"]"
---
title: Unicode BMP character is not escaped
context: {}
template: {$json: ["ă"]}
result: "[\"ă\"]"
---
title: sorting pairs by unicode key strings sorts lexically by codepoint
context: {}
template: {$json: {"\u3347\u0050": 1, "\uE1FF\u0100": 2, "\u0055\u0045": 3}}
result: "{\"\u0055\u0045\":3,\"\u3347\u0050\":1,\"\uE1FF\u0100\":2}"
---
title: sorting pairs by unicode key strings sorts lexically by codepoint, even with chars above base plane
context: {}
template: {$json: {"\U0001F809\u732b":'hey', "Z\U00010000P": 1, "\U000E1FFF\u0103": 2, "UaE": 3}}
result: "{\"UaE\":3,\"Z\U00010000P\":1,\"\U0001F809\u732b\":\"hey\",\"\U000E1FFF\u0103\":2}"
---
title: $json with undefined properties
context: {}
template: {$json: [1,2,true,{},[]], foo: 'bar'}
error: 'TemplateError: $json has undefined properties: foo'
---
title: $json can be evaluated to null without an error
context: {input: null}
template: {$json: { '$eval': 'input' } }
result: 'null'
---
section: accessing nested objects => context
---
title: $eval
context: {key: {key2: ['value', 1, 2, true, {}]}}
template: {$eval: 'key.key2'}
result: ['value', 1, 2, true, {}]
---
title: $json
context: {key: {key2: [1,2,true,{},[]]}}
template: {$json: {$eval: 'key.key2'}}
result: '[1,2,true,{},[]]'
---
section: string interpolation
---
title: string interpolation
context: {key: {key2: 'world', key3: 1}}
template: {message: 'hello ${key.key2}', 'k-${key.key3}': true}
result: {message: 'hello world', 'k-1': true}
---
title: string interpolation, first character
context: {somevalue: 13}
template: {message: '${somevalue}'}
result: {message: '13'}
---
title: no string interpolation with $$
context: {somevalue: 13}
template: {message: '$${somevalue}'}
result: {message: '${somevalue}'}
---
title: unterminated string interpolation
context: {}
template: {message: '${somevalue'}
error: "SyntaxError at template.message: unterminated ${..} expression"
---
section: $let
---
title: simple let
template: {$let: {ts: 100, foo: 200,}, in: [{$eval: "ts+foo"}, {$eval: "ts-foo"}, {$eval: "ts*foo"}]}
context: {}
result: [300, -100, 20000]
---
title: let with evaluated values
template: {$let: {thirty: {$eval: "10 + 20"}}, in: {$eval: "thirty+5"}}
context: {}
result: 35
---
title: let with evaluated context
template: {$let: {$eval: '{"thirty": 10 + 20}'}, in: {$eval: "thirty+5"}}
context: {}
result: 35
---
title: context overriding
template: {$let: {x: 20}, in: {$eval: "x + y"}}
context: {x: 10, 'y': 1}
result: 21
---
title: nested let
template: {$let: {x: 20,'y': 10}, in: {$let: {x: 30}, in: {$eval: "x + y + z"}}}
context: {x: 1,'y': 2, z: 3}
result: 43
---
title: let with undefined properties
template: {$let: {x: 1,'y': 2}, a: {$eval: "x + y"}}
context: {}
error: 'TemplateError: $let has undefined properties: a'
---
title: let without in
template: {$let: {x: 1,'y': 2}}
context: {}
error: 'TemplateError: $let operator requires an `in` clause'
---
title: let array
template: {$let: [1, 2], in: {$eval: "1 + 2"}}
context: {}
error: 'TemplateError: $let value must be an object'
---
title: let null
template: {$let: null, in: {$eval: "1 + 2"}}
context: {}
error: 'TemplateError: $let value must be an object'
---
title: checking name begin with number
context: {}
template: {$let: {ab: 100, bb: 200, 2b: 5}, in: [{$eval: "ab+bb"}, {$eval: "ab-bb"}, {$eval: "ab*bb"}]}
error: 'TemplateError: top level keys of $let must follow /[a-zA-Z_][a-zA-Z0-9_]*/'
---
title: checking space in variable name
context: {}
template: {$let: {ab: 100, bb: 200, "a b": 10}, in: [{$eval: "ab+bb"}, {$eval: "ab-bb"}, {$eval: "ab*bb"}]}
error: 'TemplateError: top level keys of $let must follow /[a-zA-Z_][a-zA-Z0-9_]*/'
---
title: checking special character in variable name
context: {}
template: {$let: {ab: 100, bb: 200, "a.b": 10}, in: [{$eval: "ab+bb"}, {$eval: "ab-bb"}, {$eval: "ab*bb"}]}
error: 'TemplateError: top level keys of $let must follow /[a-zA-Z_][a-zA-Z0-9_]*/'
---
title: checking empty name
context: {}
template: {$let: {"": 10}, in: []}
error: 'TemplateError: top level keys of $let must follow /[a-zA-Z_][a-zA-Z0-9_]*/'
---
title: checking integrity of operation $let with exact result
context: {}
template: {$let: {ts: 100, foo: 200}, in: [{$eval: "ts+foo"}, {$eval: "ts-foo"}, {$eval: "ts*foo"}]}
result: [300, -100, 20000]
---
title: checking $let and $reverse operator integrity
context: {}
template: {$let: {x: [1, 2, 3]}, in: [$reverse: {$eval: "x"}]}
result: [[ 3, 2, 1 ]]
---
title: checking $let with $if without else
context: {c: 'itm'}
template: {$let: {a: {$if: 'c == "item"', then: 'value'}}, in: {a: '${a}'}}
error: 'InterpreterError at template.a: unknown context value a'
---
title: let with a value of $if-then-else
template: {$let: {$if: something == 3, then: {a: 10, b: 20}, else: {a: 20, b: 10}}, in: {$eval: 'a + b'}}
context: {'something': 3}
result: 30
---
title: let with a rendered key
template: {$let: {"first_${name}": 1, "second_${name}": 2}, in: {$eval: "first_prize + second_prize"}}
context: {name: "prize"}
result: 3
---
title: let using values from the parent context
template: {$let: {"b": {$eval: "a + 10"}}, in: {$eval: "a + b"}}
context: {a: 5}
result: 20
---
title: let with a non-object rendered value (array)
template: {$let: {$eval: "[1, 2]"}, in: "uhoh"}
context: {}
error: 'TemplateError: $let value must be an object'
---
title: let with a non-object rendered value (string)
template: {$let: "${name}", in: "uhoh"}
context: {name: "fido"}
error: 'TemplateError: $let value must be an object'
---
title: let with a non-object rendered value (boolean)
template: {$let: {$eval: "true"}, in: "uhoh"}
context: {}
error: 'TemplateError: $let value must be an object'
---
title: fromNow with redefined `now`
context: {}
template: {$let: {now: '2017-01-01T01:00:00.123Z'}, in: {$eval: "fromNow('1 day')"}}
result: '2017-01-02T01:00:00.123Z'
---
title: defined with empty variable from a let expression
context: {}
template: {$let: {var: 10}, in: {$if: "defined('var')", then: 't', else: 'f'}}
result: t
---
title: $let with nested redefinitions of builtins
context: {}
template:
$let: {lowercase: {$eval: uppercase}}
in:
$let: {var: 10}
in:
$if: "defined('var')"
then: "${lowercase('t')}" else: "${lowercase('f')}"
result: T
---
title: $let with nested redefinitions of builtins
context: {}
template:
$let: {fromNow: {$eval: uppercase}}
in:
$let: {var: 10}
in:
$if: "defined('var')"
then: "${fromNow('1 hour')}"
else: "f"
result: '1 HOUR'
---
title: $let doesn't leak variables
context: {}
template:
- $let:
foo: 'bar'
baz: 'qux'
in: {$eval: 'foo'}
- $eval: 'foo'
error: 'InterpreterError at template[1]: unknown context value foo'
---
section: $map
---
title: simple map
context: {a: 1}
template:
$map: [2, 4, 6]
each(x): {$eval: 'x + a'}
result: [3, 5, 7]
---
title: map to objects
context: {a: 1}
template:
$map: [2, 4, 6]
each(x):
asText: '${x + a}'
integer: {$eval: 'x + a'}
result:
- {asText: '3', integer: 3}
- {asText: '5', integer: 5}
- {asText: '7', integer: 7}
---
title: complex identifier
context: {a: 1}
template:
$map: [2, 4, 6]
each(my_identifier97): {$eval: 'my_identifier97 + a'}
result: [3, 5, 7]
---
title: must wrap expressions with $eval
context: {a: 1}
template:
$map: [2, 4, 6]
each(my_identifier97): 'my_identifier97 + a'
result: ['my_identifier97 + a', 'my_identifier97 + a', 'my_identifier97 + a']
---
title: can take from objects
context: {a: 1}
template:
$map: [{k: 1}, {k: 2}, {k: 3}]
each(y): {$eval: 'y.k'}
result: [1, 2, 3]
---
title: value is rendered
context: {a: 1}
template:
$map: {$eval: '[{k: 1}, {k: 2}, {k: 3}]'}
each(y): {$eval: 'y.k'}
result: [1, 2, 3]
---
title: can make objects too
context: {a: 1}
template:
$map: [{k: 1}, {k: 2}, {k: 3}]
each(y):
k: {$eval: 'y.k + 1'}
v: 'before=${y.k}'
result:
- k: 2
v: 'before=1'
- k: 3
v: 'before=2'
- k: 4
v: 'before=3'
---
title: respects delete-marker from $if
context: {a: 1}
template:
$map: [{k: 1}, {k: 2}, {k: 3}]
each(y):
$if: 'y.k != 2'
then: {$eval: 'y.k'}
result: [1, 3]
---
title: $map works on object
context: {}
template:
$map: {a: 1, b: 2, c: 3}
each(y): {'${y.key}x': {$eval: 'y.val + 1'}}
result: {ax: 2, bx: 3, cx: 4}
---
title: $map each(value,key) on object
context: {}
template:
$map: {a: 1, b: 2, c: 3}
each(v,k): {'${k}x': {$eval: 'v + 1'}}
result: {ax: 2, bx: 3, cx: 4}
---
title: $map can add new keys to object
context: {}
template:
$map: {a: 1, b: 2, c: 3}
each(y): {'${y.key}': {$eval: 'y.val'}, '${y.key}x': {$eval: 'y.val + 1'}}
result: {a: 1, b: 2, c: 3, ax: 2, bx: 3, cx: 4}
---
title: $map array index variable
context: {}
template:
$map: ['a', 'b', 'c']
each(y,i): '${y}-${i}'
result: ['a-0','b-1','c-2']
---
title: $map no args
context: {}
template:
$map: "a, b, c"
each(): {$eval: 'y.k'}
error: 'TemplateError: $map has undefined properties: each()'
---
title: $map too many args
context: {}
template:
$map: "a, b, c"
each(k,v,i): {$eval: 'y.k'}
error: 'TemplateError: $map has undefined properties: each(k,v,i)'
---
title: $map requires an array, not string
context: {}
template:
$map: "a, b, c"
each(y): {$eval: 'y.k'}
error: 'TemplateError: $map value must evaluate to an array or object'
---
title: $map requires an array, not number
context: {}
template:
$map: 10.1
each(y): {$eval: 'y.k'}
error: 'TemplateError: $map value must evaluate to an array or object'
---
title: $map requires an array, not null
context: {}
template:
$map: null
each(y): {$eval: 'y.k'}
error: 'TemplateError: $map value must evaluate to an array or object'
---
title: map with undefined properties
context: {a: 1}
template:
$map: [2, 4, 6]
each(x): {$eval: 'x + a'}
foo: 'bar'
error: 'TemplateError: $map has undefined properties: foo'
---
title: $map as object and each(identifier) as array
context: {}
template:
$map: {"hello": 5, "test": 9}
each(x): ['${x.key}', {$eval: 'x.val+1'}]
error: 'TemplateError: $map on objects expects each(x) to evaluate to an object'
---
title: $map over object, two vars
context: {}
template: { $map: {a: 1, b: 2, c: 3}, 'each(v,k)': {'${k}x': {$eval: 'v + 1'}} }
result: {ax: 2, bx: 3, cx: 4}
---
title: $map over object, one var
context: {}
template: {$map: {a: 1, b: 2, c: 3}, 'each(y)': {'${y.key}x': {$eval: 'y.val + 1'}}}
result: {ax: 2, bx: 3, cx: 4}
---
section: range
---
title: range without step creates list of numbers
context: {}
template:
$map: {$eval: 'range(1, 5)'}
each(x): {$eval: 'x'}
result: [1, 2, 3, 4]
---
title: range with end > start creates empty list
context: {}
template:
{$eval: 'len(range(5, 1))'}
result: 0
---
title: range with step creates list of numbers
context: {}
template:
$map: {$eval: 'range(1, 10, 2)'}
each(x): {$eval: 'x'}
result: [1, 3, 5, 7, 9]
---
title: range with negative step creates list of numbers
context: {}
template:
$map: {$eval: 'range(1, -2, -1)'}
each(x): {$eval: 'x'}
result: [1, 0, -1]
---
title: range with negative step and negative start and end creates list of numbers
context: {}
template:
$map: {$eval: 'range(-7, -10, -1)'}
each(x): {$eval: 'x'}
result: [-7, -8, -9]
---
title: range with negative step that does not divide evenly
context: {}
template:
$map: {$eval: 'range(20, 0, -7)'}
each(x): {$eval: 'x'}
result: [20, 13, 6]
---
title: range with step=0 throws error
context: {}
template:
$map: {$eval: 'range(1, 5, 0)'}
each(x): {$eval: 'x'}
error: true
---
title: range with float step throws error
context: {}
template:
$map: {$eval: 'range(1, 5, 1.2)'}
each(x): {$eval: 'x'}
error: true
---
title: range with float start throws error
context: {}
template:
$map: {$eval: 'range(1.3, 5)'}
each(x): {$eval: 'x'}
error: true
---
title: range with string start throws error
context: {}
template:
$map: {$eval: 'range("1", 5)'}
each(x): {$eval: 'x'}
error: true
---
title: range without step creates list of objects
context: {}
template:
$map: {$eval: 'range(1, 4)'}
each(x):
asText: '${x}'
integer: {$eval: 'x'}
result:
- {asText: '1', integer: 1}
- {asText: '2', integer: 2}
- {asText: '3', integer: 3}
---
title: range without step creates list of strings
context: {}
template:
$map: {$eval: 'range(10, 12)'}
each(x,i): 'id_${x}_${i}'
result: ['id_10_0', 'id_11_1']
---
title: range with step creates list of strings
context: {}
template:
$map: {$eval: 'range(10, 20, 5)'}
each(x,i): 'id_${x}_${i}'
result: ['id_10_0', 'id_15_1']
---
title: range without step creates objects
context: {}
template:
$map: {$eval: 'range(1, 3)'}
each(y):
k: {$eval: 'y + 1'}
v: 'before=${y}'
result:
- k: 2
v: 'before=1'
- k: 3
v: 'before=2'
---
section: $reduce operator
---
title: reduce array into number
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x): {$eval: 'acc + x'}
initial: 0
result: 12
---
title: reduce array with indexes into number
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x, i): {$eval: 'acc + x * 10 ** i'}
initial: 0
result: 642
---
title: reduce array into string
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x): "${acc}${x}"
initial: 'pre '
result: 'pre 246'
---
title: reduce array into boolean
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x): {$eval: 'acc || x > 5'}
initial: false
result: true
---
title: reduce array into object
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x, i):
$merge: [{$eval: 'acc'}, {'k${i}': {$eval: 'x'}}]
initial: {a: 0}
result: { a: 0, k0: 2, k1: 4, k2: 6 }
---
title: reduce over an object
context: {}
template:
$reduce: {a: 2, b: 4, c: 6}
each(acc, v, k): {$eval: 'acc + v'}
initial: 0
error: 'TemplateError: $reduce value must evaluate to an array'
---
title: reduce skips delete-marker from $if
context: {}
template:
$reduce: [2, 4, 6]
initial: 0
each(acc, v, i):
$if: 'v != 4'
then: {$eval: 'acc + v'}
result: 8
---
title: reduce with undefined properties
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x): {$eval: 'acc + x'}
initial: 0
foo: 'bar'
error: 'TemplateError: $reduce has undefined properties: foo'
---
title: reduce with missing initial
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x): {$eval: 'acc + x'}
error: 'TemplateError: $reduce must have exactly three properties'
---
title: reduce with missing initial with undefined properties
context: {}
template:
$reduce: [2, 4, 6]
each(acc, x): {$eval: 'acc + x'}
init: 9
error: 'TemplateError: $reduce has undefined properties: init'
---
title: reduce with missing each
context: {}
template:
$reduce: [2, 4, 6]
initial: 0
error: 'TemplateError: $reduce must have exactly three properties'
---
title: reduce with missing each with undefined properties
context: {}
template:
$reduce: [2, 4, 6]
each: 'acc + x'
initial: 0
error: 'TemplateError: $reduce has undefined properties: each'
---
title: reduce over a number
context: {}
template:
$reduce: 10
each(acc, x): {$eval: 'acc + x'}
initial: 0
error: 'TemplateError: $reduce value must evaluate to an array'
---
title: reduce over a string
context: {}
template:
$reduce: A Thing that is a String
each(acc, x): {$eval: 'acc + x'}
initial: 0
error: 'TemplateError: $reduce value must evaluate to an array'
---
section: $find operator
---
title: $find, simple find
context: {}
template: {$find: [2, 4, 6], each(x): 'x == 2' }
result: 2
---
title: $find, simple find with context
context: {a: 2}
template: {$find: [2, 4, 6], each(x): 'x == a' }
result: 2
---
title: $find respects delete marker
context: {}
template: {a: 1, b: {$find: [1,2,3], 'each(x)': 'x > 4' }}
result: {a: 1}
---
title: $find, complicated find with $let
context: {}
template:
$let:
needle:
$find: [1, 2, 3]
each(entry): entry == 2
in:
$eval: needle
result: 2
---
title: $find complex identifier
context: {a: 1}
template:
$find: [2, 4, 6]
each(my_identifier97): 'my_identifier97 == 1 || my_identifier97 == 4'
result: 4
---
title: $find array index variable
context: {}
template:
$find: [1, 2, 3]
each(y,i): 'i == 2'
result: 3
---
title: $find no args
context: {}
template:
$find: [1, 2, 3]
each(): 'y.k'
error: 'TemplateError: $find has undefined properties: each()'
---
title: $find too many args
context: {}
template:
$find: [1, 2, 3]
each(k,v,i): 'y.k'
error: 'TemplateError: $find has undefined properties: each(k,v,i)'
---
title: $find requires an array, not string
context: {}
template:
$find: "a, b, c"
each(y): 'y.k'
error: 'TemplateError: $find value must evaluate to an array'
---
title: $find requires an array, not number
context: {}
template:
$find: 10.1
each(y): 'y.k'
error: 'TemplateError: $find value must evaluate to an array'
---
title: $find requires an array, not null
context: {}
template:
$find: null
each(y): 'y.k'
error: 'TemplateError: $find value must evaluate to an array'
---
title: $find requires an array, not object
context: {}
template:
$find: {a: 1}
each(y): 'y.k'
error: 'TemplateError: $find value must evaluate to an array'
---
title: $find with undefined properties
context: {a: 1}
template:
$find: [2, 4, 6]
each(x): 'x + a'
foo: 'bar'
error: 'TemplateError: $find has undefined properties: foo'
---
title: $find each must be string, not number
context: {}
template:
$find: [1,2,3]
each(a): 1
error: 'TemplateError: each can evaluate string expressions only'
---
title: $find each must be string, not object
context: {}
template:
$find: [1,2,3]
each(a): {a: 1}
error: 'TemplateError: each can evaluate string expressions only'
---
section: $match operator
---
title: $match, 2 matches, ordered by lexcial sorting of property names
context: {cond: 3}
template: {$match: {'cond == 3': 2, 'cond == 5': 3, 'cond < 5 && cond > 0': 4, 'true': 17}}
result: [4, 2, 17]
---
title: $match, no matches
context: {cond: 3}
template: {$match: {'cond > 5': 2, 'cond == 5': 3, 'cond == 4 || cond < 1': 4}}
result: []
---
title: $match, 1 match in array
context: {cond: 3}
template: [0, $match: {'cond == 3': 2, 'cond == 5': 3}]
result: [0, [2]]
---
title: $match, 0 matches in array
context: {cond: 3}
template: [0, $match: {'cond > 3': 2, 'cond == 5': 3}]
result: [0, []]
---
title: $match, 1 match in object
context: {cond: 3}
template: {key: 0, banana: {$match: {'cond == 3': 2, 'cond == 5': 3}}}
result: {key: 0, banana: [2]}
---
title: $match, 0 matches in object
context: {cond: 3}
template: {key: 0, banana: {$match: {'cond > 3': 2, 'cond == 5': 3}}}
result: {key: 0, banana: []}
---
title: $match, is not an object
context: {cond: 3}
template: {$match: [{'cond < 5 && cond > 0': 2}]}
error: 'TemplateError: $match can evaluate objects only'
---
title: $match, value that also needs evaluation
context: {cond: 3, ifcond: false}
template: {$match: {'cond == 3': {$if: 'ifcond', then: "t", else: "f"}}}
result: ["f"]
---
section: $switch operator
---
title: $switch, 1 match
context: {cond: 3}
template: {$switch: {'cond == 3': 2, 'cond == 5': 3}}
result: 2
---
title: $switch, 2 matches
context: {cond: 3}
template: {$switch: {'cond == 3': 2, 'cond > 1': 3}}
error: 'TemplateError: $switch can only have one truthy condition'
---
title: $switch, no matches
context: {cond: 3}
template: {$switch: {'cond > 5': 2, 'cond == 5': 3, 'cond == 4 || cond < 1': 4}}
result: null
---
title: $switch, 1 match in array
context: {cond: 3}
template: [0, $switch: {'cond == 3': 2, 'cond == 5': 3}]
result: [0, 2]
---
title: $switch, 0 matches in array
context: {cond: 3}
template: [0, $switch: {'cond > 3': 2, 'cond == 5': 3}]
result: [0]
---
title: $switch, 1 match in object
context: {cond: 3}
template: {key: 0, banana: {$switch: {'cond == 3': 2, 'cond == 5': 3}}}
result: {key: 0, banana: 2}
---
title: $switch, 0 matches in object
context: {cond: 3}
template: {key: 0, banana: {$switch: {'cond > 3': 2, 'cond == 5': 3}}}
result: {key: 0}
---
title: $switch, is not an object
context: {cond: 3}
template: {$switch: [{'cond < 5 && cond > 0': 2}]}
error: 'TemplateError: $switch can evaluate objects only'
---
title: $switch, value that also needs evaluation
context: {cond: 3, ifcond: false}
template: {$switch: {'cond == 3': {$if: 'ifcond', then: "t", else: "f"}}}
result: "f"
---
title: $switch, fallback to $default
context: {cond: 4}
template: {$switch: {'cond == 3': 1, $default: 'fallback'}}
result: "fallback"
---
title: $switch, $default value that also needs evaluation
context: {cond: 4, ifcond: false}
template: {$switch: {'cond == 3': 1, $default: {$if: 'ifcond', then: "t", else: "f"}}}
result: "f"
---
title: $switch, $default with 1 match in object
context: {cond: 3}
template: {$switch: {'cond == 3': 1, $default: 'fallback'}}
result: 1
---
title: $switch, $default of empty string
context: {}
template: {$switch: {'false': 1, $default: ''}}
result: ''
---
title: $switch, $default of empty string not a deletion marker
context: {}
template: [{$switch: {'false': 1, $default: ''}}]
result: ['']
---
title: $switch, $default of false
context: {}
template: {$switch: {'false': 1, $default: false}}
result: false
---
title: $switch, $default of false not a deletion marker
context: {}
template: [{$switch: {'false': 1, $default: false}}]
result: [false]
---
title: $switch, $default of null
context: {}
template: {$switch: {'false': 1, $default: null}}
result: null
---
title: $switch, $default of null not a deletion marker
context: {}
template: [{$switch: {'false': 1, $default: null}}]
result: [null]
---
title: $switch, $default of 0
context: {}
template: {$switch: {'false': 1, $default: 0}}
result: 0
---
title: $switch, $default of 0 not a deletion marker
context: {}
template: [{$switch: {'false': 1, $default: 0}}]
result: [0]
---
section: $merge
---
title: simple merge
context: {}
template: {$merge: [{a: 1, b: 1}, {b: 2, c: 3}, {d: 4}]}
result: {a: 1, b: 2, c: 3, d: 4}
---
title: value is evaluated
context: {defaults: {d: 4}}
template: {$merge: [{a: 1, b: 1}, {b: 2, c: 3}, {$eval: defaults}]}
result: {a: 1, b: 2, c: 3, d: 4}
---
title: merge empty array
context: {}
template: {$merge: []}
result: {}
---
title: merge empty array with empty object
context: {}
template: {$merge: [{}]}
result: {}
---
title: merge null
context: {}
template: {$merge: null}
error: 'TemplateError: $merge value must evaluate to an array of objects'
---
title: $merge [null]
template: {$merge: [null]}
context: {}
error: 'TemplateError: $merge value must evaluate to an array of objects'
---
title: merge with undefined properties
template: {$merge: [{a: 1}, {b: 2, c: 3}, {d: 4}], foo: "bar", bing: "baz"}
context: {}
error: 'TemplateError: $merge has undefined properties: bing foo'
---
section: $mergeDeep
---
title: simple non-deep mergeDeep matches merge
context: {}
template: {$mergeDeep: [{a: 1, b: 1}, {b: 2, c: 3}, {d: 4}]}
result: {a: 1, b: 2, c: 3, d: 4}
---
title: deep merge of lists appends
context: {}
template: {$mergeDeep: [{a: [1, 2]}, {a: [3, 4]}]}
result: {a: [1, 2, 3, 4]}
---
title: deep merge of objects merges
context: {}
template: {$mergeDeep: [{a: {x: 1,'y': 2}}, {a: {'y': 3, z: 4}}]}
result: {a: {x: 1,'y': 3, z: 4}}
---
title: very deep merge
context: {}
template:
$mergeDeep:
- task:
payload:
command: [a, b]
- task:
extra:
foo: bar
- task:
payload:
command: [c]
result:
task:
extra:
foo: bar
payload:
command: [a, b, c]
---
title: value is evaluated
context: {defaults: {d: 4}}
template: {$mergeDeep: [{a: 1, b: 1}, {b: 2, c: 3}, {$eval: defaults}]}
result: {a: 1, b: 2, c: 3, d: 4}
---
title: mergeDeep empty array
context: {}
template: {$mergeDeep: []}
result: {}
---
title: mergeDeep empty array with empty object
context: {}
template: {$mergeDeep: [{}]}
result: {}
---
title: mergeDeep null
context: {}
template: {$mergeDeep: null}
error: 'TemplateError: $mergeDeep value must evaluate to an array of objects'
---
title: $mergeDeep [null]
template: {$mergeDeep: [null]}
context: {}
error: 'TemplateError: $mergeDeep value must evaluate to an array of objects'
---
title: mergeDeep with undefined properties
template: {$mergeDeep: [{a: {x: 1,'y': 2}}, {a: {'y': 3, z: 4}}], foo: "bar", bing: "baz"}
context: {}
error: 'TemplateError: $mergeDeep has undefined properties: bing foo'
---
section: $sort
---
title: simple sort
context: {}
template: {$sort: [3, 4, 1, 2]}
result: [1, 2, 3, 4]
---
title: simple sort of strings (shortest first)
context: {}
template: {$sort: ['android', 'aardvark', 'add', 'adderall']}
result: ['aardvark', 'add', 'adderall', 'android']
---
title: simple sort of multi-digit numbers
context: {}
template: {$sort: [111, 22, 3]}
result: [3, 22, 111]
---
title: sort of mixed array
context: {}
template: {$sort: [1, "2", 2, 3, "111", "112"]}
error: true
---
title: simple sort with $eval
context: {array: [3, 4, 1, 2]}
template: {$sort: {$eval: 'array'}}
result: [1, 2, 3, 4]
---
title: sort by, returning number
context: {}
template:
$sort: [{a: 20}, {a: 10, b: []}, {a: 3}]
by(x): 'x.a'
result: [{a: 3}, {a: 10, b: []}, {a: 20}]
---
title: sort by, returning string
context: {}
template:
$sort: [{s: 'android'}, {s: 'add'}, {s: 'adderall'}]
by(x): 'x.s'
result: [{s: 'add'}, {s: 'adderall'}, {s: 'android'}]
---
title: cannot sort objects without by
context: {}
template:
$sort: [{a: 2}, {a: 1, b: []}, {a: 3}]
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: by cannot return objects
context: {}
template:
$sort: [{a: 2}, {a: 1, b: []}, {a: 3}]
by(x): x
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: cannot sort arrays without by
context: {}
template:
$sort: [[1,2,3], [4,5], [], [8,9,10]]
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: by cannot return arrays
context: {}
template:
$sort: [[1,2,3], [4,5], [], [8,9,10]]
by(x): x
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: cannot sort nulls
context: {}
template: {$sort: [null, null]}
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: cannot sort nulls, even with by
context: {}
template: {$sort: [null, null], 'by(x)': 'x'}
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: cannot sort booleans
context: {}
template: {$sort: [false, true]}
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: cannot sort booleans, even with by
context: {}
template: {$sort: [false, true], 'by(x)': 'x'}
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: cannot sort numbers and strings together
context: {}
template: {$sort: [1, 'a']}
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: cannot sort numbers and strings together even with by
context: {}
template: {$sort: [1, 'a'], 'by(x)': 'x'}
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: sort requires an array (string)
context: {}
template:
$sort: "some string"
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: sort requires an array (number)
context: {}
template:
$sort: 34
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: sort requires an array (object)
context: {}
template:
$sort: {k: 1, b: 4, x: 8}
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: sort requires an array (null)
context: {}
template:
$sort: null
error: 'TemplateError: $sorted values to be sorted must have the same type'
---
title: sort with undefined properties
context: {}
template:
$sort: [{s: 'android'}, {s: 'add'}, {s: 'adderall'}]
by(x): 'x.s'
foo: 'bar'
error: 'TemplateError: $sort has undefined properties: foo'
---
title: $sort variable not used (in context)
context: { foo: 1 }
template: { $sort: [2,1,3], by(x): foo}
result: [2,1,3]
---
title: $sort variable not used (not in context)
context: {}
template: { $sort: [2,1,3], by(x): foo}
error: 'InterpreterError: unknown context value foo'
---
title: $sort is stable
template:
$sort: ["aa", "dd", "ac", "ba", "ab"]
by(x): 'x[0]'
context: {}
result: ["aa", "ac", "ab", "ba", "dd"]
---
title: $sort of very large integers
template:
$sort: [1111111111111111111111, 22222222222222222222, 3333333, 444]
context: {}
result: [444, 3333333, 22222222222222222222, 1111111111111111111111]
---
section: $reverse
---
title: simple reverse
context: {}
template: {$reverse: [3, 4, 1, 2]}
result: [2, 1, 4, 3]
---
title: value is rendered
context: {}
template: {$reverse: {$eval: '[99, 999, 9]'}}
result: [9, 999, 99]
---
title: reverse of an object
context: {}
template: {$reverse: {a: 1}}
error: 'TemplateError: $reverse value must evaluate to an array of objects'
---
title: reverse of null
context: {}
template: {$reverse: null}
error: 'TemplateError: $reverse value must evaluate to an array of objects'
---
title: reverse of a string
context: {}
template: {$reverse: 'foo'}
error: 'TemplateError: $reverse value must evaluate to an array of objects'
---
title: reverse of a number
context: {}
template: {$reverse: 1}
error: 'TemplateError: $reverse value must evaluate to an array of objects'
---
title: reverse of a boolean
context: {}
template: {$reverse: true}
error: 'TemplateError: $reverse value must evaluate to an array of objects'
---
title: simple reverse with $eval
context: {key: [3, 4, 1, 2]}
template: {$reverse: {$eval: 'key'}}
result: [2, 1, 4, 3]
---
title: simple reverse + $sort context: {}
template: {$reverse: {$sort: [3, 4, 1, 2]}}
result: [4, 3, 2, 1]
---
title: reverse with undefined properties
template: {$reverse: [3, 4, 1, 2], foo: "bar", bing: "baz"}
context: {}
error: 'TemplateError: $reverse has undefined properties: bing foo'
---
section: $eval
---
title: $eval of $eval
context: {}
template: {$eval: {$eval: '"13"'}}
error: 'TemplateError: $eval must be given a string expression'
---
title: $eval with trailing characters
context: {}
template: {$eval: '"13" 13'}
error: 'SyntaxError: Found: 13 token, expected one of: !=, &&, (, *, **, +, -, ., /, <, <=, ==, >, >=, [, in, ||'
---
title: $eval with undefined properties
context: {}
template: {$eval: '13', wrong: 'a + b'}
error: 'TemplateError: $eval has undefined properties: wrong'
---
title: $eval of an array
context: {key1: 1, key2: 2}
template: {$eval: ['key1', 'key2']}
error: 'TemplateError: $eval must be given a string expression'
---
title: $eval of an object
context: {key1: 1, key2: 2}
template: {$eval: {k: 'key1'}}
error: 'TemplateError: $eval must be given a string expression'
---
title: $eval of null
context: {}
template: {$eval: null}
error: 'TemplateError: $eval must be given a string expression'
---
title: $eval of a number
context: {}
template: {$eval: 11}
error: 'TemplateError: $eval must be given a string expression'
---
title: $eval of a boolean
context: {}
template: {$eval: true}
error: 'TemplateError: $eval must be given a string expression'
---
section: builtins
---
title: min (1)
context: {key1: 1, key2: 2}
template: {$eval: 'min(key1, key2)'}
result: 1
---
title: min (2)
context: {key1: 1, key2: 2}
template: {$eval: 'min(1, key2)'}
result: 1
---
title: min (3)
context: {key1: 1, key2: 2}
template: {$eval: 'min(key1, 2)'}
result: 1
---
title: min (4)
context: {key1: 1, key2: 2}
template: {$eval: 'min(1, 2)'}
result: 1
---
title: min (5)
context: {key1: 1, key2: 2}
template: {$eval: 'min(2, 1)'}
result: 1
---
title: min (6)
context: {key1: 1, key2: 2}
template: {$eval: 'min(2, 1, 3, 4, 5)'}
result: 1
---
title: min - TypeError
context: {}
template: {$eval: 'min("11")'}
error: 'BuiltinError: invalid arguments to builtin: min'
---
title: min (7)
context: {}
template: {$eval: 'min()'}
error: 'BuiltinError: invalid arguments to builtin: min: expected at least 1 arguments'
---
title: max (1)
context: {key1: 1, key2: 2}
template: {$eval: 'max(key1, key2)'}
result: 2
---
title: max (2)
context: {key1: 1, key2: 2}
template: {$eval: 'max(1, key2)'}
result: 2
---
title: max (3)
context: {key1: 1, key2: 2}
template: {$eval: 'max(key1, 2)'}
result: 2
---
title: max (4)
context: {key1: 1, key2: 2}
template: {$eval: 'max(1, 2)'}
result: 2
---
title: max (5)
context: {key1: 1, key2: 2}
template: {$eval: 'max(2, 1)'}
result: 2
---
title: max (6)
context: {key1: 1, key2: 2}
template: {$eval: 'max(2, 1, 3, 4, 5)'}
result: 5
---
title: max - TypeError
context: {}
template: {$eval: 'max("12")'}
error: 'BuiltinError: invalid arguments to builtin: max'
---
title: max (7)
context: {}
template: {$eval: 'max()'}
error: 'BuiltinError: invalid arguments to builtin: max: expected at least 1 arguments'
---
title: sqrt (1)
context: {key: 4}
template: {$eval: 'sqrt(key)'}
result: 2
---
title: sqrt (2)
context: {}
template: {$eval: 'sqrt(9)'}
result: 3
---
title: sqrt - TypeError
context: {}
template: {$eval: 'sqrt("nine")'}
error: 'BuiltinError: invalid arguments to builtin: sqrt'
---
title: ceil (1)
context: {key: 1.1}
template: {$eval: 'ceil(key)'}
result: 2
---
title: ceil (2)
context: {}
template: {$eval: 'ceil(2.003)'}
result: 3
---
title: ceil (3)
context: {key: 1}
template: {$eval: 'ceil(key)'}
result: 1
---
title: ceil (4)
context: {key: 1.0}
template: {$eval: 'ceil(key)'}
result: 1
---
title: ceil - TypeError
context: {}
template: {$eval: 'ceil(true)'}
error: 'BuiltinError: invalid arguments to builtin: ceil'
---
title: floor (1)
context: {key: 1.1}
template: {$eval: 'floor(key)'}
result: 1
---
title: floor (2)
context: {}
template: {$eval: 'floor(2.003)'}
result: 2
---
title: floor (3)
context: {key: 1}
template: {$eval: 'floor(key)'}
result: 1
---
title: floor (4)
context: {key: 1.0}
template: {$eval: 'floor(key)'}
result: 1
---
title: floor - TypeError
context: {key: null}
template: {$eval: 'floor(key)'}
error: 'BuiltinError: invalid arguments to builtin: floor'
---
title: abs (1)
context: {key: -1.1}
template: {$eval: 'abs(key)'}
result: 1.1
---
title: abs (2)
context: {}
template: {$eval: 'abs(-1.1)'}
result: 1.1
---
title: abs (3)
context: {key: -1}
template: {$eval: 'abs(key)'}
result: 1
---
title: abs (4)
context: {key: -1.0}
template: {$eval: 'abs(key)'}
result: 1
---
title: abs (5)
context: {}
template: {$eval: 'abs(-1)'}
result: 1
---
title: abs (6)
context: {}
template: {$eval: 'abs(-1.0)'}
result: 1
---
title: abs (7)
context: {key: 1.1}
template: {$eval: 'abs(key)'}
result: 1.1
---
title: abs (8)
context: {}
template: {$eval: 'abs(1.1)'}
result: 1.1
---
title: abs (9)
context: {key: 1}
template: {$eval: 'abs(key)'}
result: 1
---
title: abs (10)
context: {key: 1.0}
template: {$eval: 'abs(key)'}
result: 1
---
title: abs (11)
context: {}
template: {$eval: 'abs(1)'}
result: 1
---
title: abs (12)
context: {}
template: {$eval: 'abs(1.0)'}
result: 1
---
title: abs - TypeError
context: {}
template: {$eval: 'abs({})'}
error: 'BuiltinError: invalid arguments to builtin: abs'
---
title: lowercase (1)
context: {key: 'HEllo'}
template: {$eval: 'lowercase(key)'}
result: 'hello'
---
title: lowercase (2)
context: {}
template: {$eval: 'lowercase("HEllo")'}
result: 'hello'
---
title: TypeError lowercase (1)
context: {key: {}}
template: {$eval: 'lowercase(key)'}
error: 'BuiltinError: invalid arguments to builtin: lowercase'
---
title: TypeError lowercase (2)
context: {}
template: {$eval: 'lowercase({})'}
error: 'BuiltinError: invalid arguments to builtin: lowercase'
---
title: TypeError lowercase (3)
context: {key: []}
template: {$eval: 'lowercase(key)'}
error: 'BuiltinError: invalid arguments to builtin: lowercase'
---
title: TypeError lowercase (4)
context: {}
template: {$eval: 'lowercase([])'}
error: 'BuiltinError: invalid arguments to builtin: lowercase'
---
title: TypeError lowercase (5)
context: {key: 1}
template: {$eval: 'lowercase(key)'}
error: 'BuiltinError: invalid arguments to builtin: lowercase'
---
title: TypeError lowercase (6)
context: {}
template: {$eval: 'lowercase(1)'}
error: 'BuiltinError: invalid arguments to builtin: lowercase'
---
title: uppercase (1)
context: {key: 'HEllo'}
template: {$eval: 'uppercase(key)'}
result: 'HELLO'
---
title: uppercase (2)
context: {}
template: {$eval: 'uppercase("HEllo")'}
result: 'HELLO'
---
title: TypeError uppercase (1)
context: {key: {}}
template: {$eval: 'uppercase(key)'}
error: 'BuiltinError: invalid arguments to builtin: uppercase'
---
title: TypeError uppercase (2)
context: {}
template: {$eval: 'uppercase({})'}
error: 'BuiltinError: invalid arguments to builtin: uppercase'
---
title: TypeError uppercase (3)
context: {key: []}
template: {$eval: 'uppercase(key)'}
error: 'BuiltinError: invalid arguments to builtin: uppercase'
---
title: TypeError uppercase (4)
context: {}
template: {$eval: 'uppercase([])'}
error: 'BuiltinError: invalid arguments to builtin: uppercase'
---
title: TypeError uppercase (5)
context: {key: 1}
template: {$eval: 'uppercase(key)'}
error: 'BuiltinError: invalid arguments to builtin: uppercase'
---
title: TypeError uppercase (6)
context: {}
template: {$eval: 'uppercase(1)'}
error: 'BuiltinError: invalid arguments to builtin: uppercase'
---
title: len (1)
context: {key: [1,2,3]}
template: {$eval: 'len(key)'}
result: 3
---
title: len (2)
context: {key: [1,2,3]}
template: {$eval: 'len([1, 2, 3])'}
result: 3
---
title: len (3)
context: {key: 'abc'}
template: {$eval: 'len(key)'}
result: 3
---
title: len of grinning face unicode character
context: {key: "\U0001F601"}
template: {$eval: 'len(key)'}
result: 1
---
title: len (4)
context: {key: [1,2,3]}
template: {$eval: 'len("abc")'}
result: 3
---
title: TypeError len (1)
context: {key: {}}
template: {$eval: 'len(key)'}
error: 'BuiltinError: invalid arguments to builtin: len'
---
title: TypeError len (2)
context: {}
template: {$eval: 'len({})'}
error: 'BuiltinError: invalid arguments to builtin: len'
---
title: TypeError len (3)
context: {key: 1}
template: {$eval: 'len(key)'}
error: 'BuiltinError: invalid arguments to builtin: len'
---
title: TypeError len (4)
context: {}
template: {$eval: 'len(1)'}
error: 'BuiltinError: invalid arguments to builtin: len'
---
title: str of num via context
context: {key: 1}
template: {$eval: 'str(key)'}
result: '1'
---
title: str of num
context: {}
template: {$eval: 'str(1)'}
result: '1'
---
title: str of string via context
context: {key: 'hello'}
template: {$eval: 'str(key)'}
result: 'hello'
---
title: str of string
context: {}
template: {$eval: 'str("hello")'}
result: 'hello'
---
title: str of bool via context
context: {key: true}
template: {$eval: 'str(key)'}
result: 'true'
---
title: str of true
context: {}
template: {$eval: 'str(true)'}
result: 'true'
---
title: str (key) with null
context: {x: null}
template: {$eval: 'str(x)'}
result: 'null'
---
title: str of bool via context
context: {key: false}
template: {$eval: 'str(key)'}
result: 'false'
---
title: str of false
context: {}
template: {$eval: 'str(false)'}
result: 'false'
---
title: str of floating-point 4.25
context: {val: 4.25}
template: {$eval: 'str(val)'}
result: '4.25'
---
title: str of floating-point 4.2
context: {val: 4.2}
template: {$eval: 'str(val)'}
result: '4.2'
---
title: str of unicode
context: {val: "let's make a ☃"}
template: {$eval: 'str(val)'}
result: "let's make a ☃"
---
title: str of empty object
context: {}
template: {$eval: 'str({})'}
error: 'BuiltinError: invalid arguments to builtin: str'
---
title: str of object
context: {}
template: {$eval: 'str({a:10})'}
error: 'BuiltinError: invalid arguments to builtin: str'
---
title: str of array
context: {}
template: {$eval: 'str([1, 2, 3])'}
error: 'BuiltinError: invalid arguments to builtin: str'
---
title: str(key) with array
context: {key: [1, 2, 3]}
template: {$eval: 'str(key)'}
error: 'BuiltinError: invalid arguments to builtin: str'
---
title: number
context: {round: "3"}
template: {foo: {$eval: number(round)}}
result: {foo: 3}
---
title: number (with point)
context: {round: "3.5"}
template: {foo: {$eval: number(round)}}
result: {foo: 3.5}
---
title: negative number
context: {round: "-14"}
template: {foo: {$eval: number(round)}}
result: {foo: -14}
---
title: negative number (with point)
context: {round: "-14.15"}
template: {foo: {$eval: number(round)}}
result: {foo: -14.15}
---
title: number zero
context: {round: "0"}
template: {foo: {$eval: number(round)}}
result: {foo: 0}
---
title: giving a number to number fails
context: {round: 0}
template: {foo: {$eval: number(round)}}
error: true
---
title: giving a bool to number fails
context: {round: false}
template: {foo: {$eval: number(round)}}
error: true
---
title: giving null to number fails
context: {round: null}
template: {foo: {$eval: number(round)}}
error: true
---
title: giving an array to number fails
context: {round: [1]}
template: {foo: {$eval: number(round)}}
error: true
---
title: giving an object to number fails
context: {round: {one: 1}}
template: {foo: {$eval: number(round)}}
error: true
---
title: strip space
context: {}
template: {$eval: "strip(' abc ')"}
result: 'abc'
---
title: strip mixed whitspace
context: {}
template: {$eval: "strip(' \f\n\r\t\vabc \f\n\r\t\v')"}
result: 'abc'
---
title: rstrip space
context: {}
template: {$eval: "rstrip(' abc ')"}
result: ' abc'
---
title: rstrip mixed whitspace
context: {}
template: {$eval: "rstrip(' \f\n\r\t\vabc \f\n\r\t\v')"}
result: " \f\n\r\t\vabc"
---
title: lstrip space
context: {}
template: {$eval: "lstrip(' abc ')"}
result: 'abc '
---
title: lstrip mixed whitspace
context: {}
template: {$eval: "lstrip(' \f\n\r\t\vabc \f\n\r\t\v')"}
result: "abc \f\n\r\t\v"
---
title: split string with delimiter
context: {}
template: {$eval: "split('left:right', ':')"}
result: ['left', 'right']
---
title: split string without delimiter
context: {}
template: {$eval: "split('spellme', '')"}
result: ['s', 'p', 'e', 'l', 'l', 'm', 'e']
---
title: split with empty string
context: {}
template: {$eval: "split('', ':')"}
result: ['']
---
title: split string with no match
context: {}
template: {$eval: "split('no semicolon', ':')"}
result: ['no semicolon']
---
title: split with number delimiter
context: {}
template: {$eval: "split('left1right', 1)"}
result: ['left', 'right']
---
title: split error with object
context: {}
template: {$eval: "split({})"}
error: 'BuiltinError: invalid arguments to builtin: split'
---
title: split error with array
context: {}
template: {$eval: "split([])"}
error: 'BuiltinError: invalid arguments to builtin: split'
---
title: split with only one argument
context: {}
template: {$eval: "split('abc')"}
error: 'BuiltinError: invalid arguments to builtin: split'
---
title: join with string separator
context: {}
template: {$eval: "join(['join', 'me'], ' ')"}
result: "join me"
---
title: join with same
context: {}
template: {$eval: "join([',', ','], ',')"}
result: ",,,"
---
title: join with number separator
context: {}
template: {$eval: "join([1, 3], 2)"}
result: "123"
---
title: join with strings separated with number
context: {}
template: {$eval: "join(['one', 'three'], 2)"}
result: "one2three"
---
title: join with numbers separated with string
context: {}
template: {$eval: "join([1, 3], 'two')"}
result: "1two3"
---
title: join with string
context: {}
template: {$eval: "join('cannot join string')"}
error: "BuiltinError: invalid arguments to builtin: join"
---
title: join with object
context: {}
template: {$eval: "join({})"}
error: "BuiltinError: invalid arguments to builtin: join"
---
title: join with boolean
context: {}
template: {$eval: "join(false)"}
error: "BuiltinError: invalid arguments to builtin: join"
---
title: fromNow
context: {}
template: {$eval: fromNow("")}
result: '2017-01-19T16:27:20.974Z'
---
title: fromNow - 2 days 3 hours
context: {}
template: {$eval: fromNow("2 days 3 hours")}
result: '2017-01-21T19:27:20.974Z'
---
title: fromNow with reference
context: {}
template: {$eval: "fromNow('1 day', '2017-01-01T01:00:00.123Z')"}
result: '2017-01-02T01:00:00.123Z'
---
title: fromNow - TypeError
context: {}
template: {$eval: fromNow(13)}
error: 'BuiltinError: invalid arguments to builtin: fromNow'
---
title: typeof str
context: {}
template: {$eval: typeof('abc')}
result: string
---
title: typeof number (int)
context: {}
template: {$eval: typeof(4)}
result: number
---
title: typeof number (float)
context: {}
template: {$eval: typeof(4.0)}
result: number
---
title: typeof boolean (true)
context: {}
template: {$eval: typeof(true)}
result: boolean
---
title: typeof boolean (false)
context: {}
template: {$eval: typeof(false)}
result: boolean
---
title: typeof array (empty)
context: {}
template: {$eval: 'typeof([])'}
result: array
---
title: typeof array
context: {}
template: {$eval: 'typeof([1, 2, 3])'}
result: array
---
title: typeof object
context: {}
template: {$eval: 'typeof({})'}
result: object
---
title: typeof null
context: {x: null}
template: {$eval: 'typeof(x)'}
result: 'null'
---
title: typeof null, interpolated
context: {x: null}
template: "${typeof(x)}"
result: 'null'
---
title: typeof null in if
context: {}
template: {$if: 'typeof(null) == "null"', then: 'foo', else: 'bar'}
result: foo
---
title: typeof function
context: {}
template: {$eval: 'typeof(typeof)'}
result: function
---
title: override builtin (1), uppercase
context: {uppercase: 1}
template: {$eval: 'uppercase + 1'}
result: 2
---
title: override builtin (2), min
context: {min: 'hello world!'}
template: {$eval: 'min'}
result: 'hello world!'
---
title: 'defined without context variable'
context: {}
template: {$if: "defined('var')", then: 't', else: 'f'}
result: f
---
title: 'defined with empty string as context variable'
context: {var: ""}
template: {$if: "defined('var')", then: 't', else: 'f'}
result: t
---
section: expression language - basics
---
title: missing right square bracket
context: {bar: "mystring"}
template: {foo: '${bar[2:}'}
error: "SyntaxError at template.foo: Found: } token, expected one of: !, (, +, -, [, false, identifier, null, number, string, true, {"
---
title: decimal literal
context: {}
template: {$eval: '10.5'}
result: 10.5
---
title: hex literal
context: {}
template: {$eval: '0xff'}
error: 'SyntaxError: Found: xff token, expected one of: !=, &&, (, *, **, +, -, ., /, <, <=, ==, >, >=, [, in, ||'
---
title: string literal with single quote
context: {}
template: {$eval: "'three!'"}
result: 'three!'
---
title: string literal with double quote
context: {}
template: {$eval: '"three!"'}
result: 'three!'
---
title: string literal escape with backslash (not supported)
context: {}
template: {$eval: '"backslash\\"maybe"'}
error: 'SyntaxError: Found: maybe token, expected one of: !=, &&, (, *, **, +, -, ., /, <, <=, ==, >, >=, [, in, ||'
---
title: string literal escape with doubling (not supported)
context: {}
template: {$eval: '"doubled""maybe"'}
error: 'SyntaxError: Found: "maybe" token, expected one of: !=, &&, (, *, **, +, -, ., /, <, <=, ==, >, >=, [, in, ||'
---
title: boolean literals
context: {}
template: {$eval: '[true, false]'}
result: [true, false]
---
title: null literal
context: {}
template: {$eval: '[null, null]'}
result: [null, null]
---
title: leading zeroes (not octal)
context: {}
template: {$eval: '0777'}
result: 777
---
title: addition
context: {a: 1, b: 2}
template: {$eval: 'a + b + 7'}
result: 10
---
title: multiplication
context: {a: 3, b: 2}
template: {$eval: 'a * b * 3'}
result: 18
---
title: string concatenation
context: {a: 3, b: 2}
template: {$eval: '"a" + "b"'}
result: 'ab'
---
title: $eval must take string
context: {a: 3, b: 2}
template: {$eval: ['a', 'b']}
error: 'TemplateError: $eval must be given a string expression'
---
title: array access [index]
context: {a: [1,2,3,4]}
template: {$eval: 'a[0]'}
result: 1
---
title: array access [index]
context: {a: [1,2,3,4]}
template: {$eval: 'a[2]'}
result: 3
---
title: array access [-index]
context: {a: [1,2,3,4]}
template: {$eval: 'a[-1]'}
result: 4
---
title: array access [-index]
context: {a: [1,2,3,4]}
template: {$eval: 'a[-2]'}
result: 3
---
title: array access [index expression]
context: {a: [10,11,12], b: 1}
template: {$eval: 'a[b]'}
result: 11
---
title: array access [index expression with +]
context: {a: [10,11,12], b: 1}
template: {$eval: 'a[b+1]'}
result: 12
---
title: array slicing [begin:end], [begin, end)
context: {a: [1,2,3,4]}
template: {$eval: 'a[0:2]'}
result: [1,2]
---
title: array slicing [begin:], [begin, end)
context: {a: [1,2,3,4]}
template: {$eval: 'a[0:]'}
result: [1,2,3,4]
---
title: array slicing [begin:], [begin, end)
context: {a: [1,2,3,4]}
template: {$eval: 'a[1:]'}
result: [2,3,4]
---
title: array slicing [-begin:], [begin, end)
context: {a: [1,2,3,4]}
template: {$eval: 'a[-3:]'}
result: [2,3,4]
---
title: array slicing [-begin:-end], [begin, end)
context: {a: [1,2,3,4]}
template: {$eval: 'a[-3:-1]'}
result: [2,3]
---
title: array slicing [:end], [begin, end)
context: {a: [1,2,3,4]}
template: {$eval: 'a[:3]'}
result: [1,2,3]
---
title: array slicing [:-end], [begin, end)
context: {a: [1,2,3,4]}
template: {$eval: 'a[:-2]'}
result: [1,2]
---
title: array slice partially out of range
context: {a: [1,2,3,4]}
template: {$eval: 'a[2:10]'}
result: [3,4]
---
title: array slice completely out of range
context: {a: [1,2,3,4]}
template: {$eval: 'a[8:10]'}
result: []
---
title: array slice negative out of range
context: {a: [1,2,3,4]}
template: {$eval: 'a[2:-10]'}
result: []
---
title: array slice negative range
context: {a: [1,2,3,4]}
template: {$eval: 'a[2:-3]'}
result: []
---
title: array slice reverse range
context: {a: [1,2,3,4]}
template: {$eval: 'a[3:2]'}
result: []
---
title: function min(contextValue, contextValue)
context: {a: 1, b: 2}
template: {$eval: 'min(a, b)'}
result: 1
---
title: function max(contextValue, contextValue)
context: {a: 1, b: 2}
template: {$eval: 'max(a, b)'}
result: 2
---
title: function min(contextValue, value)
context: {a: 1, b: 2}
template: {$eval: 'min(a, -1)'}
result: -1
---
title: function max(contextValue, value)
context: {a: 1, b: 2}
template: {$eval: 'max(a, 3)'}
result: 3
---
title: identifier beginning with in
context: {input: 6}
template: {$eval: 'input + 1'}
result: 7
---
title: identifier beginning with true / false
context: {true_facts: true, false_lies: false}
template: {$eval: 'true_facts || false_lies'}
result: true
---
title: identifier beginning with null
context: {null_hypothesis: "no difference"}
template: {$eval: 'null_hypothesis'}
result: "no difference"
---
section: expression language - arithmetic
---
title: 'addition'
context: {a: 1, b: 2}
template: {$eval: 'a + b + 7'}
result: 10
---
title: 'multiplication'
context: {a: 3, b: 2}
template: {$eval: 'a * b * 3'}
result: 18
---
title: 'multiplication (2)'
context: {a: 180000000000.0}
template: {$eval: '(a * -1000)'}
result: -180000000000000.0
---
title: 'multiplication with addition'
context: {a: 2}
template: {$eval: 'a * 3 + 4'}
result: 10
---
title: 'multiplication with subtraction'
context: {a: 2}
template: {$eval: 'a * 3 - 4'}
result: 2
---
title: 'multiplication with division'
context: {a: 4}
template: {$eval: 'a * 3 / 2'}
result: 6
---
title: 'multiplication with exponentiation'
context: {a: 2}
template: {$eval: 'a * 3 ** 4'}
result: 162
---
title: 'multiplication with grouped addition'
context: {a: 2}
template: {$eval: 'a * (3 + 4)'}
result: 14
---
title: 'multiplication with grouped subtraction'
context: {a: 2}
template: {$eval: 'a * (3 - 4)'}
result: -2
---
title: 'multiplication with grouped division'
context: {a: 4}
template: {$eval: 'a * (4 / 2)'}
result: 8
---
title: 'grouped multiplication with exponentiation'
context: {a: 4}
template: {$eval: '(a * 3) ** 2'}
result: 144
---
title: 'division (1)'
context: {a: 3, b: 2}
template: {$eval: 'a / b'}
result: 1.5
---
title: 'division (2)'
context: {a: 3.0, b: 2.0}
template: {$eval: 'a / b'}
result: 1.5
---
title: 'division (3)'
context: {a: 3, b: 2}
template: {$eval: 'b / a'}
result: 0.6666666666666666
---
title: 'division (4)'
context: {a: 3.0, b: 2.0}
template: {$eval: 'b / a'}
result: 0.6666666666666666
---
title: 'division by zero'
context: {}
template: {$eval: '1 / 0'}
error: "InterpreterError: division by zero"
---
title: 'division with addition'
context: {a: 12}
template: {$eval: 'a / 3 + 4'}
result: 8
---
title: 'division with subtraction'
context: {a: 6}
template: {$eval: 'a / 3 - 4'}
result: -2
---
title: 'division with division'
context: {a: 12}
template: {$eval: 'a / 3 / 2'}
result: 2
---
title: 'division with exponentiation'
context: {a: 162}
template: {$eval: 'a / 3 ** 4'}
result: 2
---
title: 'division with grouped addition'
context: {a: 14}
template: {$eval: 'a / (3 + 4)'}
result: 2
---
title: 'division with grouped subtraction'
context: {a: 6}
template: {$eval: 'a / (3 - 4)'}
result: -6
---
title: 'division with grouped division'
context: {a: 12}
template: {$eval: 'a / (6 / 2)'}
result: 4
---
title: 'grouped division with exponentiation'
context: {a: 12}
template: {$eval: '(a / 3) ** 4'}
result: 256
---
title: 'exponentiation (1)'
context: {a: 2, b: 3}
template: {$eval: 'a ** b'}
result: 8
---
title: 'exponentiation (2)'
context: {a: 2, b: 3}
template: {$eval: 'a ** b + 2'}
result: 10
---
title: 'exponentiation (3)'
context: {a: 2, b: 3}
template: {$eval: 'a ** b * 2'}
result: 16
---
title: 'exponentiation (4)'
context: {a: 2, b: 3}
template: {$eval: 'a * a ** b'}
result: 16
---
title: 'exponentiation, right associativity (1)'
context: {a: 2, b: 3}
template: {$eval: 'a ** a ** b == a ** (a ** b)'}
result: true
---
title: 'exponentiation, right associativity (2)'
context: {a: 2, b: 3}
template: {$eval: 'a ** a ** b'}
result: 256
---
title: 'exponentiation, right associativity (3)'
context: {a: 2, b: 3}
template: {$eval: '2 ** 2 ** 3 == 2 ** (2 ** 3)'}
result: true
---
title: 'exponentiation, right associativity (4)'
context: {a: 2, b: 3}
template: {$eval: '2 ** 2 ** 3'}
result: 256
---
title: 'unary negation'
context: {a: 2}
template: {$eval: '-a'}
result: -2
---
title: 'unary plus'
context: {a: 2}
template: {$eval: '+a'}
result: 2
---
section: expression language - operator type errors
---
title: 'addition of strings to numbers'
context: {a: 'a', b: 1}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of strings to null'
context: {a: 'a', b: null}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of strings to booleans'
context: {a: 'a', b: true}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of strings to objects'
context: {a: 'a', b: {x: 1}}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of strings to arrays'
context: {a: 'a', b: [1, 2]}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'subtraction of strings from strings'
context: {a: 'a', b: 'b'}
template: {$eval: 'a-b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of strings from numbers'
context: {a: 'a', b: 1}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of strings from null'
context: {a: 'a', b: null}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of strings from booleans'
context: {a: 'a', b: true}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of strings from objects'
context: {a: 'a', b: {x: 1}}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of strings from arrays'
context: {a: 'a', b: [1, 2]}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'multiplication of strings to strings'
context: {a: 'a', b: 'b'}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of strings to numbers'
context: {a: 'a', b: 1}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of strings to null'
context: {a: 'a', b: null}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of strings to booleans'
context: {a: 'a', b: true}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of strings to objects'
context: {a: 'a', b: {x: 1}}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of strings to arrays'
context: {a: 'a', b: [1, 2]}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'division of strings by strings'
context: {a: 'a', b: 'b'}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of strings by numbers'
context: {a: 'a', b: 1}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of strings by null'
context: {a: 'a', b: null}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of strings by booleans'
context: {a: 'a', b: true}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of strings by objects'
context: {a: 'a', b: {x: 1}}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of strings by arrays'
context: {a: 'a', b: [1, 2]}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'exponentiation of strings by strings'
context: {a: 'a', b: 'b'}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of strings by numbers'
context: {a: 'a', b: 1}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of strings by null'
context: {a: 'a', b: null}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of strings by booleans'
context: {a: 'a', b: true}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of strings by objects'
context: {a: 'a', b: {x: 1}}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of strings by arrays'
context: {a: 'a', b: [1, 2]}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'unary negation of string'
context: {a: 'a'}
template: {$eval: '-a'}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of string'
context: {a: 'a'}
template: {$eval: '+a'}
error: 'InterpreterError: unary + expects number'
---
title: 'unary negation of true'
template: {$eval: '-true'}
context: {}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of true'
template: {$eval: '+true'}
context: {}
error: 'InterpreterError: unary + expects number'
---
title: 'unary negation of false'
template: {$eval: '-false'}
context: {}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of false'
template: {$eval: '+false'}
context: {}
error: 'InterpreterError: unary + expects number'
---
title: 'unary negation of null'
template: {$eval: '-null'}
context: {}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of null'
template: {$eval: '+null'}
context: {}
error: 'InterpreterError: unary + expects number'
---
title: 'addition of numbers to strings'
context: {a: 13, b: 'b'}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of numbers to null'
context: {a: 13, b: null}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of numbers to booleans'
context: {a: 13, b: true}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of numbers to objects'
context: {a: 13, b: {x: 1}}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of numbers to arrays'
context: {a: 13, b: [1, 2]}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'subtraction of numbers from strings'
context: {a: 13, b: 'b'}
template: {$eval: 'a-b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of numbers from null'
context: {a: 13, b: null}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of numbers from booleans'
context: {a: 13, b: true}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of numbers from objects'
context: {a: 13, b: {x: 1}}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of numbers from arrays'
context: {a: 13, b: [1, 2]}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'multiplication of numbers to strings'
context: {a: 13, b: 'b'}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of numbers to null'
context: {a: 13, b: null}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of numbers to booleans'
context: {a: 13, b: true}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of numbers to objects'
context: {a: 13, b: {x: 1}}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of numbers to arrays'
context: {a: 13, b: [1, 2]}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'division of numbers by strings'
context: {a: 13, b: 'b'}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of numbers by null'
context: {a: 13, b: null}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of numbers by booleans'
context: {a: 13, b: true}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of numbers by objects'
context: {a: 13, b: {x: 1}}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of numbers by arrays'
context: {a: 13, b: [1, 2]}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'exponentiation of numbers by strings'
context: {a: 13, b: 'b'}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of numbers by null'
context: {a: 13, b: null}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of numbers by booleans'
context: {a: 13, b: true}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of numbers by objects'
context: {a: 13, b: {x: 1}}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of numbers by arrays'
context: {a: 13, b: [1, 2]}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'addition of null to strings'
context: {a: null, b: 'a'}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of null to numbers'
context: {a: null, b: 1}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of null to null'
context: {a: null, b: null}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of null to booleans'
context: {a: null, b: true}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of null to objects'
context: {a: null, b: {x: 1}}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of null to arrays'
context: {a: null, b: [1, 2]}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'subtraction of null from strings'
context: {a: null, b: 'b'}
template: {$eval: 'a-b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of null from numbers'
context: {a: null, b: 1}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of null from null'
context: {a: null, b: null}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of null from booleans'
context: {a: null, b: true}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of null from objects'
context: {a: null, b: {x: 1}}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of null from arrays'
context: {a: null, b: [1, 2]}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'multiplication of null to strings'
context: {a: null, b: 'b'}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of null to numbers'
context: {a: null, b: 1}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of null to null'
context: {a: null, b: null}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of null to booleans'
context: {a: null, b: true}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of null to objects'
context: {a: null, b: {x: 1}}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of null to arrays'
context: {a: null, b: [1, 2]}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'division of null by strings'
context: {a: null, b: 'b'}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of null by numbers'
context: {a: null, b: 1}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of null by null'
context: {a: null, b: null}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of null by booleans'
context: {a: null, b: true}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of null by objects'
context: {a: null, b: {x: 1}}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of null by arrays'
context: {a: null, b: [1, 2]}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'exponentiation of null by strings'
context: {a: null, b: 'b'}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of null by numbers'
context: {a: null, b: 1}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of null by null'
context: {a: null, b: null}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of null by booleans'
context: {a: null, b: true}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of null by objects'
context: {a: null, b: {x: 1}}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of null by arrays'
context: {a: null, b: [1, 2]}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'unary negation of null'
context: {a: null}
template: {$eval: '-a'}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of null'
context: {a: null}
template: {$eval: '+a'}
error: 'InterpreterError: unary + expects number'
---
title: 'addition of boolean to strings'
context: {a: true, b: 'a'}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of boolean to numbers'
context: {a: true, b: 1}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of boolean to null'
context: {a: true, b: null}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of boolean to booleans'
context: {a: true, b: true}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of boolean to objects'
context: {a: true, b: {x: 1}}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of boolean to arrays'
context: {a: true, b: [1, 2]}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'subtraction of boolean from strings'
context: {a: true, b: 'b'}
template: {$eval: 'a-b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of boolean from numbers'
context: {a: true, b: 1}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of boolean from null'
context: {a: true, b: null}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of boolean from booleans'
context: {a: true, b: true}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of boolean from objects'
context: {a: true, b: {x: 1}}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of boolean from arrays'
context: {a: true, b: [1, 2]}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'multiplication of boolean to strings'
context: {a: true, b: 'b'}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of boolean to numbers'
context: {a: true, b: 1}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of boolean to null'
context: {a: true, b: null}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of boolean to booleans'
context: {a: true, b: true}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of boolean to objects'
context: {a: true, b: {x: 1}}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of boolean to arrays'
context: {a: true, b: [1, 2]}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'division of boolean by strings'
context: {a: true, b: 'b'}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of boolean by numbers'
context: {a: true, b: 1}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of boolean by null'
context: {a: true, b: null}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of boolean by booleans'
context: {a: true, b: true}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of boolean by objects'
context: {a: true, b: {x: 1}}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of boolean by arrays'
context: {a: true, b: [1, 2]}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'exponentiation of boolean by strings'
context: {a: true, b: 'b'}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of boolean by numbers'
context: {a: true, b: 1}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of boolean by null'
context: {a: true, b: null}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of boolean by booleans'
context: {a: true, b: true}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of boolean by objects'
context: {a: true, b: {x: 1}}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of boolean by arrays'
context: {a: true, b: [1, 2]}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'unary negation of boolean'
context: {a: true}
template: {$eval: '-a'}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of boolean'
context: {a: true}
template: {$eval: '+a'}
error: 'InterpreterError: unary + expects number'
---
title: 'addition of object to strings'
context: {a: {x: 10}, b: 'a'}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of object to numbers'
context: {a: {x: 10}, b: 1}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of object to null'
context: {a: {x: 10}, b: null}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of object to booleans'
context: {a: {x: 10}, b: true}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of object to objects'
context: {a: {x: 10}, b: {x: 1}}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of object to arrays'
context: {a: {x: 10}, b: [1, 2]}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'subtraction of object from strings'
context: {a: {x: 10}, b: 'b'}
template: {$eval: 'a-b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of object from numbers'
context: {a: {x: 10}, b: 1}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of object from null'
context: {a: {x: 10}, b: null}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of object from booleans'
context: {a: {x: 10}, b: true}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of object from objects'
context: {a: {x: 10}, b: {x: 1}}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of object from arrays'
context: {a: {x: 10}, b: [1, 2]}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'multiplication of object to strings'
context: {a: {x: 10}, b: 'b'}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of object to numbers'
context: {a: {x: 10}, b: 1}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of object to null'
context: {a: {x: 10}, b: null}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of object to booleans'
context: {a: {x: 10}, b: true}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of object to objects'
context: {a: {x: 10}, b: {x: 1}}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of object to arrays'
context: {a: {x: 10}, b: [1, 2]}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'division of object by strings'
context: {a: {x: 10}, b: 'b'}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of object by numbers'
context: {a: {x: 10}, b: 1}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of object by null'
context: {a: {x: 10}, b: null}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of object by booleans'
context: {a: {x: 10}, b: true}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of object by objects'
context: {a: {x: 10}, b: {x: 1}}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of object by arrays'
context: {a: {x: 10}, b: [1, 2]}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'exponentiation of object by strings'
context: {a: {x: 10}, b: 'b'}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of object by numbers'
context: {a: {x: 10}, b: 1}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of object by null'
context: {a: {x: 10}, b: null}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of object by booleans'
context: {a: {x: 10}, b: true}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of object by objects'
context: {a: {x: 10}, b: {x: 1}}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of object by arrays'
context: {a: {x: 10}, b: [1, 2]}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'unary negation of object'
context: {a: {x: 10}}
template: {$eval: '-a'}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of object'
context: {a: {x: 10}}
template: {$eval: '+a'}
error: 'InterpreterError: unary + expects number'
---
title: 'addition of array to strings'
context: {a: [1, 2], b: 'a'}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of array to numbers'
context: {a: [1, 2], b: 1}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of array to null'
context: {a: [1, 2], b: null}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of array to booleans'
context: {a: [1, 2], b: true}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of array to objects'
context: {a: [1, 2], b: {x: 1}}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'addition of array to arrays'
context: {a: [1, 2], b: [1, 2]}
template: {$eval: 'a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'subtraction of array from strings'
context: {a: [1, 2], b: 'b'}
template: {$eval: 'a-b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of array from numbers'
context: {a: [1, 2], b: 1}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of array from null'
context: {a: [1, 2], b: null}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of array from booleans'
context: {a: [1, 2], b: true}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of array from objects'
context: {a: [1, 2], b: {x: 1}}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'subtraction of array from arrays'
context: {a: [1, 2], b: [1, 2]}
template: {$eval: 'a - b'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'multiplication of array to strings'
context: {a: [1, 2], b: 'b'}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of array to numbers'
context: {a: [1, 2], b: 1}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of array to null'
context: {a: [1, 2], b: null}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of array to booleans'
context: {a: [1, 2], b: true}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of array to objects'
context: {a: [1, 2], b: {x: 1}}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'multiplication of array to arrays'
context: {a: [1, 2], b: [1, 2]}
template: {$eval: 'a * b'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'division of array by strings'
context: {a: [1, 2], b: 'b'}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of array by numbers'
context: {a: [1, 2], b: 1}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of array by null'
context: {a: [1, 2], b: null}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of array by booleans'
context: {a: [1, 2], b: true}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of array by objects'
context: {a: [1, 2], b: {x: 1}}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'division of array by arrays'
context: {a: [1, 2], b: [1, 2]}
template: {$eval: 'a / b'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'exponentiation of array by strings'
context: {a: [1, 2], b: 'b'}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of array by numbers'
context: {a: [1, 2], b: 1}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of array by null'
context: {a: [1, 2], b: null}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of array by booleans'
context: {a: [1, 2], b: true}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of array by objects'
context: {a: [1, 2], b: {x: 1}}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'exponentiation of array by arrays'
context: {a: [1, 2], b: [1, 2]}
template: {$eval: 'a ** b'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'unary negation of array'
context: {a: [1, 2]}
template: {$eval: '-a'}
error: 'InterpreterError: unary - expects number'
---
title: 'unary plus of array'
context: {a: [1, 2]}
template: {$eval: '+a'}
error: 'InterpreterError: unary + expects number'
---
section: expression language - logic
---
title: 'logical not (1)'
context: {tt: true, ff: false}
template: {$eval: '!tt'}
result: false
---
title: 'logical not (2)'
context: {tt: true, ff: false}
template: {$eval: '!ff'}
result: true
---
title: 'or operator (1)'
context: {tt: true, ff: false}
template: {$eval: 'tt || tt'}
result: true
---
title: 'or operator (2)'
context: {tt: true, ff: false}
template: {$eval: 'tt || ff'}
result: true
---
title: 'or operator (3)'
context: {tt: true, ff: false}
template: {$eval: 'ff || tt'}
result: true
---
title: 'or operator (4)'
context: {tt: true, ff: false}
template: {$eval: 'ff || ff'}
result: false
---
title: 'and operator (1)'
context: {tt: true, ff: false}
template: {$eval: 'tt && tt'}
result: true
---
title: 'and operator (2)'
context: {tt: true, ff: false}
template: {$eval: 'tt && ff'}
result: false
---
title: 'and operator (3)'
context: {tt: true, ff: false}
template: {$eval: 'ff && tt'}
result: false
---
title: 'and operator (4)'
context: {tt: true, ff: false}
template: {$eval: 'ff && ff'}
result: false
---
title: 'and operator with not operator'
context: {tt: true, ff: false}
template: {$eval: 'tt && !ff'}
result: true
---
title: 'or operator with not operator'
context: {tt: true, ff: false}
template: {$eval: 'ff || !ff'}
result: true
---
title: 'complex logical operation (1)'
context: {}
template: {$eval: "4 < 6 && 2 == 1 + 1"}
result: true
---
title: 'complex logical operation (2)'
context: {}
template: {$eval: "!(4 < 6) && 2 == 1 + 1"}
result: false
---
title: 'complex logical operation (3)'
context: {}
template: {$eval: "2 == 1 + 1 && 4 < 6"}
result: true
---
title: 'complex logical operation (4)'
context: {}
template: {$eval: "4 >= 6 || 2 == 1 + 1"}
result: true
---
title: 'string not'
context: {a: 'abc'}
template: {$eval: "!a"}
result: false
---
title: 'empty string not'
context: {a: ''}
template: {$eval: "!a"}
result: true
---
title: 'number not'
context: {a: 123}
template: {$eval: "!a"}
result: false
---
title: 'zero not'
context: {a: 0}
template: {$eval: "!a"}
result: true
---
title: 'null not'
context: {a: null}
template: {$eval: "!a"}
result: true
---
title: 'object not'
context: {a: {x: 1}}
template: {$eval: "!a"}
result: false
---
title: 'empty object not'
context: {a: {}}
template: {$eval: "!a"}
result: true
---
title: 'array not'
context: {a: [1, 2]}
template: {$eval: "!a"}
result: false
---
title: 'empty array not'
context: {a: []}
template: {$eval: "!a"}
result: true
---
title: 'function not'
context: {}
template: {$eval: "!min"}
result: false
---
title: 'string and string'
context: {a: 'abc', b: 'abc'}
template: {$eval: "a && b"}
result: true
---
title: 'string or string'
context: {a: 'abc', b: 'abc'}
template: {$eval: "a || b"}
result: true
---
title: 'string and number'
context: {a: 'abc', b: 123}
template: {$eval: "a && b"}
result: true
---
title: 'string or number'
context: {a: 'abc', b: 123}
template: {$eval: "a || b"}
result: true
---
title: 'string and null'
context: {a: 'abc', b: null}
template: {$eval: "a && b"}
result: false
---
title: 'string or null'
context: {a: 'abc', b: null}
template: {$eval: "a || b"}
result: true
---
title: 'string and boolean'
context: {a: 'abc', b: true}
template: {$eval: "a && b"}
result: true
---
title: 'string or boolean'
context: {a: 'abc', b: true}
template: {$eval: "a || b"}
result: true
---
title: 'string and object'
context: {a: 'abc', b: {}}
template: {$eval: "a && b"}
result: false
---
title: 'string or object'
context: {a: 'abc', b: {}}
template: {$eval: "a || b"}
result: true
---
title: 'string and array'
context: {a: 'abc', b: []}
template: {$eval: "a && b"}
result: false
---
title: 'string or array'
context: {a: 'abc', b: []}
template: {$eval: "a || b"}
result: true
---
title: 'number and string'
context: {a: 345, b: 'abc'}
template: {$eval: "a && b"}
result: true
---
title: 'number or string'
context: {a: 345, b: 'abc'}
template: {$eval: "a || b"}
result: true
---
title: 'number and number'
context: {a: 345, b: 123}
template: {$eval: "a && b"}
result: true
---
title: 'number or number'
context: {a: 345, b: 123}
template: {$eval: "a || b"}
result: true
---
title: 'number and null'
context: {a: 345, b: null}
template: {$eval: "a && b"}
result: false
---
title: 'number or null'
context: {a: 345, b: null}
template: {$eval: "a || b"}
result: true
---
title: 'number and boolean'
context: {a: 345, b: true}
template: {$eval: "a && b"}
result: true
---
title: 'number or boolean'
context: {a: 345, b: true}
template: {$eval: "a || b"}
result: true
---
title: 'number and object'
context: {a: 345, b: {}}
template: {$eval: "a && b"}
result: false
---
title: 'number or object'
context: {a: 345, b: {}}
template: {$eval: "a || b"}
result: true
---
title: 'number and array'
context: {a: 345, b: []}
template: {$eval: "a && b"}
result: false
---
title: 'number or array'
context: {a: 345, b: []}
template: {$eval: "a || b"}
result: true
---
title: 'null and string'
context: {a: null, b: 'abc'}
template: {$eval: "a && b"}
result: false
---
title: 'null or string'
context: {a: null, b: 'abc'}
template: {$eval: "a || b"}
result: true
---
title: 'null and number'
context: {a: null, b: 123}
template: {$eval: "a && b"}
result: false
---
title: 'null or number'
context: {a: null, b: 123}
template: {$eval: "a || b"}
result: true
---
title: 'null and null'
context: {a: null, b: null}
template: {$eval: "a && b"}
result: false
---
title: 'null or null'
context: {a: null, b: null}
template: {$eval: "a || b"}
result: false
---
title: 'null and boolean'
context: {a: null, b: true}
template: {$eval: "a && b"}
result: false
---
title: 'null or boolean'
context: {a: null, b: true}
template: {$eval: "a || b"}
result: true
---
title: 'null and object'
context: {a: null, b: {}}
template: {$eval: "a && b"}
result: false
---
title: 'null or object'
context: {a: null, b: {}}
template: {$eval: "a || b"}
result: false
---
title: 'null and array'
context: {a: null, b: []}
template: {$eval: "a && b"}
result: false
---
title: 'null or array'
context: {a: null, b: []}
template: {$eval: "a || b"}
result: false
---
title: 'boolean and string'
context: {a: true, b: 'abc'}
template: {$eval: "a && b"}
result: true
---
title: 'boolean or string'
context: {a: true, b: 'abc'}
template: {$eval: "a || b"}
result: true
---
title: 'boolean and number'
context: {a: true, b: 123}
template: {$eval: "a && b"}
result: true
---
title: 'boolean or number'
context: {a: true, b: 123}
template: {$eval: "a || b"}
result: true
---
title: 'boolean and null'
context: {a: true, b: null}
template: {$eval: "a && b"}
result: false
---
title: 'boolean or null'
context: {a: true, b: null}
template: {$eval: "a || b"}
result: true
---
title: 'boolean and boolean'
context: {a: true, b: true}
template: {$eval: "a && b"}
result: true
---
title: 'boolean or boolean'
context: {a: true, b: true}
template: {$eval: "a || b"}
result: true
---
title: 'boolean and object'
context: {a: true, b: {}}
template: {$eval: "a && b"}
result: false
---
title: 'boolean or object'
context: {a: true, b: {}}
template: {$eval: "a || b"}
result: true
---
title: 'boolean and array'
context: {a: true, b: []}
template: {$eval: "a && b"}
result: false
---
title: 'boolean or array'
context: {a: true, b: []}
template: {$eval: "a || b"}
result: true
---
title: 'object and string'
context: {a: {}, b: 'abc'}
template: {$eval: "a && b"}
result: false
---
title: 'object or string'
context: {a: {}, b: 'abc'}
template: {$eval: "a || b"}
result: true
---
title: 'object and number'
context: {a: {}, b: 123}
template: {$eval: "a && b"}
result: false
---
title: 'object or number'
context: {a: {}, b: 123}
template: {$eval: "a || b"}
result: true
---
title: 'object and null'
context: {a: {}, b: null}
template: {$eval: "a && b"}
result: false
---
title: 'object or null'
context: {a: {}, b: null}
template: {$eval: "a || b"}
result: false
---
title: 'object and boolean'
context: {a: {}, b: true}
template: {$eval: "a && b"}
result: false
---
title: 'object or boolean'
context: {a: {}, b: true}
template: {$eval: "a || b"}
result: true
---
title: 'object and object'
context: {a: {}, b: {}}
template: {$eval: "a && b"}
result: false
---
title: 'object or object'
context: {a: {}, b: {}}
template: {$eval: "a || b"}
result: false
---
title: 'object and array'
context: {a: {}, b: []}
template: {$eval: "a && b"}
result: false
---
title: 'object or array'
context: {a: {}, b: []}
template: {$eval: "a || b"}
result: false
---
title: 'array and string'
context: {a: [], b: 'abc'}
template: {$eval: "a && b"}
result: false
---
title: 'array or string'
context: {a: [], b: 'abc'}
template: {$eval: "a || b"}
result: true
---
title: 'array and number'
context: {a: [], b: 123}
template: {$eval: "a && b"}
result: false
---
title: 'array or number'
context: {a: [], b: 123}
template: {$eval: "a || b"}
result: true
---
title: 'array and null'
context: {a: [], b: null}
template: {$eval: "a && b"}
result: false
---
title: 'array or null'
context: {a: [], b: null}
template: {$eval: "a || b"}
result: false
---
title: 'array and boolean'
context: {a: [], b: true}
template: {$eval: "a && b"}
result: false
---
title: 'array or boolean'
context: {a: [], b: true}
template: {$eval: "a || b"}
result: true
---
title: 'array and object'
context: {a: [], b: {}}
template: {$eval: "a && b"}
result: false
---
title: 'array or object'
context: {a: [], b: {}}
template: {$eval: "a || b"}
result: false
---
title: 'array and array'
context: {a: [], b: []}
template: {$eval: "a && b"}
result: false
---
title: 'array or array'
context: {a: [], b: []}
template: {$eval: "a || b"}
result: false
---
title: 'short-circuit evaluation for and'
context: {}
template: {$eval: "false && b"}
result: false
---
title: 'short-circuit evaluation for or'
context: {}
template: {$eval: "true || b"}
result: true
---
section: expression language - string operations
---
title: 'string concatenation (1)'
context: {a: 3, b: 2}
template: {$eval: '"a" + "b"'}
result: 'ab'
---
title: 'TypeError: string + number (1)'
context: {a: 3, b: 2}
template: {$eval: '"a" + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'TypeError: string + number (2)'
context: {a: 3, b: 2}
template: {$eval: '"" + a + b'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'TypeError: string + number (3)'
context: {a: 3, b: 2}
template: {$eval: '"" + (a + b)'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'TypeError: number + string (4)'
context: {a: 3, b: 2}
template: {$eval: '(a + b) + "abc"'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'string indexing (1)'
context: {key: '12345'}
template: {$eval: 'key[1]'}
result: '2'
---
title: 'string indexing (2)'
context: {key: '12345'}
template: {$eval: 'key[-2]'}
result: '4'
---
title: 'string indexing (3)'
context: {}
template: {$eval: '"12345"[1]'}
result: '2'
---
title: 'string indexing (4)'
context: {}
template: {$eval: '"12345"[-2]'}
result: '4'
---
title: 'string indexing (unicode)'
context: {key: "\u2622abc\U0001F601"}
template: {$eval: '[key[0], key[2], key[-1]]'}
result: ["\u2622", "b", "\U0001F601"]
---
title: 'string indexing (noninteger)'
context: {}
template: {$eval: '"12345"[2.5]'}
error: 'InterpreterError: should only use integers to access arrays or strings'
---
title: 'string slicing (1)'
context: {key: '12345'}
template: {$eval: 'key[1:-1]'}
result: '234'
---
title: 'string slicing (2)'
context: {key: '12345'}
template: {$eval: 'key[-2:]'}
result: '45'
---
title: 'string slicing (noninteger first index)'
context: {key: '12345'}
template: {$eval: 'key[1.5:3]'}
error: 'InterpreterError: cannot perform interval access with non-integers'
---
title: 'string slicing (noninteger second index)'
context: {key: '12345'}
template: {$eval: 'key[1:3.5]'}
error: 'InterpreterError: cannot perform interval access with non-integers'
---
title: 'string slicing (noninteger indexes)'
context: {key: '12345'}
template: {$eval: 'key[1.5:3.5]'}
error: 'InterpreterError: cannot perform interval access with non-integers'
---
title: 'string slicing type error (1)'
context: {key: '12345'}
template: {$eval: 'key["a":]'}
error: 'InterpreterError: cannot perform interval access with non-integers'
---
title: 'string slicing type error (2)'
context: {key: '12345'}
template: {$eval: 'key[:"a"]'}
error: 'InterpreterError: cannot perform interval access with non-integers'
---
title: 'string length attribute is an error'
context: {key: '12345'}
template: {$eval: 'key.length'}
error: 'InterpreterError: infix: . expects objects'
---
title: 'string length attribute is an error even by index'
context: {key: '12345'}
template: {$eval: 'key["length"]'}
error: 'InterpreterError: should only use integers to access arrays or strings'
---
title: 'other string attributes are not set'
context: {key: 'abc'}
template: {$eval: 'key.toUpperCase()'}
error: 'InterpreterError: infix: . expects objects'
---
title: 'non-identifier after dot'
context: {key: {}}
template: {$eval: 'key.{'}
error: 'SyntaxError: Found: { token, expected one of: identifier'
---
section: expression language - property access
---
title: 'property with numeric value'
context: {key: 1}
template: {$eval: 'key'}
result: 1
---
title: 'property with string value'
context: {key: 'a'}
template: {$eval: 'key'}
result: 'a'
---
title: 'property with boolean value'
context: {key: true}
template: {$eval: 'key'}
result: true
---
title: 'property with object value'
context: {key: {a: 1}}
template: {$eval: 'key'}
result: {a: 1}
---
title: 'property with null value'
context: {key: 'null'}
template: {$eval: 'key'}
result: 'null'
---
title: 'property that is also a function name'
context: {min: abc}
template: {$eval: 'min'}
result: abc
---
title: 'missing property'
context: {key: {a: 1}}
template: {$eval: 'key.b'}
error: 'InterpreterError: object has no property "b"'
---
title: 'missing property by name'
context: {key: {a: 1}}
template: {$eval: 'key["b"]'}
result: null
---
title: 'single property access with object value'
context: {key: {key2: 3}}
template: {$eval: 'key.key2'}
result: 3
---
title: 'nested property access with object value'
context: {key: {key2: {key3: {a: 1}}}}
template: {$eval: 'key.key2.key3'}
result: {a: 1}
---
title: 'nested property access with numeric value'
context: {key: {key2: {key3: 1}}}
template: {$eval: 'key["key2"]["key3"]'}
result: 1
---
title: 'nested property access with dot following ]'
context: {key: {key2: {key3: 1}}}
template: {$eval: 'key["key2"].key3'}
result: 1
---
title: 'nested property with object in parentheses'
context: {key: {key2: true}}
template: {$eval: '(key)["key2"]'}
result: true
---
title: 'nested property with object expression'
context: {keyid: 1, keys: [false, {key2: true}]}
template: {$eval: '(keys[keyid])["key2"]'}
result: true
---
title: 'property access with expression value'
context: {key: abc, values: {abc: 2, def: 3}}
template: {$eval: 'values[key]'}
result: 2
---
title: 'property starting with underscore'
context: {_key: abc}
template: {$eval: '_key'}
result: abc
---
title: 'property containing underscore'
context: {my_key: abc}
template: {$eval: 'my_key'}
result: abc
---
title: 'property containing hyphen'
context: {my-key: abc}
template: {$eval: 'my-key'}
error: 'TemplateError: top level keys of context must follow /[a-zA-Z_][a-zA-Z0-9_]*/'
---
title: 'property starting with capital'
context: {Key: abc}
template: {$eval: 'Key'}
result: abc
---
title: 'property containing capital'
context: {kEy: abc}
template: {$eval: 'kEy'}
result: abc
---
title: 'case sensitivity of keys'
context: {key: abc}
template: {$eval: 'Key'}
error: 'InterpreterError: unknown context value Key'
---
title: 'property starting with number'
context: {'2fast': abc}
template: {$eval: '2fast'}
error: 'TemplateError: top level keys of context must follow /[a-zA-Z_][a-zA-Z0-9_]*/'
---
title: 'property containing number'
context: {furious5: abc}
template: {$eval: 'furious5'}
result: abc
---
title: 'nested property starting with underscore'
context: {key: {_foo: abc}}
template: {$eval: 'key._foo'}
result: abc
---
title: 'nested property containing underscore'
context: {key: {foo_bar: abc}}
template: {$eval: 'key.foo_bar'}
result: abc
---
title: 'nested property containing hyphen'
context: {key: {my-foo: abc}}
template: {$eval: 'key.my-foo'}
error: 'InterpreterError: object has no property "my"'
---
title: 'nested property containing hyphen using brackets'
context: {key: {my-foo: abc}}
template: {$eval: "key['my-foo']"}
result: abc
---
title: 'nested property starting with capital'
context: {key: {Foo: abc}}
template: {$eval: 'key.Foo'}
result: abc
---
title: 'nested property containing capital'
context: {key: {fOo: abc}}
template: {$eval: 'key.fOo'}
result: abc
---
title: 'case sensitivity of nested keys'
context: {key: {foo: abc}}
template: {$eval: 'key.Foo'}
error: 'InterpreterError: object has no property "Foo"'
---
title: 'property access with number'
context:
obj: {'13': 15}
key: 13 template: {$eval: 'obj[key]'}
error: 'InterpreterError: object keys must be strings'
---
title: 'property of number'
context: {key: 123}
template: {$eval: 'key.valueOf'}
error: 'InterpreterError: infix: . expects objects'
---
title: 'property of null'
context: {key: null}
template: {$eval: 'key.foo'}
error: 'InterpreterError: infix: . expects objects'
---
title: 'property of boolean'
context: {key: null}
template: {$eval: 'key.valueOf'}
error: 'InterpreterError: infix: . expects objects'
---
title: 'property of array'
context: {key: []}
template: {$eval: 'key.valueOf'}
error: 'InterpreterError: infix: . expects objects'
---
title: 'non-identifier after dot'
context: {key: {}}
template: {$eval: 'key.{'}
error: 'SyntaxError: Found: { token, expected one of: identifier'
---
title: 'non-identifier after dot (2)'
context: {key: {}}
template: {$eval: 'key.{'}
error: 'SyntaxError: Found: { token, expected one of: identifier'
---
section: expression language - array access
---
title: 'numeric'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[0]'}
result: 1
---
title: 'numeric, nonzero index'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[2]'}
result: 3
---
title: 'numeric, noninteger index'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[2.5]'}
error: 'InterpreterError: should only use integers to access arrays or strings'
---
title: 'arithemtic with results'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[0] + key[1] + key[2] + key[3] + key[4]'}
result: 15
---
title: 'string index'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key["a"]'}
error: 'InterpreterError: should only use integers to access arrays or strings'
---
title: 'too-large index'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[999]'}
error: 'InterpreterError: index out of bounds'
---
title: 'negative index'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[-1]'}
result: 5
---
title: 'nested, in property accesses'
context: {key: {key2: {key3: [1,2,3,4,5]}}}
template: {$eval: 'key.key2.key3[0]'}
result: 1
---
title: 'nested, in property access by string'
context: {key: {key2: {key3: [1,2,3,4,5]}}}
template: {$eval: 'key["key2"]["key3"][0]'}
result: 1
---
title: 'nested, nonzero index'
context: {key: {key2: {key3: [1,2,3,4,5]}}}
template: {$eval: 'key.key2.key3[2]'}
result: 3
---
title: 'nested, nonzero index, in property access by string'
context: {key: {key2: {key3: [1,2,3,4,5]}}}
template: {$eval: 'key["key2"]["key3"][2]'}
result: 3
---
title: 'nested, with arithmetic'
context: {key: {key2: {key3: [1,2,3,4,5]}}}
template: {$eval: 'key.key2.key3[0] + key.key2.key3[1] + key.key2.key3[2] + key.key2.key3[3] + key.key2.key3[4]'}
result: 15
---
title: 'nested, with arithmetic, in property access by string'
context: {key: {key2: {key3: [1,2,3,4,5]}}}
template: {$eval: 'key["key2"]["key3"][0] + key["key2"]["key3"][1] + key["key2"]["key3"][2] + key["key2"]["key3"][3] + key["key2"]["key3"][4]'}
result: 15
---
title: 'indexing number'
context: {key: 123}
template: {$eval: 'key[2]'}
error: 'InterpreterError: infix: "[..]" expects object, array, or string'
---
title: 'indexing null'
context: {key: null}
template: {$eval: 'key[2]'}
error: 'InterpreterError: infix: "[..]" expects object, array, or string'
---
title: 'indexing boolean'
context: {key: true}
template: {$eval: 'key[2]'}
error: 'InterpreterError: infix: "[..]" expects object, array, or string'
---
title: 'indexing object'
context: {key: {x: 10}}
template: {$eval: 'key[2]'}
error: 'InterpreterError: object keys must be strings'
---
title: 'array length property is an error'
context: {key: [1, 3, 5]}
template: {$eval: 'key.length'}
error: 'InterpreterError: infix: . expects objects'
---
title: 'array length property is an error even by index'
context: {key: [1, 3, 5]}
template: {$eval: 'key["length"]'}
error: 'InterpreterError: should only use integers to access arrays or strings'
---
title: 'other array attributes are not available'
context: {key: [5, 3, 1]}
template: {$eval: 'key.sort'}
error: 'InterpreterError: infix: . expects objects'
---
section: expression language - slicing
---
title: 'array slicing (full slice)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[0:5]'}
result: [1,2,3,4,5]
---
title: 'array slicing (prefix)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[0:3]'}
result: [1,2,3]
---
title: 'array slicing (out of order)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[3:2]'}
result: []
---
title: 'array slicing (negative indices)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[-5:-1]'}
result: [1,2,3,4]
---
title: 'array slicing (negative indices larger than length)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[-10:-1]'}
result: [1,2,3,4]
---
title: 'array slicing (noninteger first index)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[2.5: 4]'}
error: true
---
title: 'array slicing (noninteger last index)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[2: 3.5]'}
error: true
---
title: 'array slicing (noninteger indexes)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[2.5: 3.5]'}
error: true
---
title: 'array slicing (floor)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[:floor(len(key)/2)]'}
result: [1, 2]
---
title: 'array slicing (no end index)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[-4:]'}
result: [2,3,4,5]
---
title: 'array slicing (no start index)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[:-3]'}
result: [1,2]
---
title: 'array slicing type error (1)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key["a":]'}
error: true
---
title: 'array slicing type error (2)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[:"a"]'}
error: true
---
title: 'array slicing type error (3)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key["a":"b"]'}
error: true
---
title: 'array slicing type error (4)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key[1:"a"]'}
error: true
---
title: 'array slicing type error (5)'
context: {key: [1,2,3,4,5]}
template: {$eval: 'key["a":2]'}
error: true
---
title: 'slicing number'
context: {key: 123}
template: {$eval: 'key[2:]'}
error: true
---
title: 'slicing null'
context: {key: null}
template: {$eval: 'key[2:]'}
error: true
---
title: 'slicing boolean'
context: {key: true}
template: {$eval: 'key[2:]'}
error: true
---
title: 'slicing object'
context: {key: {x: 10}}
template: {$eval: 'key[2:]'}
error: true
---
title: 'string slicing - full'
context: {key: "hello"}
template: {$eval: 'key[0:6]'}
result: "hello"
---
title: 'string slicing - prefix'
context: {key: "hello"}
template: {$eval: 'key[0:3]'}
result: "hel"
---
title: 'string slicing - omitted first index'
context: {key: "hello"}
template: {$eval: 'key[:3]'}
result: "hel"
---
title: 'string slicing - omitted second index'
context: {key: "hello"}
template: {$eval: 'key[3:]'}
result: "lo"
---
title: 'string slicing - negative index, omitted second index'
context: {key: "hello"}
template: {$eval: 'key[-3:]'}
result: "llo"
---
title: 'string slicing - negative index'
context: {key: "hello"}
template: {$eval: 'key[-3:4]'}
result: "ll"
---
title: 'string slicing - negative greater than length'
context: {key: "hello"}
template: {$eval: 'key[-9:]'}
result: "hello"
---
title: 'string slicing - unicode indices'
context: {key: "\u2622abc\U0001F601"}
template: {$eval: '[key[0:1], key[1:4], key[-1:]]'}
result: ["\u2622", "abc", "\U0001F601"]
---
section: expression language - function calls
---
title: 'function call (1)'
context: {a: 3, b: 2}
template: {$eval: 'min(a, b)'}
result: 2
---
title: 'function call (2)'
context: {a: 3, b: 2}
template: {$eval: 'min(3, b)'}
result: 2
---
title: 'function call (3)'
context: {a: 3, b: 2}
template: {$eval: 'min(a, 2)'}
result: 2
---
title: 'function call (4)'
context: {a: 3, b: 2}
template: {$eval: 'min(3, 2)'}
result: 2
---
title: 'function call (5)'
context: {a: 3, b: 2}
template: {$eval: 'max(a, b)'}
result: 3
---
title: 'function call (6)'
context: {a: 3, b: 2}
template: {$eval: 'max(3, b)'}
result: 3
---
title: 'function call (7)'
context: {a: 3, b: 2}
template: {$eval: 'max(a, 2)'}
result: 3
---
title: 'function call (8)'
context: {a: 3, b: 2}
template: {$eval: 'max(3, 2)'}
result: 3
---
title: 'function call (9)'
context: {a: 3, b: 2}
template: {$eval: 'min(a, b) + max(a, b)'}
result: 5
---
title: 'function call (10)'
context: {a: 3, b: 2}
template: {$eval: 'min(3, b) + max(3, b)'}
result: 5
---
title: 'function call (11)'
context: {a: 3, b: 2}
template: {$eval: 'min(a, 2) + max(a, 2)'}
result: 5
---
title: 'function call (12)'
context: {a: 3, b: 2}
template: {$eval: 'min(3, 2) + max(3, 2)'}
result: 5
---
title: 'function call (13)'
context: {}
template: {$let: {functions: [{$eval: min}, {$eval: max}]}, in: {$eval: 'functions[1](2, 3)'}}
result: 3
---
title: 'function call (14)'
context: {}
template: {$eval: '[max,min][1](5, 1)'}
result: 1
---
title: 'function name is not callable'
context: {function: "hi"}
template: {$eval: "function(10)"}
error: "InterpreterError: hi is not callable"
---
title: 'parenthesized function expression'
context: {}
template: {$eval: "(min)(10, 20)"}
result: 10
---
title: 'dotted function expression'
context: {}
template: {$let: {negated: {max: {$eval: min}, min: {$eval: max}}}, in: {$eval: "(negated.min)(10, 20)"}}
result: 20
---
title: accessor after function call
context: {}
template: {$eval: 'split("left:right", ":")[1]'}
result: right
---
section: expression language - in operator
---
title: 'in operator on string, success (1)'
context: {}
template: {$eval: '"abc" in "aabc"'}
result: true
---
title: 'in operator on string, failure (2)'
context: {}
template: {$eval: '"efg" in "aabc"'}
result: false
---
title: 'in operator on string, success (3)'
context: {key: 'aabc'}
template: {$eval: '"abc" in key'}
result: true
---
title: 'in operator on string, failure (4)'
context: {key: 'aabc'}
template: {$eval: '"efg" in key'}
result: false
---
title: 'in operator on string, failure (5)'
context: {key: 'aabc'}
template: {$eval: '"2" in key'}
result: false
---
title: 'in operator on array, success (1)'
context: {}
template: {$eval: '"abc" in [1, "abc", "def"]'}
result: true
---
title: 'in operator on array, success (2)'
context: {}
template: {$eval: '1 in [1, "abc", "def"]'}
result: true
---
title: 'in operator on array, success (3)'
context: {key: [1, 'abc', 'def']}
template: {$eval: '"abc" in key'}
result: true
---
title: 'in operator on array, success (3)'
context: {key: [1, 'abc', 'def']}
template: {$eval: '1 in key'}
result: true
---
title: 'in operator on array, failure (1)'
context: {}
template: {$eval: '"efg" in [1, "abc", "def"]'}
result: false
---
title: 'in operator on array, failure (2)'
context: {}
template: {$eval: '2 in [1, "abc", "def"]'}
result: false
---
title: 'in operator on array, failure (2)'
context: {key: [1, 'abc', 'def']}
template: {$eval: '"efg" in key'}
result: false
---
title: 'in operator on array, failure (4)'
context: {key: [1, 'abc', 'def']}
template: {$eval: '2 in key'}
result: false
---
title: 'in operator on object, success (1)'
context: {}
template: {$eval: '"a" in {"a": 1, b: 2}'}
result: true
---
title: 'in operator on object, success (2)'
context: {key: {a: 1, b: 2}}
template: {$eval: '"a" in key'}
result: true
---
title: 'in operator on object, success (3)'
context: {}
template: {$eval: '"3.4" in {"3.4": 1, "b": 2}'}
result: true
---
title: 'in operator on object, failure (1)'
context: {}
template: {$eval: '"c" in {a: 1, "b": 2}'}
result: false
---
title: 'in operator on object, failure (2)'
context: {key: {a: 1, b: 2}}
template: {$eval: '"c" in key'}
result: false
---
title: 'in operator on object, failure (3)'
context: {}
template: {$eval: '"a" in {"3": 1, "b": 2}'}
result: false
---
title: 'in operator on object, failure (4)'
context: {}
template: {$eval: '"3.4" in {"3": 1, "b": 2}'}
result: false
---
title: 'TypeError: in operator on Object, error (1)'
context: {key: {a: 1, b: 2}}
template: {$eval: '[] in key'}
error: true
---
title: 'TypeError: in operator on Object, error (2)'
context: {key: {a: 1, b: 2}}
template: {$eval: '{} in key'}
error: true
---
title: 'TypeError: in operator on Object, error (3)'
context: {key: {a: 1, b: 2}}
template: {$eval: '1 in key'}
error: true
---
title: 'TypeError: in operator on Array, Array not found'
context: {key: [2,3,4]}
template: {$eval: '[] in key'}
result: false
---
title: 'TypeError: in operator on String, error (1)'
context: {key: 'hello world!'}
template: {$eval: '[] in key'}
error: true
---
title: 'TypeError: in operator on String, error (2)'
context: {key: 'hello world!'}
template: {$eval: '{} in key'}
error: true
---
title: 'TypeError: in operator on String, error (3)'
context: {key: 'hello world!'}
template: {$eval: '1 in key'}
error: true
---
title: 'TypeError: in operator on Array, object not found'
context: {key: [2,3,4]}
template: {$eval: '{} in key'}
result: false
---
title: 'no type conversion from num to string in array'
context: {}
template: {$eval: '5 in ["5", "five"]'}
result: false
---
title: 'no type conversion from string to num in array'
context: {}
template: {$eval: '"5" in [5]'}
result: false
---
title: 'cannot search for num in object'
context: {}
template: {$eval: '5 in {"5": "five"}'}
error: true
---
title: 'deep equality, object on left side, found'
context: {}
template: {$eval: '{a: 45} in ["string", 46, {a: 45}]'}
result: true
---
title: 'deep equality, object on left side, not found'
context: {}
template: {$eval: '{a: {b: 13}} in ["string", 46, {a: {b: 14}}]'}
result: false
---
title: 'deep equality, Array on left side, found'
context: {}
template: {$eval: '[44, 45] in ["string", 46, [44, 45]]'}
result: true
---
title: 'deep equality, Array on left side, not found'
context: {}
template: {$eval: '[44, 45] in ["string", 46, [44]]'}
result: false
---
title: 'precedence of in over ||'
context: {a: 'a', b: 'ab'}
template: {$eval: "a in b || true"}
result: true
---
title: 'precedence of in over &&'
context: {a: 'a', b: 'bc'}
template: {$eval: "a in b && true"}
result: false
---
title: 'compare precedence of in and =='
context: {a: 'a', b: 'ab', x: 5,'y': 7 }
template: {$eval: "a in b || x==y"}
result: true
---
section: expression language - comparisons
---
title: 'equality (1)'
context: {a: 1, b: 1}
template: {$eval: '1 == 1'}
result: true
---
title: 'equality (2)'
context: {a: 1, b: 1}
template: {$eval: '1 == 2'}
result: false
---
title: equality (3)
context: {}
template: {$eval: '4 == 3.2 + 0.8'}
result: true
---
title: 'equality (4)'
context: {a: 1, b: 1}
template: {$eval: 'a == b'}
result: true
---
title: 'equality (5)'
context: {a: 1, b: 2}
template: {$eval: 'a == b'}
result: false
---
title: object equality, true
context: {a: {x: 1,'y': 2}, b: {x: 1,'y': 2}}
template: {$eval: 'a == b'}
result: true
---
title: object equality, false
context: {a: {x: 1,'y': 2}, b: {x: 2,'y': 2}}
template: {$eval: 'a == b'}
result: false
---
title: object in-equality, true
context: {a: {x: 1,'y': 2}, b: {x: 2,'y': 2}}
template: {$eval: 'a != b'}
result: true
---
title: object in-equality, false
context: {a: {x: 1,'y': 2}, b: {x: 1,'y': 2}}
template: {$eval: 'a != b'}
result: false
---
title: complex object equality, true
context: {a: {x: 1,'y': {e: {g: {one: 1}}}}, b: {x: 1,'y': {e: {g: {one: 1}}}}}
template: {$eval: 'a == b'}
result: true
---
title: complex object equality, false
context: {a: {x: 1,'y': {e: {g: {one: 1}}}}, b: {x: 1,'y': {e: {g: {two: 2}}}}}
template: {$eval: 'a == b'}
result: false
---
title: complex object in-equality, true
context: {a: {x: 1,'y': {e: {g: {one: 1}}}}, b: {x: 1,'y': {e: {g: {two: 2}}}}}
template: {$eval: 'a != b'}
result: true
---
title: complex object in-equality, false
context: {a: {x: 1,'y': {e: {g: {one: 1}}}}, b: {x: 1,'y': {e: {g: {one: 1}}}}}
template: {$eval: 'a != b'}
result: false
---
title: 'in-equality (1)'
context: {a: 1, b: 1}
template: {$eval: '1 != 1'}
result: false
---
title: 'in-equality (2)'
context: {a: 1, b: 1}
template: {$eval: '1 != 2'}
result: true
---
title: 'in-equality (3)'
context: {a: 1, b: 1}
template: {$eval: 'a != b'}
result: false
---
title: 'in-equality (4)'
context: {a: 1, b: 2}
template: {$eval: 'a != b'}
result: true
---
title: 'less than (1)'
context: {a: 1, b: 2}
template: {$eval: '1 < 2'}
result: true
---
title: 'less than (2)'
context: {a: 1, b: 2}
template: {$eval: '2 < 1'}
result: false
---
title: 'less than (3)'
context: {a: 1, b: 2}
template: {$eval: '"a" < "b"'}
result: true
---
title: 'less than (4)'
context: {a: 1, b: 2}
template: {$eval: '"b" < "a"'}
result: false
---
title: 'less than (5)'
context: {a: 1, b: 2}
template: {$eval: 'a < b'}
result: true
---
title: 'less than (6)'
context: {a: 1, b: 2}
template: {$eval: 'b < a'}
result: false
---
title: 'greater than (1)'
context: {a: 1, b: 2}
template: {$eval: '2 > 1'}
result: true
---
title: 'greater than (2)'
context: {a: 1, b: 2}
template: {$eval: '1 > 2'}
result: false
---
title: 'greater than (3)'
context: {a: 1, b: 2}
template: {$eval: '"b" > "a"'}
result: true
---
title: 'greater than (4)'
context: {a: 1, b: 2}
template: {$eval: '"a" > "b"'}
result: false
---
title: 'greater than (5)'
context: {a: 1, b: 2}
template: {$eval: 'b > a'}
result: true
---
title: 'greater than (6)'
context: {a: 1, b: 2}
template: {$eval: 'a > b'}
result: false
---
title: 'less than equal (1)'
context: {a: 1, b: 2}
template: {$eval: "a <= b"}
result: true
---
title: 'less than equal (2)'
context: {a: 1, b: 1}
template: {$eval: "a <= b"}
result: true
---
title: 'less than equal (3)'
context: {a: 1, b: 2}
template: {$eval: "b <= a"}
result: false
---
title: 'less than equal (4)'
context: {a: 1, b: 1}
template: {$eval: "b <= a"}
result: true
---
title: 'greater than equal (1)'
context: {a: 1, b: 2}
template: {$eval: "b >= a"}
result: true
---
title: 'greater than equal (2)'
context: {a: 1, b: 1}
template: {$eval: "a >= b"}
result: true
---
title: 'greater than equal (3)'
context: {a: 1, b: 2}
template: {$eval: "a >= b"}
result: false
---
title: 'greater than equal (4)'
context: {a: 1, b: 1}
template: {$eval: "a >= b"}
result: true
---
title: 'deep object equality'
context:
a: {left: 1, right: {left: 2, right: 3}}
b: {left: 1, right: {left: 2, right: 3}}
template: {$eval: "a == b"}
result: true
---
title: 'boolean equality'
context: {}
template: {$eval: "true == true"}
result: true
---
title: 'null equality'
context: {a: null, b: null}
template: {$eval: "a == b"}
result: true
---
title: 'string equality'
context: {a: 'xyz', b: 'xyz'}
template: {$eval: "a == b"}
result: true
---
title: 'deep object inequality'
context:
a: {left: 1, right: {left: 2, right: 3}}
b: {left: 1, right: {left: 3, right: 2}}
template: {$eval: "a != b"}
result: true
---
title: 'deep array equality'
context:
a: [1, [2, 3]]
b: [1, [2, 3]]
template: {$eval: "a == b"}
result: true
---
title: 'deep array inequality'
context:
a: [1, [2, 3]]
b: [1, [3, 2]]
template: {$eval: "a != b"}
result: true
---
title: ordering of string and string
context: {a: 'abc', b: 'def'}
template: {$eval: 'a < b'}
result: true
---
title: ordering of string and number
context: {a: 'abc', b: 27}
template: {$eval: 'a < b'}
error: true
---
title: ordering of string and null
context: {a: 'abc', b: null}
template: {$eval: 'a < b'}
error: true
---
title: ordering of string and boolean
context: {a: 'abc', b: true}
template: {$eval: 'a < b'}
error: true
---
title: ordering of string and object
context: {a: 'abc', b: {}}
template: {$eval: 'a < b'}
error: true
---
title: ordering of string and array
context: {a: 'abc', b: []}
template: {$eval: 'a < b'}
error: true
---
title: ordering of number and string
context: {a: 123, b: 'def'}
template: {$eval: 'a < b'}
error: true
---
title: ordering of number and number
context: {a: 123, b: 27}
template: {$eval: 'a < b'}
result: false
---
title: ordering of number and null
context: {a: 123, b: null}
template: {$eval: 'a < b'}
error: true
---
title: ordering of number and boolean
context: {a: 123, b: true}
template: {$eval: 'a < b'}
error: true
---
title: ordering of number and object
context: {a: 123, b: {}}
template: {$eval: 'a < b'}
error: true
---
title: ordering of number and array
context: {a: 123, b: []}
template: {$eval: 'a < b'}
error: true
---
title: ordering of null and string
context: {a: null, b: 'def'}
template: {$eval: 'a < b'}
error: true
---
title: ordering of null and number
context: {a: null, b: 27}
template: {$eval: 'a < b'}
error: true
---
title: ordering of null and null
context: {a: null, b: null}
template: {$eval: 'a < b'}
error: true
---
title: ordering of null and boolean
context: {a: null, b: true}
template: {$eval: 'a < b'}
error: true
---
title: ordering of null and object
context: {a: null, b: {}}
template: {$eval: 'a < b'}
error: true
---
title: ordering of null and array
context: {a: null, b: []}
template: {$eval: 'a < b'}
error: true
---
title: ordering of boolean and string
context: {a: true, b: 'def'}
template: {$eval: 'a < b'}
error: true
---
title: ordering of boolean and number
context: {a: true, b: 27}
template: {$eval: 'a < b'}
error: true
---
title: ordering of boolean and null
context: {a: true, b: null}
template: {$eval: 'a < b'}
error: true
---
title: ordering of boolean and boolean
context: {a: true, b: true}
template: {$eval: 'a < b'}
error: true
---
title: ordering of boolean and object
context: {a: true, b: {}}
template: {$eval: 'a < b'}
error: true
---
title: ordering of boolean and array
context: {a: true, b: []}
template: {$eval: 'a < b'}
error: true
---
title: ordering of object and string
context: {a: {}, b: 'def'}
template: {$eval: 'a < b'}
error: true
---
title: ordering of object and number
context: {a: {}, b: 27}
template: {$eval: 'a < b'}
error: true
---
title: ordering of object and null
context: {a: {}, b: null}
template: {$eval: 'a < b'}
error: true
---
title: ordering of object and boolean
context: {a: {}, b: true}
template: {$eval: 'a < b'}
error: true
---
title: ordering of object and object
context: {a: {}, b: {}}
template: {$eval: 'a < b'}
error: true
---
title: ordering of object and array
context: {a: {}, b: []}
template: {$eval: 'a < b'}
error: true
---
title: ordering of array and string
context: {a: [], b: 'def'}
template: {$eval: 'a < b'}
error: true
---
title: ordering of array and number
context: {a: [], b: 27}
template: {$eval: 'a < b'}
error: true
---
title: ordering of array and null
context: {a: [], b: null}
template: {$eval: 'a < b'}
error: true
---
title: ordering of array and boolean
context: {a: [], b: true}
template: {$eval: 'a < b'}
error: true
---
title: ordering of array and array
context: {a: [], b: {}}
template: {$eval: 'a < b'}
error: true
---
title: ordering of array and array
context: {a: [], b: []}
template: {$eval: 'a < b'}
error: true
---
title: equality of string and string
context: {a: 'abc', b: 'def'}
template: {$eval: 'a == b'}
result: false
---
title: equality of string and number
context: {a: 'abc', b: 27}
template: {$eval: 'a == b'}
result: false
---
title: equality of string and null
context: {a: 'abc', b: null}
template: {$eval: 'a == b'}
result: false
---
title: equality of string and boolean
context: {a: 'abc', b: true}
template: {$eval: 'a == b'}
result: false
---
title: equality of string and object
context: {a: 'abc', b: {}}
template: {$eval: 'a == b'}
result: false
---
title: equality of string and array
context: {a: 'abc', b: []}
template: {$eval: 'a == b'}
result: false
---
title: equality of number and string
context: {a: 123, b: 'def'}
template: {$eval: 'a == b'}
result: false
---
title: equality of number and number
context: {a: 123, b: 27}
template: {$eval: 'a == b'}
result: false
---
title: equality of number and null
context: {a: 123, b: null}
template: {$eval: 'a == b'}
result: false
---
title: equality of number and boolean
context: {a: 123, b: true}
template: {$eval: 'a == b'}
result: false
---
title: equality of number and object
context: {a: 123, b: {}}
template: {$eval: 'a == b'}
result: false
---
title: equality of number and array
context: {a: 123, b: []}
template: {$eval: 'a == b'}
result: false
---
title: equality of null and string
context: {a: null, b: 'def'}
template: {$eval: 'a == b'}
result: false
---
title: equality of null and number
context: {a: null, b: 27}
template: {$eval: 'a == b'}
result: false
---
title: equality of null and null
context: {a: null, b: null}
template: {$eval: 'a == b'}
result: true
---
title: equality of null and boolean
context: {a: null, b: true}
template: {$eval: 'a == b'}
result: false
---
title: equality of null and object
context: {a: null, b: {}}
template: {$eval: 'a == b'}
result: false
---
title: equality of null and array
context: {a: null, b: []}
template: {$eval: 'a == b'}
result: false
---
title: equality of boolean and string
context: {a: true, b: 'def'}
template: {$eval: 'a == b'}
result: false
---
title: equality of boolean and number
context: {a: true, b: 27}
template: {$eval: 'a == b'}
result: false
---
title: equality of boolean and null
context: {a: true, b: null}
template: {$eval: 'a == b'}
result: false
---
title: equality of boolean and boolean
context: {a: true, b: true}
template: {$eval: 'a == b'}
result: true
---
title: equality of boolean and object
context: {a: true, b: {}}
template: {$eval: 'a == b'}
result: false
---
title: equality of boolean and array
context: {a: true, b: []}
template: {$eval: 'a == b'}
result: false
---
title: equality of object and string
context: {a: {}, b: 'def'}
template: {$eval: 'a == b'}
result: false
---
title: equality of object and number
context: {a: {}, b: 27}
template: {$eval: 'a == b'}
result: false
---
title: equality of object and null
context: {a: {}, b: null}
template: {$eval: 'a == b'}
result: false
---
title: equality of object and boolean
context: {a: {}, b: true}
template: {$eval: 'a == b'}
result: false
---
title: equality of object and object
context: {a: {}, b: {}}
template: {$eval: 'a == b'}
result: true
---
title: equality of object and array
context: {a: {}, b: []}
template: {$eval: 'a == b'}
result: false
---
title: equality of array and string
context: {a: [], b: 'def'}
template: {$eval: 'a == b'}
result: false
---
title: equality of array and number
context: {a: [], b: 27}
template: {$eval: 'a == b'}
result: false
---
title: equality of array and null
context: {a: [], b: null}
template: {$eval: 'a == b'}
result: false
---
title: equality of array and boolean
context: {a: [], b: true}
template: {$eval: 'a == b'}
result: false
---
title: equality of array and object
context: {a: [], b: {}}
template: {$eval: 'a == b'}
result: false
---
title: equality of array and array
context: {a: [], b: []}
template: {$eval: 'a == b'}
result: true
---
title: equality of functions
context: {}
template: {$eval: 'min == min'}
result: true
---
title: inequality of functions
context: {}
template: {$eval: 'min == max'}
result: false
---
title: equality of function and string
context: {}
template: {$eval: 'min == "min"'}
result: false
---
title: equality of function and number
context: {}
template: {$eval: 'min == 13'}
result: false
---
section: expression language - compound literals
---
title: 'parse list (1)'
context: {}
template: {$eval: '[1,2,3,4]'}
result: [1,2,3,4]
---
title: 'parse list (2)'
context: {}
template: {$eval: '[1,2,3,4][0]'}
result: 1
---
title: 'parse list (3)'
context: {}
template: {$eval: '[1,2,3,4][0:-1]'}
result: [1,2,3]
---
title: 'parse list (4)'
context: {}
template: {$eval: '[1,2,3,4'}
error: true
---
title: 'parse object (1)'
context: {key: 1}
template: {$eval: '{a: key, "b": key + 1}'}
result: {a: 1, b: 2}
---
title: 'parse object (2)'
context: {key: 1}
template: {$eval: '{"a": key, b: key + 1}'}
result: {a: 1, b: 2}
---
title: 'parse object (3)'
context: {key: 1}
template: {$eval: '{"a": key, "b": key + 1}'}
result: {a: 1, b: 2}
---
title: 'parse object (4)'
context: {key: 1}
template: {$eval: '{"a": key, b: [key,key+1,key+2]}'}
result: {a: 1, b: [1,2,3]}
---
title: 'parse object (5)'
context: {key: 1}
template: {$eval: '{a: key, "b": [key,key+1,key+2]}'}
result: {a: 1, b: [1,2,3]}
---
title: 'parse object (6)'
context: {key: 1}
template: {$eval: '{"a": key, "b": [key,key+1,key+2]}'}
result: {a: 1, b: [1,2,3]}
---
title: 'parse object (7)'
context: {key: 1}
template: {$eval: '{a: key, b: [key,key+1,key+2]}'}
result: {a: 1, b: [1,2,3]}
---
title: 'parse object (8)'
context: {key: 1}
template: {$eval: '{a: key, b: min(key + 1, 1)}'}
result: {a: 1, b: 1}
---
title: 'parse object (9)'
context: {key: 1}
template: {$eval: '{"a": key, b: min(key + 1, 1)}'}
result: {a: 1, b: 1}
---
title: 'parse object (10)'
context: {key: 1}
template: {$eval: '{a: key, "b": min(key + 1, 1)}'}
result: {a: 1, b: 1}
---
title: 'parse object (11)'
context: {key: 1}
template: {$eval: '{"a": key, "b": min(key + 1, 1)}'}
result: {a: 1, b: 1}
---
title: 'parse object (12)'
context: {key: 1}
template: {$eval: '{a: key, b: key + 1'}
error: true
---
section: expression language - errors
---
title: 'unary - type error'
context: {key: 'hello'}
template: {$eval: '-key'}
error: 'InterpreterError: unary - expects number'
---
title: 'unary + type error'
context: {key: 'hello'}
template: {$eval: '+key'}
error: 'InterpreterError: unary + expects number'
---
title: 'undefined variable'
context: {key: 'hello'}
template: {$eval: 'key2'}
error: 'InterpreterError: unknown context value key2'
---
title: 'missing closing parenthesis'
context: {key1: 1, key2: 1}
template: {$eval: 'key1 + (key2 + key1'}
error: true
---
title: 'missing opening parenthesis'
context: {key1: 1, key2: 1}
template: {$eval: 'key1 + key2 + key1)'}
error: true
---
title: 'missing closing "'
context: {}
template: {$eval: '"hello'}
error: true
---
title: 'missing opening "'
context: {}
template: {$eval: 'hello"'}
error: "SyntaxError: Unexpected input for 'hello\"' at '\"'"
---
title: 'Infix + type error'
context: {}
template: {$eval: 'true + false'}
error: 'InterpreterError: infix: + expects numbers/strings + numbers/strings'
---
title: 'Infix - type error'
context: {}
template: {$eval: '"hello" - 3'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'Infix * type error'
context: {}
template: {$eval: '"hello" * 3'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'Infix / type error'
context: {}
template: {$eval: '"hello" / 3'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'Infix - type error'
context: {}
template: {$eval: '3 - "hello"'}
error: 'InterpreterError: infix: - expects number - number'
---
title: 'Infix * type error'
context: {}
template: {$eval: '3 * "hello"'}
error: 'InterpreterError: infix: * expects number * number'
---
title: 'Infix / type error'
context: {}
template: {$eval: '3 / "hello"'}
error: 'InterpreterError: infix: / expects number / number'
---
title: 'Infix ** type error'
context: {}
template: {$eval: '"hello" ** 3'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'Infix ** type error'
context: {}
template: {$eval: '3 ** "hello"'}
error: 'InterpreterError: infix: ** expects number ** number'
---
title: 'Infix < type error'
context: {}
template: {$eval: '"hello" < 3'}
error: 'InterpreterError: infix: < expects numbers/strings < numbers/strings'
---
title: 'Infix > type error'
context: {}
template: {$eval: '"hello" > 3'}
error: 'InterpreterError: infix: > expects numbers/strings > numbers/strings'
---
title: 'Infix <= type error'
context: {}
template: {$eval: '"hello" <= 3'}
error: 'InterpreterError: infix: <= expects numbers/strings <= numbers/strings'
---
title: 'Infix >= type error'
context: {}
template: {$eval: '"hello" >= 3'}
error: 'InterpreterError: infix: >= expects numbers/strings >= numbers/strings'
---
title: 'Infix < type error'
context: {}
template: {$eval: '3 < "hello"'}
error: 'InterpreterError: infix: < expects numbers/strings < numbers/strings'
---
title: 'Infix > type error'
context: {}
template: {$eval: '3 > "hello"'}
error: 'InterpreterError: infix: > expects numbers/strings > numbers/strings'
---
title: 'Infix <= type error'
context: {}
template: {$eval: '3 <= "hello"'}
error: 'InterpreterError: infix: <= expects numbers/strings <= numbers/strings'
---
title: 'Infix >= type error'
context: {}
template: {$eval: '3 >= "hello"'}
error: 'InterpreterError: infix: >= expects numbers/strings >= numbers/strings'
---
title: 'Infix access array or string with non-integer type error'
context: {extra: {attributes: 'a string!'}}
template: {$if: "extra.attributes['someattr'] == 'x'", then: true}
error: 'InterpreterError: should only use integers to access arrays or strings'
---
title: 'Nested error has appropriate message'
context: {}
template: {foo: [1, {"123": [{$eval: 10}]}]}
error: 'TemplateError at template.foo[1]["123"][0]: $eval must be given a string expression'
---
title: 'object with missing value '
context: {}
template: {$eval: '{a: 1, "b": }'}
error: "SyntaxError: Found: } token, expected one of: !, (, +, -, [, false, identifier, null, number, string, true, {"
---
title: 'object missing key and value after comma'
context: {}
template: {$eval: '{a: 1,'}
error: "SyntaxError: Unexpected end of input"
---
title: 'array missing value after comma'
context: {}
template: { $eval: '[2,1,]'}
error: true
---
title: 'list with missing first value'
context: {}
template: {$eval: '[,2,3]'}
error: "SyntaxError: Found: , token, expected one of: !, (, +, -, [, false, identifier, null, number, string, true, {"
---
title: 'list with missing value'
context: {}
template: {$eval: '[1,,3]'}
error: "SyntaxError: Found: , token, expected one of: !, (, +, -, [, false, identifier, null, number, string, true, {"
---
title: 'empty brackets in property access'
context: {a: "0123456789"}
template: {$eval: 'a[]'}
error: "SyntaxError: Found: ] token, expected one of: !, (, +, -, [, false, identifier, null, number, string, true, {"
---
title: 'function call with missing closing bracket'
context: {}
template: {$eval: 'max(2, 0'}
error: "SyntaxError: Unexpected end of input"
---
title: 'function call with missing argument in brackets'
context: {}
template: {$eval: 'max(, 0)'}
error: "SyntaxError: Found: , token, expected one of: !, (, +, -, [, false, identifier, null, number, string, true, {"
---
title: 'uncalled function'
context: {}
template: {$eval: 'fromNow'}
error: "TemplateError: evaluated template contained uncalled functions"
---
title: 'list expression with uncalled functions'
context: {}
template: {$eval: '[min, max]'}
error: "TemplateError: evaluated template contained uncalled functions"
---
title: 'list with uncalled function inside'
context: {}
template: [{$eval: 'min'}]
error: "TemplateError: evaluated template contained uncalled functions"
---
title: 'object containing uncalled function'
context: {}
template: {maximum: {$eval: 'max'}}
error: "TemplateError: evaluated template contained uncalled functions"
---
title: 'deep data structure with uncalled functions'
context: {}
template: [{minimum: {$eval: 'min'}}, {maximum: {$eval: 'max'}}]
error: "TemplateError: evaluated template contained uncalled functions"
---
title: '$json with an uncalled function'
context: {}
template: {$json: {$eval: 'lowercase'}}
error: "TemplateError: evaluated template contained uncalled functions"
---
title: '$json with deep uncalled functions'
context: {}
template: {$json: [{minimum: {$eval: 'min'}}, {maximum: {$eval: 'max'}}]}
error: "TemplateError: evaluated template contained uncalled functions"
---
section: Regression tests
---
title: issue 354
template: {$eval: 'max(3, 2)'}
context: {}
result: 3