def test_transform_decorator_using_function_name(): jexl = JEXL() @jexl.transform() def old_name(x): return x + 2 assert jexl.evaluate('3|old_name') == 5
def test_transform_decorator_explicit_name(): jexl = JEXL() @jexl.transform(name='new_name') def old_name(x): return x + 2 assert jexl.evaluate('3|new_name') == 5 with pytest.raises(MissingTransformError): jexl.evaluate('3|old_name')
def test_remove_transform(): jexl = JEXL() jexl.add_transform('foo', lambda x: x) assert jexl.evaluate('4|foo') == 4 jexl.remove_transform('foo') with pytest.raises(MissingTransformError): jexl.evaluate('4|foo')
def test_binary_operator_precedence(): jexl = JEXL() jexl.add_binary_operator('=', 50, lambda x, y: x + y) jexl.add_binary_operator('@', 100, lambda x, y: x / y) assert jexl.evaluate('(3 = 6) @ 3') == 3 assert jexl.evaluate('3 = 6 @ 3') == 5
def test_grammar_invalidation(): """ Ensure that the grammar object doesn't get stale when operators change. """ jexl = JEXL() jexl.add_unary_operator('=', lambda x: x + 5) assert jexl.evaluate('=5') == 10 jexl.remove_unary_operator('=') with pytest.raises(ParseError): jexl.evaluate('=5')
def test_validate(): jexl = JEXL() jexl.add_transform('foo', lambda x: x + 1) assert list(jexl.validate('5+6|foo')) == [] errors = list(jexl.validate('5+6|bar')) assert len(errors) == 1 assert 'bar' in errors[0] errors = list(jexl.validate('1+')) assert errors == ['Could not parse expression: 1+'] errors = list(jexl.validate('"\n"')) assert errors == ['Could not parse expression: "\n"']
def test_remove_unary_operator(): jexl = JEXL() jexl.remove_unary_operator('!') with pytest.raises(ParseError): jexl.evaluate('!true')
def test_add_custom_unary_operator(): jexl = JEXL() jexl.add_unary_operator('=', lambda x: x + 5) assert jexl.evaluate('=5') == 10
def test_it_works(): assert JEXL().evaluate('1 + 1') == 2
def test_remove_binary_operator(): jexl = JEXL() jexl.remove_binary_operator('+') with pytest.raises(ParseError): jexl.evaluate('2 + 4')
def test_add_custom_binary_operator(): jexl = JEXL() jexl.add_binary_operator('=', 20, lambda x, y: (x + y) / 2) assert jexl.evaluate('2 = 4') == 3
def test_add_transform(): jexl = JEXL() jexl.add_transform('foo', lambda x: x + 2) assert jexl.evaluate('4|foo') == 6
def test_analysis(): jexl = JEXL() assert jexl.analyze('1+(2*3)|concat(4)', SumIntAnalyzer) == 10
def test_validate_simple_equality(): jexl = JEXL() errors = list(jexl.validate('FOO_BAR ==12345')) assert errors == []
def test_parse_error(): jexl = JEXL() with pytest.raises(ParseError): jexl.evaluate('this is ( invalid + =s')
#!/usr/bin/env python3 import json import sys import jsonschema from jsonschema.exceptions import best_match, ValidationError from pyjexl.jexl import JEXL # Create a jexl evaluator EVALUATOR = JEXL() EVALUATOR.add_binary_operator('intersect', 40, lambda x, y: set(x).intersection(y)) EVALUATOR.add_transform('date', lambda x: 0) EVALUATOR.add_transform('length', lambda x: 0) EVALUATOR.add_transform('preferenceValue', lambda x: False) EVALUATOR.add_transform('mapToProperty', lambda x, y: []) EVALUATOR.add_transform('keys', lambda x: []) EVALUATOR.add_transform('bucketSample', lambda x, y, z, q: False) EVALUATOR.add_transform('stableSample', lambda x, y: False) # cache all the known schemas to validate experiments ALL_SCHEMAS = dict() SCHEMA_MAP = { "cfr": "schema/cfr.schema.json", "onboarding": "schema/onboarding.schema.json", "onboarding-multistage": "schema/onboarding-multistage.schema.json", "cfr-fxa": "schema/cfr-fxa.schema.json", "cfr-heartbeat": "schema/cfr-heartbeat.schema.json",
def jexl(): """Return an instance of the JEXL class. Useful when tests are repeated with hypothesis since only one instance of JEXL is created once.""" return JEXL()