From 92dab9608c4ea4d4d3925555f5da147f5bc15b35 Mon Sep 17 00:00:00 2001 From: Stefan Mitterrutzner Date: Fri, 1 Aug 2025 10:39:44 +0200 Subject: [PATCH 1/2] Add MapLibre expression test framework with comprehensive test suite --- shared/test/CMakeLists.txt | 4 +- shared/test/TestExpressions.cpp | 373 ++++++++++++++++++ .../data/expression-tests/abs/basic/test.json | 18 + .../expression-tests/acos/basic/test.json | 14 + .../expression-tests/all/arity-0/test.json | 14 + .../expression-tests/all/arity-1/test.json | 14 + .../data/expression-tests/all/basic/test.json | 17 + .../all/short-circuiting/test.json | 14 + .../expression-tests/any/arity-0/test.json | 14 + .../expression-tests/any/arity-1/test.json | 14 + .../data/expression-tests/any/basic/test.json | 19 + .../any/short-circuiting/test.json | 14 + .../expression-tests/array/basic/test.json | 14 + .../array/default-value/test.json | 22 ++ .../array/implicit-1/test.json | 20 + .../array/implicit-2/test.json | 32 ++ .../array/implicit-3/test.json | 33 ++ .../array/item-type-and-length/test.json | 26 ++ .../array/item-type/test.json | 28 ++ .../expression-tests/asin/basic/test.json | 14 + .../data/expression-tests/at/basic/test.json | 30 ++ .../at/infer-array-type/test.json | 20 + .../expression-tests/atan/basic/test.json | 14 + .../expression-tests/boolean/basic/test.json | 42 ++ .../boolean/default-value/test.json | 23 ++ .../expression-tests/case/basic/test.json | 40 ++ .../case/infer-array-type/test.json | 30 ++ .../case/precedence/test.json | 14 + .../expression-tests/ceil/basic/test.json | 23 ++ .../coalesce/argument-type-mismatch/test.json | 12 + .../expression-tests/coalesce/basic/test.json | 20 + .../expression-tests/coalesce/error/test.json | 36 ++ .../coalesce/infer-array-type/test.json | 26 ++ .../coalesce/inference/test.json | 25 ++ .../expression-tests/coalesce/null/test.json | 15 + .../collator/accent-equals-de/test.json | 67 ++++ .../collator/accent-lt-en/test.json | 34 ++ .../collator/accent-not-equals-en/test.json | 40 ++ .../collator/base-default-locale/test.json | 28 ++ .../collator/base-equals-en/test.json | 34 ++ .../collator/base-gt-en/test.json | 34 ++ .../collator/case-lteq-en/test.json | 35 ++ .../collator/case-not-equals-en/test.json | 40 ++ .../collator/case-omitted-en/test.json | 32 ++ .../comparison-number-error/test.json | 16 + .../collator/diacritic-omitted-en/test.json | 31 ++ .../equals-non-string-error/test.json | 16 + .../collator/non-object-error/test.json | 11 + .../collator/variant-equals-en/test.json | 34 ++ .../collator/variant-gteq-en/test.json | 35 ++ .../expression-tests/concat/arity-0/test.json | 14 + .../expression-tests/concat/arity-1/test.json | 14 + .../expression-tests/concat/basic/test.json | 14 + .../concat/coercion/test.json | 14 + .../evaluation-error/test.json | 23 ++ .../to-color-inferred/test.json | 15 + .../constant-folding/to-color/test.json | 14 + .../constant-folding/var/test.json | 21 + .../data/expression-tests/cos/basic/test.json | 14 + .../expression-tests/divide/basic/test.json | 14 + .../expression-tests/downcase/basic/test.json | 14 + .../data/expression-tests/e/basic/test.json | 14 + .../expression-tests/equal/array/test.json | 14 + .../equal/collator-value/test.json | 31 ++ .../expression-tests/equal/color/test.json | 14 + .../expression-tests/equal/mismatch/test.json | 11 + .../expression-tests/equal/null-lhs/test.json | 14 + .../expression-tests/equal/null-rhs/test.json | 14 + .../expression-tests/equal/number/test.json | 18 + .../expression-tests/equal/object/test.json | 14 + .../expression-tests/equal/string/test.json | 18 + .../expression-tests/equal/value/test.json | 21 + .../expression-tests/floor/basic/test.json | 23 ++ .../expression-tests/format/basic/test.json | 96 +++++ .../format/coercion/test.json | 56 +++ .../format/data-driven-font/test.json | 52 +++ .../format/data-driven-scale/test.json | 23 ++ .../format/image-sections/test.json | 54 +++ .../format/implicit-assert/test.json | 14 + .../format/implicit-coerce/test.json | 59 +++ .../format/implicit-omit/test.json | 59 +++ .../format/implicit/test.json | 59 +++ .../format/to-string/test.json | 42 ++ .../geometry-type/basic/test.json | 16 + .../data/expression-tests/get/basic/test.json | 17 + .../get/from-literal--missing/test.json | 15 + .../get/from-literal/test.json | 14 + .../get/from-object-property/test.json | 14 + .../greater/boolean/test.json | 14 + .../greater/mismatch/test.json | 11 + .../expression-tests/greater/null/test.json | 14 + .../expression-tests/greater/number/test.json | 18 + .../greater/string-and-value/test.json | 26 ++ .../expression-tests/greater/string/test.json | 21 + .../expression-tests/greater/value/test.json | 28 ++ .../greater_or_equal/boolean/test.json | 14 + .../greater_or_equal/mismatch/test.json | 11 + .../greater_or_equal/null/test.json | 14 + .../greater_or_equal/number/test.json | 18 + .../string-and-value/test.json | 26 ++ .../greater_or_equal/string/test.json | 21 + .../greater_or_equal/value/test.json | 28 ++ .../data/expression-tests/has/basic/test.json | 20 + .../heatmap-density/basic/test.json | 45 +++ .../data/expression-tests/id/basic/test.json | 14 + .../expression-tests/image/basic/test.json | 27 ++ .../expression-tests/image/coalesce/test.json | 29 ++ .../expression-tests/image/compound/test.json | 29 ++ .../image/implicit-assert/test.json | 14 + .../in/assert-array/test.json | 30 ++ .../in/assert-string/test.json | 30 ++ .../expression-tests/in/basic-array/test.json | 34 ++ .../in/basic-string/test.json | 36 ++ .../in/invalid-haystack/test.json | 28 ++ .../in/invalid-needle/test.json | 26 ++ .../index-of/assert-array/test.json | 26 ++ .../index-of/assert-string/test.json | 24 ++ .../index-of/basic-array/test.json | 46 +++ .../index-of/basic-string/test.json | 32 ++ .../index-of/invalid-haystack/test.json | 28 ++ .../index-of/invalid-needle/test.json | 24 ++ .../index-of/with-from-index/test.json | 50 +++ .../interpolate-hcl/linear/test.json | 40 ++ .../interpolate-lab/linear/test.json | 40 ++ .../interpolate/cubic-bezier-3-args/test.json | 26 ++ .../interpolate/cubic-bezier-5-args/test.json | 26 ++ .../test.json | 26 ++ .../interpolate/cubic-bezier/test.json | 60 +++ .../interpolate/duplicate_stops/test.json | 15 + .../exponential-number-array/test.json | 36 ++ .../exponential-single-stop/test.json | 24 ++ .../exponential-string-array/test.json | 20 + .../test.json | 20 + .../interpolate/exponential/test.json | 26 ++ .../interpolate/infer-array-type/test.json | 32 ++ .../interpolate/linear-color/test.json | 46 +++ .../interpolate/linear-many-stops/test.json | 104 +++++ .../interpolate/linear/test.json | 43 ++ .../is-supported-script/default/test.json | 18 + .../categorical/array-default/test.json | 39 ++ .../legacy/categorical/array/test.json | 39 ++ .../categorical/boolean-default/test.json | 36 ++ .../legacy/categorical/boolean/test.json | 36 ++ .../categorical/color-default/test.json | 37 ++ .../legacy/categorical/color/test.json | 37 ++ .../categorical/number-default/test.json | 31 ++ .../legacy/categorical/number/test.json | 31 ++ .../categorical/string-default/test.json | 29 ++ .../legacy/categorical/string/test.json | 29 ++ .../legacy/categorical/tokens/test.json | 30 ++ .../exponential/array-default/test.json | 47 +++ .../legacy/exponential/array/test.json | 51 +++ .../legacy/exponential/base/test.json | 19 + .../exponential/color-default/test.json | 53 +++ .../legacy/exponential/color-hcl/test.json | 50 +++ .../legacy/exponential/color-lab/test.json | 50 +++ .../legacy/exponential/color/test.json | 49 +++ .../exponential/composite-default/test.json | 55 +++ .../legacy/exponential/composite/test.json | 54 +++ .../exponential/duplicate-stops/test.json | 22 ++ .../legacy/exponential/implicit/test.json | 45 +++ .../exponential/number-default/test.json | 37 ++ .../legacy/exponential/number/test.json | 49 +++ .../legacy/identity/array-default/test.json | 25 ++ .../legacy/identity/array/test.json | 34 ++ .../legacy/identity/boolean-default/test.json | 24 ++ .../legacy/identity/boolean/test.json | 33 ++ .../legacy/identity/color-default/test.json | 23 ++ .../legacy/identity/color/test.json | 27 ++ .../legacy/identity/enum-default/test.json | 31 ++ .../legacy/identity/enum/test.json | 30 ++ .../legacy/identity/number-default/test.json | 24 ++ .../legacy/identity/number/test.json | 31 ++ .../legacy/identity/string-default/test.json | 24 ++ .../legacy/identity/string/test.json | 31 ++ .../legacy/interval/array-default/test.json | 39 ++ .../legacy/interval/array/test.json | 49 +++ .../legacy/interval/color-default/test.json | 51 +++ .../legacy/interval/color/test.json | 47 +++ .../interval/composite-default/test.json | 53 +++ .../legacy/interval/composite/test.json | 52 +++ .../legacy/interval/duplicate-stops/test.json | 22 ++ .../legacy/interval/implicit/test.json | 37 ++ .../legacy/interval/number-default/test.json | 37 ++ .../legacy/interval/number/test.json | 41 ++ .../legacy/interval/string-default/test.json | 37 ++ .../legacy/interval/string/test.json | 41 ++ .../legacy/interval/tokens-property/test.json | 34 ++ .../legacy/interval/tokens-zoom/test.json | 30 ++ .../expression-tests/length/array/test.json | 14 + .../length/implicit/test.json | 24 ++ .../expression-tests/length/invalid/test.json | 15 + .../expression-tests/length/string/test.json | 14 + .../expression-tests/less/boolean/test.json | 14 + .../expression-tests/less/mismatch/test.json | 11 + .../data/expression-tests/less/null/test.json | 14 + .../expression-tests/less/number/test.json | 18 + .../less/string-and-value/test.json | 26 ++ .../expression-tests/less/string/test.json | 21 + .../expression-tests/less/value/test.json | 28 ++ .../less_or_equal/boolean/test.json | 14 + .../less_or_equal/mismatch/test.json | 11 + .../less_or_equal/null/test.json | 14 + .../less_or_equal/number/test.json | 18 + .../less_or_equal/string-and-value/test.json | 26 ++ .../less_or_equal/string/test.json | 21 + .../less_or_equal/value/test.json | 28 ++ .../data/expression-tests/let/basic/test.json | 28 ++ .../let/expected-value/test.json | 58 +++ .../let/invalid-name/test.json | 15 + .../expression-tests/let/nested/test.json | 24 ++ .../let/property-function/test.json | 14 + .../expression-tests/let/shadow/test.json | 24 ++ .../expression-tests/let/unbound/test.json | 19 + .../data/expression-tests/let/zoom/test.json | 44 +++ .../literal/boolean-array/test.json | 14 + .../expression-tests/literal/empty/test.json | 15 + .../literal/infer-empty-array-type/test.json | 20 + .../literal/mixed-primitive-array/test.json | 14 + .../literal/multiple-args/test.json | 15 + .../literal/nested-array/test.json | 14 + .../literal/number-array/test.json | 14 + .../expression-tests/literal/object/test.json | 14 + .../literal/string-array/test.json | 14 + .../expression-tests/literal/string/test.json | 14 + .../literal/u2028u2029/test.json | 14 + .../data/expression-tests/ln/basic/test.json | 14 + .../data/expression-tests/ln2/basic/test.json | 14 + .../expression-tests/log10/basic/test.json | 14 + .../expression-tests/log2/basic/test.json | 14 + .../expression-tests/match/arity-0/test.json | 11 + .../expression-tests/match/arity-1/test.json | 11 + .../expression-tests/match/arity-2/test.json | 12 + .../expression-tests/match/arity-3/test.json | 12 + .../expression-tests/match/basic/test.json | 28 ++ .../match/empty-case/test.json | 9 + .../match/infer-array-type/test.json | 36 ++ .../match/label-array/test.json | 17 + .../match/label-boolean/test.json | 25 ++ .../match/label-non-integer/test.json | 11 + .../match/label-null/test.json | 12 + .../match/label-number/test.json | 30 ++ .../match/label-object/test.json | 11 + .../match/label-overflow/test.json | 14 + .../label-string-invalid-identifier/test.json | 32 ++ .../match/label-string/test.json | 32 ++ .../match/mismatch-input/test.json | 11 + .../match/mismatch-label-1/test.json | 21 + .../match/mismatch-label-2/test.json | 11 + .../match/mismatch-output/test.json | 11 + .../match/mixed-type/test.json | 27 ++ .../match/multi-value/test.json | 42 ++ .../match/unreachable-branch-1/test.json | 17 + .../match/unreachable-branch-2/test.json | 17 + .../expression-tests/max/arity-0/test.json | 14 + .../expression-tests/max/arity-1/test.json | 14 + .../data/expression-tests/max/basic/test.json | 14 + .../expression-tests/min/arity-0/test.json | 14 + .../expression-tests/min/arity-1/test.json | 14 + .../data/expression-tests/min/basic/test.json | 14 + .../expression-tests/minus/arity-0/test.json | 15 + .../expression-tests/minus/arity-1/test.json | 14 + .../expression-tests/minus/basic/test.json | 14 + .../minus/inference-arity-2/test.json | 14 + .../data/expression-tests/mod/basic/test.json | 14 + .../data/expression-tests/not/basic/test.json | 17 + .../not_equal/mismatch/test.json | 11 + .../not_equal/number/test.json | 18 + .../not_equal/string/test.json | 18 + .../not_equal/value/test.json | 21 + .../number-format/currency/test.json | 31 ++ .../number-format/default/test.json | 21 + .../number-format/precision/test.json | 33 ++ .../expression-tests/number/basic/test.json | 28 ++ .../number/default-value/test.json | 19 + .../expression-tests/object/basic/test.json | 32 ++ .../object/default-value/test.json | 26 ++ .../object/implicit/test.json | 22 ++ .../expression-tests/parse/empty/test.json | 14 + .../parse/non-array/test.json | 14 + .../parse/non-string/test.json | 14 + .../parse/unknown-expression/test.json | 14 + .../data/expression-tests/pi/basic/test.json | 14 + .../expression-tests/plus/arity-0/test.json | 14 + .../expression-tests/plus/arity-1/test.json | 14 + .../expression-tests/plus/basic/test.json | 14 + .../data/expression-tests/pow/basic/test.json | 14 + .../properties/basic/test.json | 14 + .../resolved-locale/basic/test.json | 34 ++ .../expression-tests/result_item.html.tmpl | 16 + .../data/expression-tests/rgb/basic/test.json | 14 + .../expression-tests/rgba/basic/test.json | 14 + .../rgba/out-of-bounds/test.json | 44 +++ .../expression-tests/round/basic/test.json | 23 ++ .../data/expression-tests/sin/basic/test.json | 14 + .../slice/array-one-index/test.json | 19 + .../slice/array-two-indexes/test.json | 31 ++ .../slice/invalid-inputs/test.json | 40 ++ .../slice/string-one-index/test.json | 19 + .../slice/string-two-indexes/test.json | 20 + .../expression-tests/sqrt/basic/test.json | 14 + .../expression-tests/step/basic/test.json | 27 ++ .../step/duplicate_stops/test.json | 15 + .../expression-tests/string/basic/test.json | 28 ++ .../string/default-value/test.json | 19 + .../data/expression-tests/tan/basic/test.json | 14 + .../expression-tests/times/arity-0/test.json | 14 + .../expression-tests/times/arity-1/test.json | 14 + .../expression-tests/times/basic/test.json | 14 + .../to-boolean/2-ary/test.json | 10 + .../to-boolean/basic/test.json | 23 ++ .../expression-tests/to-color/2-ary/test.json | 30 ++ .../expression-tests/to-color/basic/test.json | 30 ++ .../expression-tests/to-color/color/test.json | 18 + .../to-number/2-ary/test.json | 34 ++ .../to-number/basic/test.json | 30 ++ .../expression-tests/to-rgba/alpha/test.json | 14 + .../expression-tests/to-rgba/basic/test.json | 19 + .../expression-tests/to-rgba/zero/test.json | 14 + .../to-string/2-ary/test.json | 10 + .../to-string/basic/test.json | 21 + .../to-string/color/test.json | 14 + .../to-string/implicit/test.json | 24 ++ .../typecheck/array-invalid-item/test.json | 22 ++ .../typecheck/array-item-subtyping/test.json | 19 + .../test.json | 22 ++ .../array-length-subtyping/test.json | 20 + .../typecheck/array-wrong-length/test.json | 22 ++ .../expression-tests/typeof/basic/test.json | 34 ++ .../expression-tests/upcase/basic/test.json | 14 + .../within/invalid-geojson/test.json | 52 +++ .../within/line-within-polygon/test.json | 44 +++ .../within/non-supported/test.json | 32 ++ .../within/point-within-polygon/test.json | 44 +++ .../expression-tests/zoom/basic/test.json | 14 + .../zoom/invalid-nested-1/test.json | 15 + .../zoom/invalid-nested-2/test.json | 23 ++ .../zoom/invalid-nested-3/test.json | 20 + .../zoom/invalid-nested-4/test.json | 19 + .../zoom/invalid-nested-5/test.json | 20 + .../zoom/invalid-no-curve/test.json | 15 + .../zoom/nested-coalesce/test.json | 20 + .../zoom/nested-let/test.json | 26 ++ 343 files changed, 8922 insertions(+), 2 deletions(-) create mode 100644 shared/test/TestExpressions.cpp create mode 100644 shared/test/data/expression-tests/abs/basic/test.json create mode 100644 shared/test/data/expression-tests/acos/basic/test.json create mode 100644 shared/test/data/expression-tests/all/arity-0/test.json create mode 100644 shared/test/data/expression-tests/all/arity-1/test.json create mode 100644 shared/test/data/expression-tests/all/basic/test.json create mode 100644 shared/test/data/expression-tests/all/short-circuiting/test.json create mode 100644 shared/test/data/expression-tests/any/arity-0/test.json create mode 100644 shared/test/data/expression-tests/any/arity-1/test.json create mode 100644 shared/test/data/expression-tests/any/basic/test.json create mode 100644 shared/test/data/expression-tests/any/short-circuiting/test.json create mode 100644 shared/test/data/expression-tests/array/basic/test.json create mode 100644 shared/test/data/expression-tests/array/default-value/test.json create mode 100644 shared/test/data/expression-tests/array/implicit-1/test.json create mode 100644 shared/test/data/expression-tests/array/implicit-2/test.json create mode 100644 shared/test/data/expression-tests/array/implicit-3/test.json create mode 100644 shared/test/data/expression-tests/array/item-type-and-length/test.json create mode 100644 shared/test/data/expression-tests/array/item-type/test.json create mode 100644 shared/test/data/expression-tests/asin/basic/test.json create mode 100644 shared/test/data/expression-tests/at/basic/test.json create mode 100644 shared/test/data/expression-tests/at/infer-array-type/test.json create mode 100644 shared/test/data/expression-tests/atan/basic/test.json create mode 100644 shared/test/data/expression-tests/boolean/basic/test.json create mode 100644 shared/test/data/expression-tests/boolean/default-value/test.json create mode 100644 shared/test/data/expression-tests/case/basic/test.json create mode 100644 shared/test/data/expression-tests/case/infer-array-type/test.json create mode 100644 shared/test/data/expression-tests/case/precedence/test.json create mode 100644 shared/test/data/expression-tests/ceil/basic/test.json create mode 100644 shared/test/data/expression-tests/coalesce/argument-type-mismatch/test.json create mode 100644 shared/test/data/expression-tests/coalesce/basic/test.json create mode 100644 shared/test/data/expression-tests/coalesce/error/test.json create mode 100644 shared/test/data/expression-tests/coalesce/infer-array-type/test.json create mode 100644 shared/test/data/expression-tests/coalesce/inference/test.json create mode 100644 shared/test/data/expression-tests/coalesce/null/test.json create mode 100644 shared/test/data/expression-tests/collator/accent-equals-de/test.json create mode 100644 shared/test/data/expression-tests/collator/accent-lt-en/test.json create mode 100644 shared/test/data/expression-tests/collator/accent-not-equals-en/test.json create mode 100644 shared/test/data/expression-tests/collator/base-default-locale/test.json create mode 100644 shared/test/data/expression-tests/collator/base-equals-en/test.json create mode 100644 shared/test/data/expression-tests/collator/base-gt-en/test.json create mode 100644 shared/test/data/expression-tests/collator/case-lteq-en/test.json create mode 100644 shared/test/data/expression-tests/collator/case-not-equals-en/test.json create mode 100644 shared/test/data/expression-tests/collator/case-omitted-en/test.json create mode 100644 shared/test/data/expression-tests/collator/comparison-number-error/test.json create mode 100644 shared/test/data/expression-tests/collator/diacritic-omitted-en/test.json create mode 100644 shared/test/data/expression-tests/collator/equals-non-string-error/test.json create mode 100644 shared/test/data/expression-tests/collator/non-object-error/test.json create mode 100644 shared/test/data/expression-tests/collator/variant-equals-en/test.json create mode 100644 shared/test/data/expression-tests/collator/variant-gteq-en/test.json create mode 100644 shared/test/data/expression-tests/concat/arity-0/test.json create mode 100644 shared/test/data/expression-tests/concat/arity-1/test.json create mode 100644 shared/test/data/expression-tests/concat/basic/test.json create mode 100644 shared/test/data/expression-tests/concat/coercion/test.json create mode 100644 shared/test/data/expression-tests/constant-folding/evaluation-error/test.json create mode 100644 shared/test/data/expression-tests/constant-folding/to-color-inferred/test.json create mode 100644 shared/test/data/expression-tests/constant-folding/to-color/test.json create mode 100644 shared/test/data/expression-tests/constant-folding/var/test.json create mode 100644 shared/test/data/expression-tests/cos/basic/test.json create mode 100644 shared/test/data/expression-tests/divide/basic/test.json create mode 100644 shared/test/data/expression-tests/downcase/basic/test.json create mode 100644 shared/test/data/expression-tests/e/basic/test.json create mode 100644 shared/test/data/expression-tests/equal/array/test.json create mode 100644 shared/test/data/expression-tests/equal/collator-value/test.json create mode 100644 shared/test/data/expression-tests/equal/color/test.json create mode 100644 shared/test/data/expression-tests/equal/mismatch/test.json create mode 100644 shared/test/data/expression-tests/equal/null-lhs/test.json create mode 100644 shared/test/data/expression-tests/equal/null-rhs/test.json create mode 100644 shared/test/data/expression-tests/equal/number/test.json create mode 100644 shared/test/data/expression-tests/equal/object/test.json create mode 100644 shared/test/data/expression-tests/equal/string/test.json create mode 100644 shared/test/data/expression-tests/equal/value/test.json create mode 100644 shared/test/data/expression-tests/floor/basic/test.json create mode 100644 shared/test/data/expression-tests/format/basic/test.json create mode 100644 shared/test/data/expression-tests/format/coercion/test.json create mode 100644 shared/test/data/expression-tests/format/data-driven-font/test.json create mode 100644 shared/test/data/expression-tests/format/data-driven-scale/test.json create mode 100644 shared/test/data/expression-tests/format/image-sections/test.json create mode 100644 shared/test/data/expression-tests/format/implicit-assert/test.json create mode 100644 shared/test/data/expression-tests/format/implicit-coerce/test.json create mode 100644 shared/test/data/expression-tests/format/implicit-omit/test.json create mode 100644 shared/test/data/expression-tests/format/implicit/test.json create mode 100644 shared/test/data/expression-tests/format/to-string/test.json create mode 100644 shared/test/data/expression-tests/geometry-type/basic/test.json create mode 100644 shared/test/data/expression-tests/get/basic/test.json create mode 100644 shared/test/data/expression-tests/get/from-literal--missing/test.json create mode 100644 shared/test/data/expression-tests/get/from-literal/test.json create mode 100644 shared/test/data/expression-tests/get/from-object-property/test.json create mode 100644 shared/test/data/expression-tests/greater/boolean/test.json create mode 100644 shared/test/data/expression-tests/greater/mismatch/test.json create mode 100644 shared/test/data/expression-tests/greater/null/test.json create mode 100644 shared/test/data/expression-tests/greater/number/test.json create mode 100644 shared/test/data/expression-tests/greater/string-and-value/test.json create mode 100644 shared/test/data/expression-tests/greater/string/test.json create mode 100644 shared/test/data/expression-tests/greater/value/test.json create mode 100644 shared/test/data/expression-tests/greater_or_equal/boolean/test.json create mode 100644 shared/test/data/expression-tests/greater_or_equal/mismatch/test.json create mode 100644 shared/test/data/expression-tests/greater_or_equal/null/test.json create mode 100644 shared/test/data/expression-tests/greater_or_equal/number/test.json create mode 100644 shared/test/data/expression-tests/greater_or_equal/string-and-value/test.json create mode 100644 shared/test/data/expression-tests/greater_or_equal/string/test.json create mode 100644 shared/test/data/expression-tests/greater_or_equal/value/test.json create mode 100644 shared/test/data/expression-tests/has/basic/test.json create mode 100644 shared/test/data/expression-tests/heatmap-density/basic/test.json create mode 100644 shared/test/data/expression-tests/id/basic/test.json create mode 100644 shared/test/data/expression-tests/image/basic/test.json create mode 100644 shared/test/data/expression-tests/image/coalesce/test.json create mode 100644 shared/test/data/expression-tests/image/compound/test.json create mode 100644 shared/test/data/expression-tests/image/implicit-assert/test.json create mode 100644 shared/test/data/expression-tests/in/assert-array/test.json create mode 100644 shared/test/data/expression-tests/in/assert-string/test.json create mode 100644 shared/test/data/expression-tests/in/basic-array/test.json create mode 100644 shared/test/data/expression-tests/in/basic-string/test.json create mode 100644 shared/test/data/expression-tests/in/invalid-haystack/test.json create mode 100644 shared/test/data/expression-tests/in/invalid-needle/test.json create mode 100644 shared/test/data/expression-tests/index-of/assert-array/test.json create mode 100644 shared/test/data/expression-tests/index-of/assert-string/test.json create mode 100644 shared/test/data/expression-tests/index-of/basic-array/test.json create mode 100644 shared/test/data/expression-tests/index-of/basic-string/test.json create mode 100644 shared/test/data/expression-tests/index-of/invalid-haystack/test.json create mode 100644 shared/test/data/expression-tests/index-of/invalid-needle/test.json create mode 100644 shared/test/data/expression-tests/index-of/with-from-index/test.json create mode 100644 shared/test/data/expression-tests/interpolate-hcl/linear/test.json create mode 100644 shared/test/data/expression-tests/interpolate-lab/linear/test.json create mode 100644 shared/test/data/expression-tests/interpolate/cubic-bezier-3-args/test.json create mode 100644 shared/test/data/expression-tests/interpolate/cubic-bezier-5-args/test.json create mode 100644 shared/test/data/expression-tests/interpolate/cubic-bezier-invalid-control-point/test.json create mode 100644 shared/test/data/expression-tests/interpolate/cubic-bezier/test.json create mode 100644 shared/test/data/expression-tests/interpolate/duplicate_stops/test.json create mode 100644 shared/test/data/expression-tests/interpolate/exponential-number-array/test.json create mode 100644 shared/test/data/expression-tests/interpolate/exponential-single-stop/test.json create mode 100644 shared/test/data/expression-tests/interpolate/exponential-string-array/test.json create mode 100644 shared/test/data/expression-tests/interpolate/exponential-uninterpolatable-numeric-array/test.json create mode 100644 shared/test/data/expression-tests/interpolate/exponential/test.json create mode 100644 shared/test/data/expression-tests/interpolate/infer-array-type/test.json create mode 100644 shared/test/data/expression-tests/interpolate/linear-color/test.json create mode 100644 shared/test/data/expression-tests/interpolate/linear-many-stops/test.json create mode 100644 shared/test/data/expression-tests/interpolate/linear/test.json create mode 100644 shared/test/data/expression-tests/is-supported-script/default/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/array-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/array/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/boolean-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/boolean/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/color-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/color/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/number-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/number/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/string-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/string/test.json create mode 100644 shared/test/data/expression-tests/legacy/categorical/tokens/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/array-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/array/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/base/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/color-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/color-hcl/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/color-lab/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/color/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/composite-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/composite/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/duplicate-stops/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/implicit/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/number-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/exponential/number/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/array-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/array/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/boolean-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/boolean/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/color-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/color/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/enum-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/enum/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/number-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/number/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/string-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/identity/string/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/array-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/array/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/color-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/color/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/composite-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/composite/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/duplicate-stops/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/implicit/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/number-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/number/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/string-default/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/string/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/tokens-property/test.json create mode 100644 shared/test/data/expression-tests/legacy/interval/tokens-zoom/test.json create mode 100644 shared/test/data/expression-tests/length/array/test.json create mode 100644 shared/test/data/expression-tests/length/implicit/test.json create mode 100644 shared/test/data/expression-tests/length/invalid/test.json create mode 100644 shared/test/data/expression-tests/length/string/test.json create mode 100644 shared/test/data/expression-tests/less/boolean/test.json create mode 100644 shared/test/data/expression-tests/less/mismatch/test.json create mode 100644 shared/test/data/expression-tests/less/null/test.json create mode 100644 shared/test/data/expression-tests/less/number/test.json create mode 100644 shared/test/data/expression-tests/less/string-and-value/test.json create mode 100644 shared/test/data/expression-tests/less/string/test.json create mode 100644 shared/test/data/expression-tests/less/value/test.json create mode 100644 shared/test/data/expression-tests/less_or_equal/boolean/test.json create mode 100644 shared/test/data/expression-tests/less_or_equal/mismatch/test.json create mode 100644 shared/test/data/expression-tests/less_or_equal/null/test.json create mode 100644 shared/test/data/expression-tests/less_or_equal/number/test.json create mode 100644 shared/test/data/expression-tests/less_or_equal/string-and-value/test.json create mode 100644 shared/test/data/expression-tests/less_or_equal/string/test.json create mode 100644 shared/test/data/expression-tests/less_or_equal/value/test.json create mode 100644 shared/test/data/expression-tests/let/basic/test.json create mode 100644 shared/test/data/expression-tests/let/expected-value/test.json create mode 100644 shared/test/data/expression-tests/let/invalid-name/test.json create mode 100644 shared/test/data/expression-tests/let/nested/test.json create mode 100644 shared/test/data/expression-tests/let/property-function/test.json create mode 100644 shared/test/data/expression-tests/let/shadow/test.json create mode 100644 shared/test/data/expression-tests/let/unbound/test.json create mode 100644 shared/test/data/expression-tests/let/zoom/test.json create mode 100644 shared/test/data/expression-tests/literal/boolean-array/test.json create mode 100644 shared/test/data/expression-tests/literal/empty/test.json create mode 100644 shared/test/data/expression-tests/literal/infer-empty-array-type/test.json create mode 100644 shared/test/data/expression-tests/literal/mixed-primitive-array/test.json create mode 100644 shared/test/data/expression-tests/literal/multiple-args/test.json create mode 100644 shared/test/data/expression-tests/literal/nested-array/test.json create mode 100644 shared/test/data/expression-tests/literal/number-array/test.json create mode 100644 shared/test/data/expression-tests/literal/object/test.json create mode 100644 shared/test/data/expression-tests/literal/string-array/test.json create mode 100644 shared/test/data/expression-tests/literal/string/test.json create mode 100644 shared/test/data/expression-tests/literal/u2028u2029/test.json create mode 100644 shared/test/data/expression-tests/ln/basic/test.json create mode 100644 shared/test/data/expression-tests/ln2/basic/test.json create mode 100644 shared/test/data/expression-tests/log10/basic/test.json create mode 100644 shared/test/data/expression-tests/log2/basic/test.json create mode 100644 shared/test/data/expression-tests/match/arity-0/test.json create mode 100644 shared/test/data/expression-tests/match/arity-1/test.json create mode 100644 shared/test/data/expression-tests/match/arity-2/test.json create mode 100644 shared/test/data/expression-tests/match/arity-3/test.json create mode 100644 shared/test/data/expression-tests/match/basic/test.json create mode 100644 shared/test/data/expression-tests/match/empty-case/test.json create mode 100644 shared/test/data/expression-tests/match/infer-array-type/test.json create mode 100644 shared/test/data/expression-tests/match/label-array/test.json create mode 100644 shared/test/data/expression-tests/match/label-boolean/test.json create mode 100644 shared/test/data/expression-tests/match/label-non-integer/test.json create mode 100644 shared/test/data/expression-tests/match/label-null/test.json create mode 100644 shared/test/data/expression-tests/match/label-number/test.json create mode 100644 shared/test/data/expression-tests/match/label-object/test.json create mode 100644 shared/test/data/expression-tests/match/label-overflow/test.json create mode 100644 shared/test/data/expression-tests/match/label-string-invalid-identifier/test.json create mode 100644 shared/test/data/expression-tests/match/label-string/test.json create mode 100644 shared/test/data/expression-tests/match/mismatch-input/test.json create mode 100644 shared/test/data/expression-tests/match/mismatch-label-1/test.json create mode 100644 shared/test/data/expression-tests/match/mismatch-label-2/test.json create mode 100644 shared/test/data/expression-tests/match/mismatch-output/test.json create mode 100644 shared/test/data/expression-tests/match/mixed-type/test.json create mode 100644 shared/test/data/expression-tests/match/multi-value/test.json create mode 100644 shared/test/data/expression-tests/match/unreachable-branch-1/test.json create mode 100644 shared/test/data/expression-tests/match/unreachable-branch-2/test.json create mode 100644 shared/test/data/expression-tests/max/arity-0/test.json create mode 100644 shared/test/data/expression-tests/max/arity-1/test.json create mode 100644 shared/test/data/expression-tests/max/basic/test.json create mode 100644 shared/test/data/expression-tests/min/arity-0/test.json create mode 100644 shared/test/data/expression-tests/min/arity-1/test.json create mode 100644 shared/test/data/expression-tests/min/basic/test.json create mode 100644 shared/test/data/expression-tests/minus/arity-0/test.json create mode 100644 shared/test/data/expression-tests/minus/arity-1/test.json create mode 100644 shared/test/data/expression-tests/minus/basic/test.json create mode 100644 shared/test/data/expression-tests/minus/inference-arity-2/test.json create mode 100644 shared/test/data/expression-tests/mod/basic/test.json create mode 100644 shared/test/data/expression-tests/not/basic/test.json create mode 100644 shared/test/data/expression-tests/not_equal/mismatch/test.json create mode 100644 shared/test/data/expression-tests/not_equal/number/test.json create mode 100644 shared/test/data/expression-tests/not_equal/string/test.json create mode 100644 shared/test/data/expression-tests/not_equal/value/test.json create mode 100644 shared/test/data/expression-tests/number-format/currency/test.json create mode 100644 shared/test/data/expression-tests/number-format/default/test.json create mode 100644 shared/test/data/expression-tests/number-format/precision/test.json create mode 100644 shared/test/data/expression-tests/number/basic/test.json create mode 100644 shared/test/data/expression-tests/number/default-value/test.json create mode 100644 shared/test/data/expression-tests/object/basic/test.json create mode 100644 shared/test/data/expression-tests/object/default-value/test.json create mode 100644 shared/test/data/expression-tests/object/implicit/test.json create mode 100644 shared/test/data/expression-tests/parse/empty/test.json create mode 100644 shared/test/data/expression-tests/parse/non-array/test.json create mode 100644 shared/test/data/expression-tests/parse/non-string/test.json create mode 100644 shared/test/data/expression-tests/parse/unknown-expression/test.json create mode 100644 shared/test/data/expression-tests/pi/basic/test.json create mode 100644 shared/test/data/expression-tests/plus/arity-0/test.json create mode 100644 shared/test/data/expression-tests/plus/arity-1/test.json create mode 100644 shared/test/data/expression-tests/plus/basic/test.json create mode 100644 shared/test/data/expression-tests/pow/basic/test.json create mode 100644 shared/test/data/expression-tests/properties/basic/test.json create mode 100644 shared/test/data/expression-tests/resolved-locale/basic/test.json create mode 100644 shared/test/data/expression-tests/result_item.html.tmpl create mode 100644 shared/test/data/expression-tests/rgb/basic/test.json create mode 100644 shared/test/data/expression-tests/rgba/basic/test.json create mode 100644 shared/test/data/expression-tests/rgba/out-of-bounds/test.json create mode 100644 shared/test/data/expression-tests/round/basic/test.json create mode 100644 shared/test/data/expression-tests/sin/basic/test.json create mode 100644 shared/test/data/expression-tests/slice/array-one-index/test.json create mode 100644 shared/test/data/expression-tests/slice/array-two-indexes/test.json create mode 100644 shared/test/data/expression-tests/slice/invalid-inputs/test.json create mode 100644 shared/test/data/expression-tests/slice/string-one-index/test.json create mode 100644 shared/test/data/expression-tests/slice/string-two-indexes/test.json create mode 100644 shared/test/data/expression-tests/sqrt/basic/test.json create mode 100644 shared/test/data/expression-tests/step/basic/test.json create mode 100644 shared/test/data/expression-tests/step/duplicate_stops/test.json create mode 100644 shared/test/data/expression-tests/string/basic/test.json create mode 100644 shared/test/data/expression-tests/string/default-value/test.json create mode 100644 shared/test/data/expression-tests/tan/basic/test.json create mode 100644 shared/test/data/expression-tests/times/arity-0/test.json create mode 100644 shared/test/data/expression-tests/times/arity-1/test.json create mode 100644 shared/test/data/expression-tests/times/basic/test.json create mode 100644 shared/test/data/expression-tests/to-boolean/2-ary/test.json create mode 100644 shared/test/data/expression-tests/to-boolean/basic/test.json create mode 100644 shared/test/data/expression-tests/to-color/2-ary/test.json create mode 100644 shared/test/data/expression-tests/to-color/basic/test.json create mode 100644 shared/test/data/expression-tests/to-color/color/test.json create mode 100644 shared/test/data/expression-tests/to-number/2-ary/test.json create mode 100644 shared/test/data/expression-tests/to-number/basic/test.json create mode 100644 shared/test/data/expression-tests/to-rgba/alpha/test.json create mode 100644 shared/test/data/expression-tests/to-rgba/basic/test.json create mode 100644 shared/test/data/expression-tests/to-rgba/zero/test.json create mode 100644 shared/test/data/expression-tests/to-string/2-ary/test.json create mode 100644 shared/test/data/expression-tests/to-string/basic/test.json create mode 100644 shared/test/data/expression-tests/to-string/color/test.json create mode 100644 shared/test/data/expression-tests/to-string/implicit/test.json create mode 100644 shared/test/data/expression-tests/typecheck/array-invalid-item/test.json create mode 100644 shared/test/data/expression-tests/typecheck/array-item-subtyping/test.json create mode 100644 shared/test/data/expression-tests/typecheck/array-length-subtyping--no-length/test.json create mode 100644 shared/test/data/expression-tests/typecheck/array-length-subtyping/test.json create mode 100644 shared/test/data/expression-tests/typecheck/array-wrong-length/test.json create mode 100644 shared/test/data/expression-tests/typeof/basic/test.json create mode 100644 shared/test/data/expression-tests/upcase/basic/test.json create mode 100644 shared/test/data/expression-tests/within/invalid-geojson/test.json create mode 100644 shared/test/data/expression-tests/within/line-within-polygon/test.json create mode 100644 shared/test/data/expression-tests/within/non-supported/test.json create mode 100644 shared/test/data/expression-tests/within/point-within-polygon/test.json create mode 100644 shared/test/data/expression-tests/zoom/basic/test.json create mode 100644 shared/test/data/expression-tests/zoom/invalid-nested-1/test.json create mode 100644 shared/test/data/expression-tests/zoom/invalid-nested-2/test.json create mode 100644 shared/test/data/expression-tests/zoom/invalid-nested-3/test.json create mode 100644 shared/test/data/expression-tests/zoom/invalid-nested-4/test.json create mode 100644 shared/test/data/expression-tests/zoom/invalid-nested-5/test.json create mode 100644 shared/test/data/expression-tests/zoom/invalid-no-curve/test.json create mode 100644 shared/test/data/expression-tests/zoom/nested-coalesce/test.json create mode 100644 shared/test/data/expression-tests/zoom/nested-let/test.json diff --git a/shared/test/CMakeLists.txt b/shared/test/CMakeLists.txt index ef5733a3d..5811c2121 100644 --- a/shared/test/CMakeLists.txt +++ b/shared/test/CMakeLists.txt @@ -14,10 +14,10 @@ add_executable(tests "TestTileSource.cpp" "TestGeometryHandler.cpp" "TestStyleParser.cpp" - "TestValueEvaluate.cpp" - "TestVectorSet.cpp" + "TestVectorSet.cpp" "TestStyleParser.cpp" "TestInternedString.cpp" + "TestExpressions.cpp" "helper/TestData.cpp" "helper/TestLocalDataProvider.h" ) diff --git a/shared/test/TestExpressions.cpp b/shared/test/TestExpressions.cpp new file mode 100644 index 000000000..32b30f984 --- /dev/null +++ b/shared/test/TestExpressions.cpp @@ -0,0 +1,373 @@ +/* + * Expression tests based on MapLibre Native expression test definitions + * + * Test definitions adapted from: + * https://github.com/maplibre/maplibre-native/tree/ecab4a390e0310a775b7de2b2b1a5a9230fd0773/metrics/integration/expression-tests + * + * Original work Copyright (c) 2014-2020 Mapbox + * Copyright (c) 2018-2021 MapTiler.com + * Copyright (c) 2021 MapLibre contributors + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Value.h" +#include "Tiled2dMapVectorStyleParser.h" +#include "json.h" +#include "helper/TestData.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using json = nlohmann::json; + +namespace { + // Test cases to ignore for now - add test names here to skip them + static const std::unordered_set IGNORED_TESTS = { + "abs/basic", + "acos/basic", + "asin/basic", + "atan/basic", + "ceil/basic", + "cos/basic", + "divide/basic", + "floor/basic", + "ln/basic", + "ln2/basic", + "log10/basic", + "log2/basic", + "max/arity-0", + "max/arity-1", + "max/basic", + "min/arity-0", + "min/arity-1", + "min/basic", + "minus/arity-0", + "minus/arity-1", + "minus/basic", + "minus/inference-arity-2", + "mod/basic", + "pi/basic", + "plus/arity-0", + "plus/arity-1", + "plus/basic", + "pow/basic", + "round/basic", + "sin/basic", + "sqrt/basic", + "tan/basic", + "times/arity-0", + "times/arity-1", + "times/basic", + "e/basic", + "array/basic", + "array/default-value", + "array/implicit-1", + "array/implicit-2", + "array/implicit-3", + "array/item-type-and-length", + "array/item-type", + "at/basic", + "at/infer-array-type", + "case/basic", + "case/infer-array-type", + "case/precedence", + "coalesce/argument-type-mismatch", + "coalesce/basic", + "coalesce/error", + "coalesce/infer-array-type", + "coalesce/inference", + "coalesce/null", + "interpolate/linear", + "interpolate/exponential", + "step/basic", + "step/duplicate_stops", + "match/basic", + "let/basic", + "literal/string", + "literal/object", + "geometry-type/basic", + "id/basic", + "properties/basic", + "zoom/basic", + "heatmap-density/basic", + "downcase/basic", + "upcase/basic", + "slice/string-one-index", + "slice/string-two-indexes", + "index-of/basic-string", + "rgb/basic", + "rgba/basic", + "to-rgba/basic", + "to-color/basic", + "format/basic", + "number-format/default", + "typeof/basic", + "legacy", + "collator/accent-equals-de" , + "collator/base-gt-en", + "collator/diacritic-omitted-en", + "collator/accent-lt-en" , + "collator/case-lteq-en" , + "collator/equals-non-string-error", + "collator/accent-not-equals-en" , + "collator/case-not-equals-en" , + "collator/non-object-error", + "collator/base-default-locale" , + "collator/case-omitted-en" , + "collator/variant-equals-en", + "collator/base-equals-en" , + "collator/comparison-number-error", + "collator/variant-gteq-en", + "within/invalid-geojson", + "within/non-supported", + "within/line-within-polygon", + "within/point-within-polygon" + }; + + // Helper function to recursively find all test.json files + std::vector findAllTestFiles() { + std::vector testFiles; + std::filesystem::path expressionTestsDir = TestData::resolve("expression-tests"); + + if (!std::filesystem::exists(expressionTestsDir)) { + return testFiles; + } + + for (const auto& entry : std::filesystem::recursive_directory_iterator(expressionTestsDir)) { + if (entry.is_regular_file() && entry.path().filename() == "test.json") { + testFiles.push_back(entry.path()); + } + } + + return testFiles; + } + + // Helper function to load test JSON file + json loadTestFile(const std::filesystem::path& filePath) { + std::ifstream file(filePath); + if (!file.is_open()) { + throw std::runtime_error("Could not open test file: " + filePath.string()); + } + + json testData; + file >> testData; + return testData; + } + + // Helper function to create evaluation context from test input + // Returns both the context and the feature context to keep it alive + std::pair> createContextFromInput(const json& input, StringInterner& stringTable) { + double zoom = 0.0; + int32_t zoomLevel = 0; + std::shared_ptr featureContext = nullptr; + + if (input.size() >= 1 && input[0].is_object()) { + // First element is zoom context + if (input[0].contains("zoom")) { + zoom = input[0]["zoom"]; + zoomLevel = static_cast(zoom); + } + } + + if (input.size() >= 2 && input[1].is_object()) { + // Second element is feature context + const auto& feature = input[1]; + FeatureContext::mapType properties; + + if (feature.contains("properties") && feature["properties"].is_object()) { + for (const auto& [key, value] : feature["properties"].items()) { + auto keyId = stringTable.add(key); + + if (value.is_string()) { + properties.emplace_back(keyId, value.get()); + } else if (value.is_number_integer()) { + properties.emplace_back(keyId, value.get()); + } else if (value.is_number_float()) { + properties.emplace_back(keyId, value.get()); + } else if (value.is_boolean()) { + properties.emplace_back(keyId, value.get()); + } else if (value.is_null()) { + properties.emplace_back(keyId, std::monostate()); + } + } + } + + featureContext = std::make_shared(vtzero::GeomType::POINT, properties, 0); + } else { + featureContext = std::make_shared(); + } + + EvaluationContext context(zoom, zoomLevel, featureContext, nullptr); + return std::make_pair(context, featureContext); + } + + // Helper function to compare expected outputs with actual results + bool compareValue(const ValueVariant& actual, const json& expected) { + if (expected.is_null()) { + return std::holds_alternative(actual); + } else if (expected.is_string()) { + return std::holds_alternative(actual) && + std::get(actual) == expected.get(); + } else if (expected.is_number_integer()) { + if (std::holds_alternative(actual)) { + return std::get(actual) == expected.get(); + } else if (std::holds_alternative(actual)) { + return std::abs(std::get(actual) - expected.get()) < 1e-10; + } + } else if (expected.is_number_float()) { + if (std::holds_alternative(actual)) { + return std::abs(std::get(actual) - expected.get()) < 1e-10; + } + } else if (expected.is_boolean()) { + return std::holds_alternative(actual) && + std::get(actual) == expected.get(); + } + + return false; + } + + // Get test name from file path + std::string getTestName(const std::filesystem::path& filePath) { + std::filesystem::path expressionTestsDir = TestData::resolve("expression-tests"); + auto relativePath = std::filesystem::relative(filePath.parent_path(), expressionTestsDir); + return relativePath.string(); + } +} + +TEST_CASE("Expression Tests - Dynamic Test Runner", "[expressions]") { + auto testFiles = findAllTestFiles(); + + REQUIRE(!testFiles.empty()); + + // Group results by test outcome + std::map> results; + results["passed"] = {}; + results["failed"] = {}; + results["skipped"] = {}; + + StringInterner stringTable = ValueKeys::newStringInterner(); + Tiled2dMapVectorStyleParser parser(stringTable); + + for (const auto& testFile : testFiles) { + try { + auto testData = loadTestFile(testFile); + std::string testName = getTestName(testFile); + + // Check if this test should be ignored + bool shouldIgnore = false; + for (const auto& ignoredTest : IGNORED_TESTS) { + if (testName.find(ignoredTest) != std::string::npos) { + shouldIgnore = true; + break; + } + } + + if (shouldIgnore) { + results["skipped"].push_back(testName + " (ignored)"); + continue; + } + + DYNAMIC_SECTION("Test: " + testName) { + try { + // Use the Tiled2dMapVectorStyleParser to parse the expression + auto expression = parser.parseValue(testData["expression"]); + + if (!expression) { + results["skipped"].push_back(testName + " (expression not parseable)"); + continue; + } + + const auto& inputs = testData["inputs"]; + const auto& expectedOutputs = testData["expected"]["outputs"]; + + bool allPassed = true; + std::string errorMessage; + + for (size_t i = 0; i < inputs.size() && i < expectedOutputs.size(); ++i) { + auto [context, featureContext] = createContextFromInput(inputs[i], stringTable); + + try { + auto result = expression->evaluate(context); + + if (!compareValue(result, expectedOutputs[i])) { + allPassed = false; + errorMessage = "output mismatch at input " + std::to_string(i); + break; + } + } catch (const std::exception& e) { + allPassed = false; + errorMessage = "evaluation exception: " + std::string(e.what()); + break; + } + } + + if (allPassed) { + results["passed"].push_back(testName); + REQUIRE(true); // Test passed + } else { + results["failed"].push_back(testName + " (" + errorMessage + ")"); + REQUIRE(false); // Test failed + } + } catch (const std::exception& e) { + results["failed"].push_back(testName + " (parse exception: " + e.what() + ")"); + REQUIRE(false); + } + } + } catch (const std::exception& e) { + std::string testName = getTestName(testFile); + results["failed"].push_back(testName + " (file error: " + e.what() + ")"); + } + } + + // Print summary only once at the very end + static bool summaryPrinted = false; + if (!summaryPrinted) { + summaryPrinted = true; + + std::cout << "\n=== Expression Test Summary ===" << std::endl; + std::cout << "Total tests found: " << testFiles.size() << std::endl; + std::cout << "Passed: " << results["passed"].size() << std::endl; + std::cout << "Failed: " << results["failed"].size() << std::endl; + std::cout << "Skipped: " << results["skipped"].size() << std::endl; + + std::cout << "\nFailed results:" << std::endl; + for (size_t i = 0; i < results["failed"].size(); ++i) { + std::cout << " - " << results["failed"][i] << std::endl; + } + + + std::cout << "\nPassed results:" << std::endl; + for (size_t i = 0; i < results["passed"].size(); ++i) { + std::cout << " - " << results["passed"][i] << std::endl; + } + } +} \ No newline at end of file diff --git a/shared/test/data/expression-tests/abs/basic/test.json b/shared/test/data/expression-tests/abs/basic/test.json new file mode 100644 index 000000000..4d068dbfc --- /dev/null +++ b/shared/test/data/expression-tests/abs/basic/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["abs", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": -2}}], + [{}, {"properties": {"x": 2}}], + [{}, {"properties": {"x": -1.1}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [2, 2, 1.1], + "serialized": ["abs", ["number", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/acos/basic/test.json b/shared/test/data/expression-tests/acos/basic/test.json new file mode 100644 index 000000000..95b6a304f --- /dev/null +++ b/shared/test/data/expression-tests/acos/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["acos", 0.5], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1.04719], + "serialized": 1.0471975511965979 + } +} diff --git a/shared/test/data/expression-tests/all/arity-0/test.json b/shared/test/data/expression-tests/all/arity-0/test.json new file mode 100644 index 000000000..b7c4d2917 --- /dev/null +++ b/shared/test/data/expression-tests/all/arity-0/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["all"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true], + "serialized": true + } +} diff --git a/shared/test/data/expression-tests/all/arity-1/test.json b/shared/test/data/expression-tests/all/arity-1/test.json new file mode 100644 index 000000000..a56dcf856 --- /dev/null +++ b/shared/test/data/expression-tests/all/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["all", false], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false], + "serialized": false + } +} diff --git a/shared/test/data/expression-tests/all/basic/test.json b/shared/test/data/expression-tests/all/basic/test.json new file mode 100644 index 000000000..9c1e31f4e --- /dev/null +++ b/shared/test/data/expression-tests/all/basic/test.json @@ -0,0 +1,17 @@ +{ + "expression": ["all", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": true, "y": false}}], + [{}, {"properties": {"x": true, "y": true}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true], + "serialized": ["all", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/all/short-circuiting/test.json b/shared/test/data/expression-tests/all/short-circuiting/test.json new file mode 100644 index 000000000..572836742 --- /dev/null +++ b/shared/test/data/expression-tests/all/short-circuiting/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["all", false, ["error", "unreachable"]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false], + "serialized": ["all", false, ["error", "unreachable"]] + } +} diff --git a/shared/test/data/expression-tests/any/arity-0/test.json b/shared/test/data/expression-tests/any/arity-0/test.json new file mode 100644 index 000000000..3e91e1456 --- /dev/null +++ b/shared/test/data/expression-tests/any/arity-0/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["any"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false], + "serialized": false + } +} diff --git a/shared/test/data/expression-tests/any/arity-1/test.json b/shared/test/data/expression-tests/any/arity-1/test.json new file mode 100644 index 000000000..e9d2a0e0c --- /dev/null +++ b/shared/test/data/expression-tests/any/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["any", false], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false], + "serialized": false + } +} diff --git a/shared/test/data/expression-tests/any/basic/test.json b/shared/test/data/expression-tests/any/basic/test.json new file mode 100644 index 000000000..2e9397fa6 --- /dev/null +++ b/shared/test/data/expression-tests/any/basic/test.json @@ -0,0 +1,19 @@ +{ + "expression": ["any", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": true, "y": true}}], + [{}, {"properties": {"x": true, "y": false}}], + [{}, {"properties": {"x": false, "y": true}}], + [{}, {"properties": {"x": false, "y": false}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, true, false], + "serialized": ["any", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/any/short-circuiting/test.json b/shared/test/data/expression-tests/any/short-circuiting/test.json new file mode 100644 index 000000000..553d72849 --- /dev/null +++ b/shared/test/data/expression-tests/any/short-circuiting/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["any", true, ["error", "unreachable"]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true], + "serialized": ["any", true, ["error", "unreachable"]] + } +} diff --git a/shared/test/data/expression-tests/array/basic/test.json b/shared/test/data/expression-tests/array/basic/test.json new file mode 100644 index 000000000..b9ceb78b9 --- /dev/null +++ b/shared/test/data/expression-tests/array/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["array", ["literal", [1, 2, 3]]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[1, 2, 3]], + "serialized": ["literal", [1, 2, 3]] + } +} diff --git a/shared/test/data/expression-tests/array/default-value/test.json b/shared/test/data/expression-tests/array/default-value/test.json new file mode 100644 index 000000000..40a849028 --- /dev/null +++ b/shared/test/data/expression-tests/array/default-value/test.json @@ -0,0 +1,22 @@ +{ + "expression": ["array", "number", null, ["get", "x"], ["literal", [0]]], + "inputs": [ + [{}, {}], + [{}, {"properties": {"x": []}}], + [{}, {"properties": {"x": ["1"]}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + [0], + [], + [0] + ], + "serialized": ["array", "number", null, ["get", "x"], ["literal", [0]]] + } +} diff --git a/shared/test/data/expression-tests/array/implicit-1/test.json b/shared/test/data/expression-tests/array/implicit-1/test.json new file mode 100644 index 000000000..d55f44e29 --- /dev/null +++ b/shared/test/data/expression-tests/array/implicit-1/test.json @@ -0,0 +1,20 @@ +{ + "expression": ["at", 0, ["get", "array"]], + "inputs": [ + [{}, {"properties": {"array": [0, 1, 2]}}], + [{}, {"properties": {"array": "not"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": [ + 0, + {"error": "Expected value to be of type array, but found string instead."} + ], + "serialized": ["at", 0, ["array", ["get", "array"]]] + } +} diff --git a/shared/test/data/expression-tests/array/implicit-2/test.json b/shared/test/data/expression-tests/array/implicit-2/test.json new file mode 100644 index 000000000..8c6fe029c --- /dev/null +++ b/shared/test/data/expression-tests/array/implicit-2/test.json @@ -0,0 +1,32 @@ +{ + "propertySpec": { + "type": "array", + "value": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["get", "array"], + "inputs": [ + [{}, {"properties": {"array": ["a", "b"]}}], + [{}, {"properties": {"array": [1, 2]}}], + [{}, {"properties": {"array": "not"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + ["a", "b"], + { + "error": "Expected value to be of type array, but found array instead." + }, + { + "error": "Expected value to be of type array, but found string instead." + } + ], + "serialized": ["array", "string", ["get", "array"]] + } +} diff --git a/shared/test/data/expression-tests/array/implicit-3/test.json b/shared/test/data/expression-tests/array/implicit-3/test.json new file mode 100644 index 000000000..2b095e411 --- /dev/null +++ b/shared/test/data/expression-tests/array/implicit-3/test.json @@ -0,0 +1,33 @@ +{ + "propertySpec": { + "type": "array", + "value": "number", + "length": 2, + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["get", "array"], + "inputs": [ + [{}, {"properties": {"array": [1, 2]}}], + [{}, {"properties": {"array": [1, 2, 3]}}], + [{}, {"properties": {"array": "not"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + [1, 2], + { + "error": "Expected value to be of type array, but found array instead." + }, + { + "error": "Expected value to be of type array, but found string instead." + } + ], + "serialized": ["array", "number", 2, ["get", "array"]] + } +} diff --git a/shared/test/data/expression-tests/array/item-type-and-length/test.json b/shared/test/data/expression-tests/array/item-type-and-length/test.json new file mode 100644 index 000000000..cac818e08 --- /dev/null +++ b/shared/test/data/expression-tests/array/item-type-and-length/test.json @@ -0,0 +1,26 @@ +{ + "expression": ["array", "number", 2, ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": [1, 0]}}], + [{}, {"properties": {"x": [0]}}], + [{}, {"properties": {"x": [1, 2, 3]}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + [1, 0], + { + "error": "Expected value to be of type array, but found array instead." + }, + { + "error": "Expected value to be of type array, but found array instead." + } + ], + "serialized": ["array", "number", 2, ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/array/item-type/test.json b/shared/test/data/expression-tests/array/item-type/test.json new file mode 100644 index 000000000..bd3b326bb --- /dev/null +++ b/shared/test/data/expression-tests/array/item-type/test.json @@ -0,0 +1,28 @@ +{ + "expression": ["array", "string", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": ["a", "b"]}}], + [{}, {"properties": {"x": [1, 2]}}], + [{}, {"properties": {"x": [1, "b"]}}], + [{}, {"properties": {"x": []}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + ["a", "b"], + { + "error": "Expected value to be of type array, but found array instead." + }, + { + "error": "Expected value to be of type array, but found array instead." + }, + [] + ], + "serialized": ["array", "string", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/asin/basic/test.json b/shared/test/data/expression-tests/asin/basic/test.json new file mode 100644 index 000000000..1da643267 --- /dev/null +++ b/shared/test/data/expression-tests/asin/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["asin", 0.5], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0.523598], + "serialized": 0.5235987755982989 + } +} diff --git a/shared/test/data/expression-tests/at/basic/test.json b/shared/test/data/expression-tests/at/basic/test.json new file mode 100644 index 000000000..47ba77bcc --- /dev/null +++ b/shared/test/data/expression-tests/at/basic/test.json @@ -0,0 +1,30 @@ +{ + "expression": [ + "number", + ["at", ["number", ["get", "i"]], ["array", ["get", "arr"]]] + ], + "inputs": [ + [{}, {"properties": {"i": 1, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": -1, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 4, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 1.5, "arr": [9, 8, 7]}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 8, + {"error": "Array index out of bounds: -1 < 0."}, + {"error": "Array index out of bounds: 4 > 2."}, + {"error": "Array index must be an integer, but found 1.5 instead."} + ], + "serialized": [ + "number", + ["at", ["number", ["get", "i"]], ["array", ["get", "arr"]]] + ] + } +} diff --git a/shared/test/data/expression-tests/at/infer-array-type/test.json b/shared/test/data/expression-tests/at/infer-array-type/test.json new file mode 100644 index 000000000..e3e6c2ac1 --- /dev/null +++ b/shared/test/data/expression-tests/at/infer-array-type/test.json @@ -0,0 +1,20 @@ +{ + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["at", 1, ["literal", [1, 2, 3]]], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[2]", + "error": "Expected array but found array instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/atan/basic/test.json b/shared/test/data/expression-tests/atan/basic/test.json new file mode 100644 index 000000000..1789434a6 --- /dev/null +++ b/shared/test/data/expression-tests/atan/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["atan", 1], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0.785398], + "serialized": 0.7853981633974483 + } +} diff --git a/shared/test/data/expression-tests/boolean/basic/test.json b/shared/test/data/expression-tests/boolean/basic/test.json new file mode 100644 index 000000000..1bb399c31 --- /dev/null +++ b/shared/test/data/expression-tests/boolean/basic/test.json @@ -0,0 +1,42 @@ +{ + "expression": ["boolean", ["get", "x"]], + "inputs": [ + [{}, {}], + [{}, {"properties": {"x": true}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": ""}}], + [{}, {"properties": {"x": "false"}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + { + "error": "Expected value to be of type boolean, but found null instead." + }, + true, + false, + { + "error": "Expected value to be of type boolean, but found string instead." + }, + { + "error": "Expected value to be of type boolean, but found string instead." + }, + { + "error": "Expected value to be of type boolean, but found number instead." + }, + { + "error": "Expected value to be of type boolean, but found number instead." + }, + {"error": "Expected value to be of type boolean, but found null instead."} + ], + "serialized": ["boolean", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/boolean/default-value/test.json b/shared/test/data/expression-tests/boolean/default-value/test.json new file mode 100644 index 000000000..100831346 --- /dev/null +++ b/shared/test/data/expression-tests/boolean/default-value/test.json @@ -0,0 +1,23 @@ +{ + "expression": ["boolean", ["get", "x"], false], + "inputs": [ + [{}, {}], + [{}, {"properties": {"x": true}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": ""}}], + [{}, {"properties": {"x": "false"}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, false, false, false, false, false, false], + "serialized": ["boolean", ["get", "x"], false] + } +} diff --git a/shared/test/data/expression-tests/case/basic/test.json b/shared/test/data/expression-tests/case/basic/test.json new file mode 100644 index 000000000..510e4eb39 --- /dev/null +++ b/shared/test/data/expression-tests/case/basic/test.json @@ -0,0 +1,40 @@ +{ + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["case", ["get", "x"], "x", ["get", "y"], "y", "otherwise"], + "inputs": [ + [{}, {"properties": {"x": true, "y": true}}], + [{}, {"properties": {"x": true, "y": false}}], + [{}, {"properties": {"x": false, "y": true}}], + [{}, {"properties": {"x": false, "y": false}}], + [{}, {"properties": {"x": "false", "y": false}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "x", + "x", + "y", + "otherwise", + { + "error": "Expected value to be of type boolean, but found string instead." + } + ], + "serialized": [ + "case", + ["boolean", ["get", "x"]], + "x", + ["boolean", ["get", "y"]], + "y", + "otherwise" + ] + } +} diff --git a/shared/test/data/expression-tests/case/infer-array-type/test.json b/shared/test/data/expression-tests/case/infer-array-type/test.json new file mode 100644 index 000000000..9c5e3ec25 --- /dev/null +++ b/shared/test/data/expression-tests/case/infer-array-type/test.json @@ -0,0 +1,30 @@ +{ + "propertySpec": { + "type": "array", + "value": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": [ + "case", + ["boolean", ["get", "x"]], + ["literal", ["one"]], + ["literal", ["one", "two"]] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [], + "serialized": [ + "case", + ["boolean", ["get", "x"]], + ["literal", ["one"]], + ["literal", ["one", "two"]] + ] + } +} diff --git a/shared/test/data/expression-tests/case/precedence/test.json b/shared/test/data/expression-tests/case/precedence/test.json new file mode 100644 index 000000000..07e732e82 --- /dev/null +++ b/shared/test/data/expression-tests/case/precedence/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["boolean", ["all", false, ["case", true, true, true]]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false], + "serialized": false + } +} diff --git a/shared/test/data/expression-tests/ceil/basic/test.json b/shared/test/data/expression-tests/ceil/basic/test.json new file mode 100644 index 000000000..8fbee7c58 --- /dev/null +++ b/shared/test/data/expression-tests/ceil/basic/test.json @@ -0,0 +1,23 @@ +{ + "expression": ["ceil", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": -2.6}}], + [{}, {"properties": {"x": -2.5}}], + [{}, {"properties": {"x": -2.4}}], + [{}, {"properties": {"x": -2}}], + [{}, {"properties": {"x": 2.6}}], + [{}, {"properties": {"x": 2.5}}], + [{}, {"properties": {"x": 2.4}}], + [{}, {"properties": {"x": 2}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-2, -2, -2, -2, 3, 3, 3, 2], + "serialized": ["ceil", ["number", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/coalesce/argument-type-mismatch/test.json b/shared/test/data/expression-tests/coalesce/argument-type-mismatch/test.json new file mode 100644 index 000000000..b10de788b --- /dev/null +++ b/shared/test/data/expression-tests/coalesce/argument-type-mismatch/test.json @@ -0,0 +1,12 @@ +{ + "propertySpec": {"type": "string"}, + "expression": ["coalesce", ["get", "a"], 5], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[2]", "error": "Expected string but found number instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/coalesce/basic/test.json b/shared/test/data/expression-tests/coalesce/basic/test.json new file mode 100644 index 000000000..1df53771f --- /dev/null +++ b/shared/test/data/expression-tests/coalesce/basic/test.json @@ -0,0 +1,20 @@ +{ + "expression": ["coalesce", ["get", "x"], ["get", "y"], ["get", "z"], 0], + "inputs": [ + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 1, "y": 2, "z": 3}}], + [{}, {"properties": {"y": 2}}], + [{}, {"properties": {"z": 3}}], + [{}, {}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": [1, 1, 2, 3, 0], + "serialized": ["coalesce", ["get", "x"], ["get", "y"], ["get", "z"], 0] + } +} diff --git a/shared/test/data/expression-tests/coalesce/error/test.json b/shared/test/data/expression-tests/coalesce/error/test.json new file mode 100644 index 000000000..703151b20 --- /dev/null +++ b/shared/test/data/expression-tests/coalesce/error/test.json @@ -0,0 +1,36 @@ +{ + "expression": [ + "coalesce", + ["number", ["get", "x"]], + ["number", ["get", "y"]], + ["number", ["get", "z"]] + ], + "inputs": [ + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 1, "y": 2, "z": 3}}], + [{}, {"properties": {"y": 2}}], + [{}, {"properties": {"z": 3}}], + [{}, {}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 1, + 1, + {"error": "Expected value to be of type number, but found null instead."}, + {"error": "Expected value to be of type number, but found null instead."}, + {"error": "Expected value to be of type number, but found null instead."} + ], + "serialized": [ + "coalesce", + ["number", ["get", "x"]], + ["number", ["get", "y"]], + ["number", ["get", "z"]] + ] + } +} diff --git a/shared/test/data/expression-tests/coalesce/infer-array-type/test.json b/shared/test/data/expression-tests/coalesce/infer-array-type/test.json new file mode 100644 index 000000000..8661cffed --- /dev/null +++ b/shared/test/data/expression-tests/coalesce/infer-array-type/test.json @@ -0,0 +1,26 @@ +{ + "propertySpec": { + "type": "array", + "value": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": [ + "coalesce", + ["literal", ["one"]], + ["literal", ["one", "two"]], + null + ], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[3]", + "error": "Expected array but found null instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/coalesce/inference/test.json b/shared/test/data/expression-tests/coalesce/inference/test.json new file mode 100644 index 000000000..8399bb100 --- /dev/null +++ b/shared/test/data/expression-tests/coalesce/inference/test.json @@ -0,0 +1,25 @@ +{ + "propertySpec": {"type": "string"}, + "expression": ["coalesce", ["get", "a"], ["get", "b"]], + "inputs": [ + [{}, {"properties": {"a": "one"}}], + [{}, {"properties": {"b": "two"}}], + [{}, {"properties": {"b": 5}}], + [{}, {"properties": {}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "one", + "two", + "5", + "" + ], + "serialized": ["to-string", ["coalesce", ["get", "a"], ["get", "b"]]] + } +} diff --git a/shared/test/data/expression-tests/coalesce/null/test.json b/shared/test/data/expression-tests/coalesce/null/test.json new file mode 100644 index 000000000..a0ceaf778 --- /dev/null +++ b/shared/test/data/expression-tests/coalesce/null/test.json @@ -0,0 +1,15 @@ +{ + "expectExpressionType": null, + "expression": ["coalesce", ["get", "z"], 0], + "inputs": [[{}, {"properties": {"z": 1}}], [{}, {"properties": {"z": null}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": [1, 0], + "serialized": ["coalesce", ["get", "z"], 0] + } +} diff --git a/shared/test/data/expression-tests/collator/accent-equals-de/test.json b/shared/test/data/expression-tests/collator/accent-equals-de/test.json new file mode 100644 index 000000000..e69ebb894 --- /dev/null +++ b/shared/test/data/expression-tests/collator/accent-equals-de/test.json @@ -0,0 +1,67 @@ +{ + "expression": [ + "case", + [ + "==", + [ + "resolved-locale", + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "de"} + ] + ], + "de" + ], + [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "de"} + ] + ], + ["case", ["==", ["get", "rhs"], "ue"], true, false] + ], + "inputs": [ + [{}, {"properties": {"lhs": "ü", "rhs": "ue"}}], + [{}, {"properties": {"lhs": "ü", "rhs": "u"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false], + "serialized": [ + "case", + [ + "==", + [ + "resolved-locale", + [ + "collator", + { + "case-sensitive": true, + "diacritic-sensitive": false, + "locale": "de" + } + ] + ], + "de" + ], + [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "de"} + ] + ], + ["case", ["==", ["get", "rhs"], "ue"], true, false] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/accent-lt-en/test.json b/shared/test/data/expression-tests/collator/accent-lt-en/test.json new file mode 100644 index 000000000..f2932b726 --- /dev/null +++ b/shared/test/data/expression-tests/collator/accent-lt-en/test.json @@ -0,0 +1,34 @@ +{ + "expression": [ + "<", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "en"} + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "ä", "rhs": "b"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, true], + "serialized": [ + "<", + ["string", ["get", "lhs"]], + ["string", ["get", "rhs"]], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/accent-not-equals-en/test.json b/shared/test/data/expression-tests/collator/accent-not-equals-en/test.json new file mode 100644 index 000000000..190cb9251 --- /dev/null +++ b/shared/test/data/expression-tests/collator/accent-not-equals-en/test.json @@ -0,0 +1,40 @@ +{ + "expression": [ + "!", + [ + "!=", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "en"} + ] + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "b", "rhs": "ä"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false, false], + "serialized": [ + "!", + [ + "!=", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "en"} + ] + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/base-default-locale/test.json b/shared/test/data/expression-tests/collator/base-default-locale/test.json new file mode 100644 index 000000000..46675af49 --- /dev/null +++ b/shared/test/data/expression-tests/collator/base-default-locale/test.json @@ -0,0 +1,28 @@ +{ + "expression": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + ["collator", {"case-sensitive": false, "diacritic-sensitive": false}] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "a"}}], + [{}, {"properties": {"lhs": "A", "rhs": "A"}}], + [{}, {"properties": {"lhs": "b", "rhs": "a"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false], + "serialized": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + ["collator", {"case-sensitive": false, "diacritic-sensitive": false}] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/base-equals-en/test.json b/shared/test/data/expression-tests/collator/base-equals-en/test.json new file mode 100644 index 000000000..554e90d56 --- /dev/null +++ b/shared/test/data/expression-tests/collator/base-equals-en/test.json @@ -0,0 +1,34 @@ +{ + "expression": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": false, "locale": "en"} + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "b", "rhs": "ä"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false], + "serialized": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": false, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/base-gt-en/test.json b/shared/test/data/expression-tests/collator/base-gt-en/test.json new file mode 100644 index 000000000..0a33197f6 --- /dev/null +++ b/shared/test/data/expression-tests/collator/base-gt-en/test.json @@ -0,0 +1,34 @@ +{ + "expression": [ + ">", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": false, "locale": "en"} + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "b", "rhs": "ä"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, false, true], + "serialized": [ + ">", + ["string", ["get", "lhs"]], + ["string", ["get", "rhs"]], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": false, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/case-lteq-en/test.json b/shared/test/data/expression-tests/collator/case-lteq-en/test.json new file mode 100644 index 000000000..bdbfa6802 --- /dev/null +++ b/shared/test/data/expression-tests/collator/case-lteq-en/test.json @@ -0,0 +1,35 @@ +{ + "expression": [ + "<=", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"} + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "ä", "rhs": "a"}}], + [{}, {"properties": {"lhs": "A", "rhs": "a"}}], + [{}, {"properties": {"lhs": "a", "rhs": "a"}}], + [{}, {"properties": {"lhs": "ä", "rhs": "b"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, true, true], + "serialized": [ + "<=", + ["string", ["get", "lhs"]], + ["string", ["get", "rhs"]], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/case-not-equals-en/test.json b/shared/test/data/expression-tests/collator/case-not-equals-en/test.json new file mode 100644 index 000000000..ee494a4d5 --- /dev/null +++ b/shared/test/data/expression-tests/collator/case-not-equals-en/test.json @@ -0,0 +1,40 @@ +{ + "expression": [ + "!", + [ + "!=", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"} + ] + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "b", "rhs": "ä"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, false], + "serialized": [ + "!", + [ + "!=", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"} + ] + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/case-omitted-en/test.json b/shared/test/data/expression-tests/collator/case-omitted-en/test.json new file mode 100644 index 000000000..b852f5c88 --- /dev/null +++ b/shared/test/data/expression-tests/collator/case-omitted-en/test.json @@ -0,0 +1,32 @@ +{ + "expression": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + ["collator", {"diacritic-sensitive": true, "locale": "en"}] + ], + "inputs": [ + [{}, {"properties": {"lhs": "ä", "rhs": "a"}}], + [{}, {"properties": {"lhs": "A", "rhs": "a"}}], + [{}, {"properties": {"lhs": "a", "rhs": "a"}}], + [{}, {"properties": {"lhs": "ä", "rhs": "b"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, true, false], + "serialized": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": false, "diacritic-sensitive": true, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/comparison-number-error/test.json b/shared/test/data/expression-tests/collator/comparison-number-error/test.json new file mode 100644 index 000000000..921caa41d --- /dev/null +++ b/shared/test/data/expression-tests/collator/comparison-number-error/test.json @@ -0,0 +1,16 @@ +{ + "expression": [ + "<", + 1, + 2, + ["collator", {"case-sensitive": false, "diacritic-sensitive": false}] + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot use collator to compare non-string types."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/collator/diacritic-omitted-en/test.json b/shared/test/data/expression-tests/collator/diacritic-omitted-en/test.json new file mode 100644 index 000000000..db8416c79 --- /dev/null +++ b/shared/test/data/expression-tests/collator/diacritic-omitted-en/test.json @@ -0,0 +1,31 @@ +{ + "expression": [ + "<", + ["string", ["get", "lhs"]], + ["get", "rhs"], + ["collator", {"case-sensitive": ["==", 1, 1], "locale": "en"}] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "ä", "rhs": "b"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, true], + "serialized": [ + "<", + ["string", ["get", "lhs"]], + ["string", ["get", "rhs"]], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": false, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/equals-non-string-error/test.json b/shared/test/data/expression-tests/collator/equals-non-string-error/test.json new file mode 100644 index 000000000..4d566f90b --- /dev/null +++ b/shared/test/data/expression-tests/collator/equals-non-string-error/test.json @@ -0,0 +1,16 @@ +{ + "expression": [ + "==", + 1, + 2, + ["collator", {"case-sensitive": false, "diacritic-sensitive": false}] + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot use collator to compare non-string types."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/collator/non-object-error/test.json b/shared/test/data/expression-tests/collator/non-object-error/test.json new file mode 100644 index 000000000..148c9f1b5 --- /dev/null +++ b/shared/test/data/expression-tests/collator/non-object-error/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["==", "foo", "bar", ["collator", ["subexpression"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[3]", "error": "Collator options argument must be an object."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/collator/variant-equals-en/test.json b/shared/test/data/expression-tests/collator/variant-equals-en/test.json new file mode 100644 index 000000000..c632b45e8 --- /dev/null +++ b/shared/test/data/expression-tests/collator/variant-equals-en/test.json @@ -0,0 +1,34 @@ +{ + "expression": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": true, "locale": "en"} + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "b", "rhs": "ä"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, false, false], + "serialized": [ + "==", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": true, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/collator/variant-gteq-en/test.json b/shared/test/data/expression-tests/collator/variant-gteq-en/test.json new file mode 100644 index 000000000..ffdb3025b --- /dev/null +++ b/shared/test/data/expression-tests/collator/variant-gteq-en/test.json @@ -0,0 +1,35 @@ +{ + "expression": [ + ">=", + ["string", ["get", "lhs"]], + ["get", "rhs"], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": true, "locale": "en"} + ] + ], + "inputs": [ + [{}, {"properties": {"lhs": "a", "rhs": "ä"}}], + [{}, {"properties": {"lhs": "a", "rhs": "A"}}], + [{}, {"properties": {"lhs": "a", "rhs": "a"}}], + [{}, {"properties": {"lhs": "b", "rhs": "ä"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, false, true, true], + "serialized": [ + ">=", + ["string", ["get", "lhs"]], + ["string", ["get", "rhs"]], + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": true, "locale": "en"} + ] + ] + } +} diff --git a/shared/test/data/expression-tests/concat/arity-0/test.json b/shared/test/data/expression-tests/concat/arity-0/test.json new file mode 100644 index 000000000..19b57cf18 --- /dev/null +++ b/shared/test/data/expression-tests/concat/arity-0/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["concat"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [""], + "serialized": "" + } +} diff --git a/shared/test/data/expression-tests/concat/arity-1/test.json b/shared/test/data/expression-tests/concat/arity-1/test.json new file mode 100644 index 000000000..a5b25ab15 --- /dev/null +++ b/shared/test/data/expression-tests/concat/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["concat", "foo"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["foo"], + "serialized": "foo" + } +} diff --git a/shared/test/data/expression-tests/concat/basic/test.json b/shared/test/data/expression-tests/concat/basic/test.json new file mode 100644 index 000000000..833fd2949 --- /dev/null +++ b/shared/test/data/expression-tests/concat/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["concat", "a", "b", "c"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["abc"], + "serialized": "abc" + } +} diff --git a/shared/test/data/expression-tests/concat/coercion/test.json b/shared/test/data/expression-tests/concat/coercion/test.json new file mode 100644 index 000000000..9b872b8ad --- /dev/null +++ b/shared/test/data/expression-tests/concat/coercion/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["concat", ["get", "a"], ["get", "1"], ["get", "true"]], + "inputs": [[{}, {"properties": {"a": "a", "1": 1, "true": true}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["a1true"], + "serialized": ["concat", ["get", "a"], ["get", "1"], ["get", "true"]] + } +} diff --git a/shared/test/data/expression-tests/constant-folding/evaluation-error/test.json b/shared/test/data/expression-tests/constant-folding/evaluation-error/test.json new file mode 100644 index 000000000..1cde4dc35 --- /dev/null +++ b/shared/test/data/expression-tests/constant-folding/evaluation-error/test.json @@ -0,0 +1,23 @@ +{ + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["step", ["get", "x"], "black", 0, "invalid", 10, "blue"], + "inputs": [ + [{}, {"properties": {"x": -1}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 5}}], + [{}, {"properties": {"x": 10}}], + [{}, {"properties": {"x": 11}}] + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[4]", "error": "Could not parse color from value 'invalid'"} + ] + } + } +} diff --git a/shared/test/data/expression-tests/constant-folding/to-color-inferred/test.json b/shared/test/data/expression-tests/constant-folding/to-color-inferred/test.json new file mode 100644 index 000000000..2d1279aa2 --- /dev/null +++ b/shared/test/data/expression-tests/constant-folding/to-color-inferred/test.json @@ -0,0 +1,15 @@ +{ + "propertySpec": {"type": "color"}, + "expression": "red", + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[1, 0, 0, 1]], + "serialized": ["rgba", 255, 0, 0, 1] + } +} diff --git a/shared/test/data/expression-tests/constant-folding/to-color/test.json b/shared/test/data/expression-tests/constant-folding/to-color/test.json new file mode 100644 index 000000000..e3dfe9d4e --- /dev/null +++ b/shared/test/data/expression-tests/constant-folding/to-color/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["to-color", "red"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[1, 0, 0, 1]], + "serialized": ["rgba", 255, 0, 0, 1] + } +} diff --git a/shared/test/data/expression-tests/constant-folding/var/test.json b/shared/test/data/expression-tests/constant-folding/var/test.json new file mode 100644 index 000000000..7b35bddd7 --- /dev/null +++ b/shared/test/data/expression-tests/constant-folding/var/test.json @@ -0,0 +1,21 @@ +{ + "expression": [ + "let", + "a", + 1, + "b", + 2, + ["+", ["+", ["var", "a"], ["var", "b"]], ["var", "a"]] + ], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [4], + "serialized": 4 + } +} diff --git a/shared/test/data/expression-tests/cos/basic/test.json b/shared/test/data/expression-tests/cos/basic/test.json new file mode 100644 index 000000000..3d495d60f --- /dev/null +++ b/shared/test/data/expression-tests/cos/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["cos", 0], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1], + "serialized": 1 + } +} diff --git a/shared/test/data/expression-tests/divide/basic/test.json b/shared/test/data/expression-tests/divide/basic/test.json new file mode 100644 index 000000000..9c10acab2 --- /dev/null +++ b/shared/test/data/expression-tests/divide/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["/", 10, 5], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [2], + "serialized": 2 + } +} diff --git a/shared/test/data/expression-tests/downcase/basic/test.json b/shared/test/data/expression-tests/downcase/basic/test.json new file mode 100644 index 000000000..7bf06fcae --- /dev/null +++ b/shared/test/data/expression-tests/downcase/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["downcase", "StRiNg"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["string"], + "serialized": "string" + } +} diff --git a/shared/test/data/expression-tests/e/basic/test.json b/shared/test/data/expression-tests/e/basic/test.json new file mode 100644 index 000000000..fdf524abb --- /dev/null +++ b/shared/test/data/expression-tests/e/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["e"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [2.71828], + "serialized": 2.718281828459045 + } +} diff --git a/shared/test/data/expression-tests/equal/array/test.json b/shared/test/data/expression-tests/equal/array/test.json new file mode 100644 index 000000000..fe28d0798 --- /dev/null +++ b/shared/test/data/expression-tests/equal/array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["==", ["get", "x"], ["literal", [1]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[2]", + "error": "\"==\" comparisons are not supported for type 'array'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/equal/collator-value/test.json b/shared/test/data/expression-tests/equal/collator-value/test.json new file mode 100644 index 000000000..4d0db1e8d --- /dev/null +++ b/shared/test/data/expression-tests/equal/collator-value/test.json @@ -0,0 +1,31 @@ +{ + "expression": [ + "==", + ["get", "x"], + ["get", "y"], + ["collator", {"case-sensitive": false, "diacritic-sensitive": false}] + ], + "inputs": [ + [{}, {"properties": {"x": "a", "y": "A"}}], + [{}, {"properties": {"x": "1", "y": "2"}}], + [{}, {"properties": {"x": "1", "y": null}}], + [{}, {"properties": {"x": null, "y": null}}], + [{}, {"properties": {"x": 1, "y": "1"}}], + [{}, {"properties": {"x": 1, "y": 1}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false, false, true, false, true], + "serialized": [ + "==", + ["get", "x"], + ["get", "y"], + ["collator", {"case-sensitive": false, "diacritic-sensitive": false}] + ] + } +} diff --git a/shared/test/data/expression-tests/equal/color/test.json b/shared/test/data/expression-tests/equal/color/test.json new file mode 100644 index 000000000..6e04c7410 --- /dev/null +++ b/shared/test/data/expression-tests/equal/color/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["==", ["get", "x"], ["to-color", "red"]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[2]", + "error": "\"==\" comparisons are not supported for type 'color'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/equal/mismatch/test.json b/shared/test/data/expression-tests/equal/mismatch/test.json new file mode 100644 index 000000000..a1b440244 --- /dev/null +++ b/shared/test/data/expression-tests/equal/mismatch/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["==", ["string", ["get", "x"]], ["number", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot compare types 'string' and 'number'."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/equal/null-lhs/test.json b/shared/test/data/expression-tests/equal/null-lhs/test.json new file mode 100644 index 000000000..69cc18bf3 --- /dev/null +++ b/shared/test/data/expression-tests/equal/null-lhs/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["==", null, ["get", "x"]], + "inputs": [[{}, {"properties": {}}], [{}, {"properties": {"x": 1}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false], + "serialized": ["==", null, ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/equal/null-rhs/test.json b/shared/test/data/expression-tests/equal/null-rhs/test.json new file mode 100644 index 000000000..69cc18bf3 --- /dev/null +++ b/shared/test/data/expression-tests/equal/null-rhs/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["==", null, ["get", "x"]], + "inputs": [[{}, {"properties": {}}], [{}, {"properties": {"x": 1}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false], + "serialized": ["==", null, ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/equal/number/test.json b/shared/test/data/expression-tests/equal/number/test.json new file mode 100644 index 000000000..ec4e96872 --- /dev/null +++ b/shared/test/data/expression-tests/equal/number/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["==", ["number", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": 1, "y": 1}}], + [{}, {"properties": {"x": 1, "y": 2}}], + [{}, {"properties": {"x": 1, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false, false], + "serialized": ["==", ["number", ["get", "x"]], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/equal/object/test.json b/shared/test/data/expression-tests/equal/object/test.json new file mode 100644 index 000000000..97a51854e --- /dev/null +++ b/shared/test/data/expression-tests/equal/object/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["==", ["get", "x"], ["literal", {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[2]", + "error": "\"==\" comparisons are not supported for type 'object'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/equal/string/test.json b/shared/test/data/expression-tests/equal/string/test.json new file mode 100644 index 000000000..8a28af37b --- /dev/null +++ b/shared/test/data/expression-tests/equal/string/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["==", ["string", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": 2}}], + [{}, {"properties": {"x": "1", "y": 1}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false, false], + "serialized": ["==", ["string", ["get", "x"]], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/equal/value/test.json b/shared/test/data/expression-tests/equal/value/test.json new file mode 100644 index 000000000..52d65fd40 --- /dev/null +++ b/shared/test/data/expression-tests/equal/value/test.json @@ -0,0 +1,21 @@ +{ + "expression": ["==", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": 0, "y": 0}}], + [{}, {"properties": {"x": "0", "y": "0"}}], + [{}, {"properties": {"x": 0, "y": false}}], + [{}, {"properties": {"x": 0, "y": "0"}}], + [{}, {"properties": {"x": 0, "y": null}}], + [{}, {"properties": {"x": "0", "y": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false, false, false, false], + "serialized": ["==", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/floor/basic/test.json b/shared/test/data/expression-tests/floor/basic/test.json new file mode 100644 index 000000000..ad28186ce --- /dev/null +++ b/shared/test/data/expression-tests/floor/basic/test.json @@ -0,0 +1,23 @@ +{ + "expression": ["floor", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": -2.6}}], + [{}, {"properties": {"x": -2.5}}], + [{}, {"properties": {"x": -2.4}}], + [{}, {"properties": {"x": -2}}], + [{}, {"properties": {"x": 2.6}}], + [{}, {"properties": {"x": 2.5}}], + [{}, {"properties": {"x": 2.4}}], + [{}, {"properties": {"x": 2}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-3, -3, -3, -2, 2, 2, 2, 2], + "serialized": ["floor", ["number", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/format/basic/test.json b/shared/test/data/expression-tests/format/basic/test.json new file mode 100644 index 000000000..3f6eeaddc --- /dev/null +++ b/shared/test/data/expression-tests/format/basic/test.json @@ -0,0 +1,96 @@ +{ + "expression": [ + "format", + "a", + {}, + "b", + { + "font-scale": 2 + }, + "c", + { + "text-font": [ + "literal", + [ + "a", + "b" + ] + ] + }, + "d", + { + "text-color": "rgb(0, 255, 0)" + } + ], + "inputs": [ + [ + {}, + {} + ] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "formatted" + }, + "outputs": [ + { + "sections": [ + { + "text": "a", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + }, + { + "text": "b", + "image": null, + "scale": 2, + "fontStack": null, + "textColor": null + }, + { + "text": "c", + "image": null, + "scale": null, + "fontStack": "a,b", + "textColor": null + }, + { + "text": "d", + "image": null, + "scale": null, + "fontStack": null, + "textColor": {"r":0,"g":1,"b":0,"a":1} + } + ] + } + ], + "serialized": [ + "format", + "a", + {}, + "b", + { + "font-scale": 2 + }, + "c", + { + "text-font": [ + "literal", + [ + "a", + "b" + ] + ] + }, + "d", + { + "text-color": ["rgba", 0, 255, 0, 1] + } + ] + } +} diff --git a/shared/test/data/expression-tests/format/coercion/test.json b/shared/test/data/expression-tests/format/coercion/test.json new file mode 100644 index 000000000..213eb9615 --- /dev/null +++ b/shared/test/data/expression-tests/format/coercion/test.json @@ -0,0 +1,56 @@ +{ + "expression": [ + "format", + ["get", "a"], + {}, + ["get", "1"], + {}, + ["get", "true"], + {} + ], + "inputs": [[{}, {"properties": {"a": "a", "1": 1, "true": true}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "formatted" + }, + "outputs": [ + { + "sections": [ + { + "text": "a", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + }, + { + "text": "1", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + }, + { + "text": "true", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + } + ], + "serialized": [ + "format", + ["get", "a"], + {}, + ["get", "1"], + {}, + ["get", "true"], + {} + ] + } +} diff --git a/shared/test/data/expression-tests/format/data-driven-font/test.json b/shared/test/data/expression-tests/format/data-driven-font/test.json new file mode 100644 index 000000000..c81fff8e8 --- /dev/null +++ b/shared/test/data/expression-tests/format/data-driven-font/test.json @@ -0,0 +1,52 @@ +{ + "expression": [ + "format", + "a", + { + "font-scale": ["get", "font-scale"] + } + ], + "inputs": [ + [{}, {"properties": {"font-scale": 1.5}}], + [{}, {"properties": {"font-scale": 0.5}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "formatted" + }, + "outputs": [ + { + "sections": [ + { + "text": "a", + "image": null, + "scale": 1.5, + "fontStack": null, + "textColor": null + } + ] + }, + { + "sections": [ + { + "text": "a", + "image": null, + "scale": 0.5, + "fontStack": null, + "textColor": null + } + ] + } + ], + "serialized": [ + "format", + "a", + { + "font-scale": ["number", ["get", "font-scale"]] + } + ] + } +} diff --git a/shared/test/data/expression-tests/format/data-driven-scale/test.json b/shared/test/data/expression-tests/format/data-driven-scale/test.json new file mode 100644 index 000000000..c34d1a6b9 --- /dev/null +++ b/shared/test/data/expression-tests/format/data-driven-scale/test.json @@ -0,0 +1,23 @@ +{ + "expression": [ + "format", + "a", + { + "text-font": ["array", ["string", ["get", "text-font"]]] + } + ], + "inputs": [ + [{}, {"properties": {"text-font": "test"}}] + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "error": "Expected array but found array instead.", + "key": "[1]" + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/format/image-sections/test.json b/shared/test/data/expression-tests/format/image-sections/test.json new file mode 100644 index 000000000..63f40ec47 --- /dev/null +++ b/shared/test/data/expression-tests/format/image-sections/test.json @@ -0,0 +1,54 @@ +{ + "expression": [ + "format", + ["image", "monument-15"], + ["image", "beach-11"] + ], + "inputs": [ + [ + {"availableImages": ["monument-15"]}, + {} + ] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "formatted" + }, + "outputs": [ + { + "sections": [ + { + "text": "", + "image": {"name": "monument-15", "available": true}, + "scale": null, + "fontStack": null, + "textColor": null + }, + { + "text": "", + "image": {"name": "beach-11", "available": false}, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + } + ], + "serialized": [ + "format", + [ + "image", + "monument-15" + ], + {}, + [ + "image", + "beach-11" + ], + {} + ] + } +} diff --git a/shared/test/data/expression-tests/format/implicit-assert/test.json b/shared/test/data/expression-tests/format/implicit-assert/test.json new file mode 100644 index 000000000..ee26d2f0b --- /dev/null +++ b/shared/test/data/expression-tests/format/implicit-assert/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["number", ["get", "p"]], + "propertySpec": { + "type": "formatted" + }, + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Expected formatted but found number instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/format/implicit-coerce/test.json b/shared/test/data/expression-tests/format/implicit-coerce/test.json new file mode 100644 index 000000000..6b0877bc6 --- /dev/null +++ b/shared/test/data/expression-tests/format/implicit-coerce/test.json @@ -0,0 +1,59 @@ +{ + "expression": ["to-string", ["get", "p"]], + "propertySpec": { + "type": "formatted" + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": "a"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "formatted" + }, + "outputs": [ + { + "sections": [ + { + "text": "", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + }, + { + "sections": [ + { + "text": "0", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + }, + { + "sections": [ + { + "text": "a", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + } + ], + "serialized": [ + "format", + ["to-string", ["get", "p"]], + {} + ] + } +} diff --git a/shared/test/data/expression-tests/format/implicit-omit/test.json b/shared/test/data/expression-tests/format/implicit-omit/test.json new file mode 100644 index 000000000..c586958ed --- /dev/null +++ b/shared/test/data/expression-tests/format/implicit-omit/test.json @@ -0,0 +1,59 @@ +{ + "expression": ["coalesce", ["get", "q"], ["get", "p"]], + "propertySpec": { + "type": "formatted" + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": "a"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "formatted" + }, + "outputs": [ + { + "sections": [ + { + "text": "", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + }, + { + "sections": [ + { + "text": "0", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + }, + { + "sections": [ + { + "text": "a", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + } + ], + "serialized": [ + "format", + ["coalesce", ["get", "q"], ["get", "p"]], + {} + ] + } +} diff --git a/shared/test/data/expression-tests/format/implicit/test.json b/shared/test/data/expression-tests/format/implicit/test.json new file mode 100644 index 000000000..097bdf814 --- /dev/null +++ b/shared/test/data/expression-tests/format/implicit/test.json @@ -0,0 +1,59 @@ +{ + "expression": ["get", "p"], + "propertySpec": { + "type": "formatted" + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": "a"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "formatted" + }, + "outputs": [ + { + "sections": [ + { + "text": "", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + }, + { + "sections": [ + { + "text": "0", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + }, + { + "sections": [ + { + "text": "a", + "image": null, + "scale": null, + "fontStack": null, + "textColor": null + } + ] + } + ], + "serialized": [ + "format", + ["get", "p"], + {} + ] + } +} diff --git a/shared/test/data/expression-tests/format/to-string/test.json b/shared/test/data/expression-tests/format/to-string/test.json new file mode 100644 index 000000000..2c505712f --- /dev/null +++ b/shared/test/data/expression-tests/format/to-string/test.json @@ -0,0 +1,42 @@ +{ + "expression": [ + "to-string", + [ + "format", + "a", + {}, + "b", + { + "font-scale": 2 + }, + "c", + { + "text-font": [ + "literal", + [ + "a", + "b" + ] + ] + } + ] + ], + "inputs": [ + [ + {}, + {} + ] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "abc" + ], + "serialized": "abc" + } +} diff --git a/shared/test/data/expression-tests/geometry-type/basic/test.json b/shared/test/data/expression-tests/geometry-type/basic/test.json new file mode 100644 index 000000000..999521d88 --- /dev/null +++ b/shared/test/data/expression-tests/geometry-type/basic/test.json @@ -0,0 +1,16 @@ +{ + "expression": ["geometry-type"], + "inputs": [ + [{}, {"geometry": {"type": "LineString", "coordinates": [[0, 0], [10, 0]]}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["LineString"], + "serialized": ["geometry-type"] + } +} diff --git a/shared/test/data/expression-tests/get/basic/test.json b/shared/test/data/expression-tests/get/basic/test.json new file mode 100644 index 000000000..b5b8da5a4 --- /dev/null +++ b/shared/test/data/expression-tests/get/basic/test.json @@ -0,0 +1,17 @@ +{ + "expression": ["number", ["get", "x"]], + "inputs": [[{}, {}], [{}, {"properties": {"x": 1}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + 1 + ], + "serialized": ["number", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/get/from-literal--missing/test.json b/shared/test/data/expression-tests/get/from-literal--missing/test.json new file mode 100644 index 000000000..dcd403efd --- /dev/null +++ b/shared/test/data/expression-tests/get/from-literal--missing/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["number", ["get", "x", ["literal", {"y": 0}]]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Expected value to be of type number, but found null instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/get/from-literal/test.json b/shared/test/data/expression-tests/get/from-literal/test.json new file mode 100644 index 000000000..e7ee4478b --- /dev/null +++ b/shared/test/data/expression-tests/get/from-literal/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["number", ["get", "x", ["literal", {"x": 0}]]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0], + "serialized": 0 + } +} diff --git a/shared/test/data/expression-tests/get/from-object-property/test.json b/shared/test/data/expression-tests/get/from-object-property/test.json new file mode 100644 index 000000000..6d1c091e2 --- /dev/null +++ b/shared/test/data/expression-tests/get/from-object-property/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["number", ["get", "x", ["object", ["get", "a"]]]], + "inputs": [[{}, {"properties": {"a": {"x": 1}}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1], + "serialized": ["number", ["get", "x", ["object", ["get", "a"]]]] + } +} diff --git a/shared/test/data/expression-tests/greater/boolean/test.json b/shared/test/data/expression-tests/greater/boolean/test.json new file mode 100644 index 000000000..0947dcf6e --- /dev/null +++ b/shared/test/data/expression-tests/greater/boolean/test.json @@ -0,0 +1,14 @@ +{ + "expression": [">", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\">\" comparisons are not supported for type 'boolean'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/greater/mismatch/test.json b/shared/test/data/expression-tests/greater/mismatch/test.json new file mode 100644 index 000000000..e073c4848 --- /dev/null +++ b/shared/test/data/expression-tests/greater/mismatch/test.json @@ -0,0 +1,11 @@ +{ + "expression": [">", ["string", ["get", "x"]], ["number", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot compare types 'string' and 'number'."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/greater/null/test.json b/shared/test/data/expression-tests/greater/null/test.json new file mode 100644 index 000000000..44c8e864d --- /dev/null +++ b/shared/test/data/expression-tests/greater/null/test.json @@ -0,0 +1,14 @@ +{ + "expression": [">", null, null], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\">\" comparisons are not supported for type 'null'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/greater/number/test.json b/shared/test/data/expression-tests/greater/number/test.json new file mode 100644 index 000000000..15d24ab95 --- /dev/null +++ b/shared/test/data/expression-tests/greater/number/test.json @@ -0,0 +1,18 @@ +{ + "expression": [">", ["number", ["get", "x"]], ["number", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": 1, "y": 1}}], + [{}, {"properties": {"x": 1, "y": 2}}], + [{}, {"properties": {"x": 2, "y": 1}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, false, true], + "serialized": [">", ["number", ["get", "x"]], ["number", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/greater/string-and-value/test.json b/shared/test/data/expression-tests/greater/string-and-value/test.json new file mode 100644 index 000000000..e345c087a --- /dev/null +++ b/shared/test/data/expression-tests/greater/string-and-value/test.json @@ -0,0 +1,26 @@ +{ + "expression": [">", ["string", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "2", "y": "1"}}], + [{}, {"properties": {"x": "2", "y": 1}}], + [{}, {"properties": {"x": 2, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + { + "error": "Expected value to be of type string, but found number instead." + }, + { + "error": "Expected value to be of type string, but found number instead." + } + ], + "serialized": [">", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/greater/string/test.json b/shared/test/data/expression-tests/greater/string/test.json new file mode 100644 index 000000000..26927b20a --- /dev/null +++ b/shared/test/data/expression-tests/greater/string/test.json @@ -0,0 +1,21 @@ +{ + "expression": [">", ["string", ["get", "x"]], ["string", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": "2"}}], + [{}, {"properties": {"x": "2", "y": "1"}}], + [{}, {"properties": {"x": "abc", "y": "azz"}}], + [{}, {"properties": {"x": "abc", "y": "aaa"}}], + [{}, {"properties": {"x": "abc", "y": "abc"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, false, true, false, true, false], + "serialized": [">", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/greater/value/test.json b/shared/test/data/expression-tests/greater/value/test.json new file mode 100644 index 000000000..75c314eec --- /dev/null +++ b/shared/test/data/expression-tests/greater/value/test.json @@ -0,0 +1,28 @@ +{ + "expression": [">", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "2", "y": "10"}}], + [{}, {"properties": {"x": 10, "y": 1}}], + [{}, {"properties": {"x": "1", "y": 1}}], + [{}, {"properties": {"x": 1, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + true, + { + "error": "Expected arguments for \">\" to be (string, string) or (number, number), but found (string, number) instead." + }, + { + "error": "Expected arguments for \">\" to be (string, string) or (number, number), but found (number, string) instead." + } + ], + "serialized": [">", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/greater_or_equal/boolean/test.json b/shared/test/data/expression-tests/greater_or_equal/boolean/test.json new file mode 100644 index 000000000..5ec7d8021 --- /dev/null +++ b/shared/test/data/expression-tests/greater_or_equal/boolean/test.json @@ -0,0 +1,14 @@ +{ + "expression": [">=", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\">=\" comparisons are not supported for type 'boolean'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/greater_or_equal/mismatch/test.json b/shared/test/data/expression-tests/greater_or_equal/mismatch/test.json new file mode 100644 index 000000000..9b2275f0f --- /dev/null +++ b/shared/test/data/expression-tests/greater_or_equal/mismatch/test.json @@ -0,0 +1,11 @@ +{ + "expression": [">=", ["string", ["get", "x"]], ["number", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot compare types 'string' and 'number'."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/greater_or_equal/null/test.json b/shared/test/data/expression-tests/greater_or_equal/null/test.json new file mode 100644 index 000000000..4fbf753fc --- /dev/null +++ b/shared/test/data/expression-tests/greater_or_equal/null/test.json @@ -0,0 +1,14 @@ +{ + "expression": [">=", null, null], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\">=\" comparisons are not supported for type 'null'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/greater_or_equal/number/test.json b/shared/test/data/expression-tests/greater_or_equal/number/test.json new file mode 100644 index 000000000..cf731070f --- /dev/null +++ b/shared/test/data/expression-tests/greater_or_equal/number/test.json @@ -0,0 +1,18 @@ +{ + "expression": [">=", ["number", ["get", "x"]], ["number", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": 1, "y": 1}}], + [{}, {"properties": {"x": 1, "y": 2}}], + [{}, {"properties": {"x": 2, "y": 1}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false, true], + "serialized": [">=", ["number", ["get", "x"]], ["number", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/greater_or_equal/string-and-value/test.json b/shared/test/data/expression-tests/greater_or_equal/string-and-value/test.json new file mode 100644 index 000000000..0cdd25d88 --- /dev/null +++ b/shared/test/data/expression-tests/greater_or_equal/string-and-value/test.json @@ -0,0 +1,26 @@ +{ + "expression": [">=", ["string", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": 1}}], + [{}, {"properties": {"x": 1, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + { + "error": "Expected value to be of type string, but found number instead." + }, + { + "error": "Expected value to be of type string, but found number instead." + } + ], + "serialized": [">=", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/greater_or_equal/string/test.json b/shared/test/data/expression-tests/greater_or_equal/string/test.json new file mode 100644 index 000000000..bd4153ba8 --- /dev/null +++ b/shared/test/data/expression-tests/greater_or_equal/string/test.json @@ -0,0 +1,21 @@ +{ + "expression": [">=", ["string", ["get", "x"]], ["string", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": "2"}}], + [{}, {"properties": {"x": "2", "y": "1"}}], + [{}, {"properties": {"x": "abc", "y": "azz"}}], + [{}, {"properties": {"x": "abc", "y": "aaa"}}], + [{}, {"properties": {"x": "abc", "y": "abc"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, false, true, false, true, true], + "serialized": [">=", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/greater_or_equal/value/test.json b/shared/test/data/expression-tests/greater_or_equal/value/test.json new file mode 100644 index 000000000..e92a5684b --- /dev/null +++ b/shared/test/data/expression-tests/greater_or_equal/value/test.json @@ -0,0 +1,28 @@ +{ + "expression": [">=", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "2", "y": "10"}}], + [{}, {"properties": {"x": 10, "y": 1}}], + [{}, {"properties": {"x": "1", "y": 1}}], + [{}, {"properties": {"x": 1, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + true, + { + "error": "Expected arguments for \">=\" to be (string, string) or (number, number), but found (string, number) instead." + }, + { + "error": "Expected arguments for \">=\" to be (string, string) or (number, number), but found (number, string) instead." + } + ], + "serialized": [">=", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/has/basic/test.json b/shared/test/data/expression-tests/has/basic/test.json new file mode 100644 index 000000000..45b1fdfe1 --- /dev/null +++ b/shared/test/data/expression-tests/has/basic/test.json @@ -0,0 +1,20 @@ +{ + "expression": ["has", "x"], + "inputs": [ + [{}, {}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, true, true, true], + "serialized": ["has", "x"] + } +} diff --git a/shared/test/data/expression-tests/heatmap-density/basic/test.json b/shared/test/data/expression-tests/heatmap-density/basic/test.json new file mode 100644 index 000000000..f5f9b76f4 --- /dev/null +++ b/shared/test/data/expression-tests/heatmap-density/basic/test.json @@ -0,0 +1,45 @@ +{ + "propertySpec": { + "type": "color", + "default": { + "stops": [ + [0, "rgba(0, 0, 255, 0)"], + [0.1, "royalblue"], + [0.3, "cyan"], + [0.5, "lime"], + [0.7, "yellow"], + [1, "red"] + ] + }, + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": [ + "interpolate", + ["linear"], + ["heatmap-density"], + 0, + "#000000", + 1, + "#ff0000" + ], + "inputs": [[{"heatmapDensity": 0.5}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[0.5, 0, 0, 1]], + "serialized": [ + "interpolate", + ["linear"], + ["heatmap-density"], + 0, + ["rgba", 0, 0, 0, 1], + 1, + ["rgba", 255, 0, 0, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/id/basic/test.json b/shared/test/data/expression-tests/id/basic/test.json new file mode 100644 index 000000000..e6aa009ad --- /dev/null +++ b/shared/test/data/expression-tests/id/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["id"], + "inputs": [[{}, {}], [{}, {"id": 1}], [{}, {"id": "one"}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": [null, 1, "one"], + "serialized": ["id"] + } +} diff --git a/shared/test/data/expression-tests/image/basic/test.json b/shared/test/data/expression-tests/image/basic/test.json new file mode 100644 index 000000000..797966e7e --- /dev/null +++ b/shared/test/data/expression-tests/image/basic/test.json @@ -0,0 +1,27 @@ +{ + "expression": [ + "image", + "monument-15" + ], + "inputs": [ + [ + {"availableImages": ["monument-15"]}, + {} + ] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "resolvedImage" + }, + "outputs": [ + {"name":"monument-15","available":true} + ], + "serialized": [ + "image", + "monument-15" + ] + } +} diff --git a/shared/test/data/expression-tests/image/coalesce/test.json b/shared/test/data/expression-tests/image/coalesce/test.json new file mode 100644 index 000000000..75f168207 --- /dev/null +++ b/shared/test/data/expression-tests/image/coalesce/test.json @@ -0,0 +1,29 @@ +{ + "expression": ["coalesce", ["image", "foo"], ["image", "bar"], ["image", "monument-15"]], + "propertySpec": { + "type": "resolvedImage" + }, + "inputs": [ + [ + {"availableImages": ["monument-15"]}, + {} + ] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "resolvedImage" + }, + "outputs": [ + {"name":"monument-15","available":true} + ], + "serialized": [ + "coalesce", + ["image", "foo"], + ["image", "bar"], + ["image", "monument-15"] + ] + } +} diff --git a/shared/test/data/expression-tests/image/compound/test.json b/shared/test/data/expression-tests/image/compound/test.json new file mode 100644 index 000000000..0b2b8bbcf --- /dev/null +++ b/shared/test/data/expression-tests/image/compound/test.json @@ -0,0 +1,29 @@ +{ + "expression": [ + "image", + ["get", "icon"] + ], + "inputs": [ + [ + {"availableImages": ["monument-15"]}, + { + "properties": {"icon": "monument-15"} + } + ] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "resolvedImage" + }, + "outputs": [ + {"name":"monument-15","available":true} + ], + "serialized": [ + "image", + ["string", ["get", "icon"]] + ] + } +} diff --git a/shared/test/data/expression-tests/image/implicit-assert/test.json b/shared/test/data/expression-tests/image/implicit-assert/test.json new file mode 100644 index 000000000..beb6630d5 --- /dev/null +++ b/shared/test/data/expression-tests/image/implicit-assert/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["number", ["get", "icon"]], + "propertySpec": { + "type": "resolvedImage" + }, + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Expected resolvedImage but found number instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/in/assert-array/test.json b/shared/test/data/expression-tests/in/assert-array/test.json new file mode 100644 index 000000000..e3da9d024 --- /dev/null +++ b/shared/test/data/expression-tests/in/assert-array/test.json @@ -0,0 +1,30 @@ +{ + "expression": [ + "boolean", + ["in", ["get", "i"], ["array", ["get", "arr"]]] + ], + "inputs": [ + [{}, {"properties": {"i": null, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 1, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 9, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 1, "arr": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + false, + false, + true, + {"error":"Expected value to be of type array, but found null instead."} + ], + "serialized": [ + "boolean", + ["in", ["get", "i"], ["array", ["get", "arr"]]] + ] + } +} diff --git a/shared/test/data/expression-tests/in/assert-string/test.json b/shared/test/data/expression-tests/in/assert-string/test.json new file mode 100644 index 000000000..ce59df2ab --- /dev/null +++ b/shared/test/data/expression-tests/in/assert-string/test.json @@ -0,0 +1,30 @@ +{ + "expression": [ + "boolean", + ["in", ["get", "substr"], ["string", ["get", "str"]]] + ], + "inputs": [ + [{}, {"properties": {"substr": null, "str": "helloworld"}}], + [{}, {"properties": {"substr": "foo", "str": "helloworld"}}], + [{}, {"properties": {"substr": "low", "str": "helloworld"}}], + [{}, {"properties": {"substr": "low", "str": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + false, + false, + true, + {"error":"Expected value to be of type string, but found null instead."} + ], + "serialized": [ + "boolean", + ["in", ["get", "substr"], ["string", ["get", "str"]]] + ] + } +} diff --git a/shared/test/data/expression-tests/in/basic-array/test.json b/shared/test/data/expression-tests/in/basic-array/test.json new file mode 100644 index 000000000..91b2270d2 --- /dev/null +++ b/shared/test/data/expression-tests/in/basic-array/test.json @@ -0,0 +1,34 @@ +{ + "expression": [ + "boolean", + ["in", ["get", "i"], ["get", "arr"]] + ], + "inputs": [ + [{}, {"properties": {"i": null, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 1, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 9, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": "foo", "arr": ["baz", "bar", "hello", "foo", "world"]}}], + [{}, {"properties": {"i": true, "arr": ["foo", 123, null, 456, false, {}, true]}}], + [{}, {"properties": {"i": 1, "arr": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + false, + false, + true, + true, + true, + false + ], + "serialized": [ + "boolean", + ["in", ["get", "i"], ["get", "arr"]] + ] + } +} diff --git a/shared/test/data/expression-tests/in/basic-string/test.json b/shared/test/data/expression-tests/in/basic-string/test.json new file mode 100644 index 000000000..728f1d084 --- /dev/null +++ b/shared/test/data/expression-tests/in/basic-string/test.json @@ -0,0 +1,36 @@ +{ + "expression": [ + "boolean", + ["in", ["get", "substr"], ["get", "str"]] + ], + "inputs": [ + [{}, {"properties": {"substr": null, "str": "helloworld"}}], + [{}, {"properties": {"substr": "foo", "str": "helloworld"}}], + [{}, {"properties": {"substr": "low", "str": "helloworld"}}], + [{}, {"properties": {"substr": true, "str": "falsetrue"}}], + [{}, {"properties": {"substr": false, "str": "falsetrue"}}], + [{}, {"properties": {"substr": 123, "str": "hello123world"}}], + [{}, {"properties": {"substr": "low", "str": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + false, + false, + true, + true, + true, + true, + false + ], + "serialized": [ + "boolean", + ["in", ["get", "substr"], ["get", "str"]] + ] + } +} diff --git a/shared/test/data/expression-tests/in/invalid-haystack/test.json b/shared/test/data/expression-tests/in/invalid-haystack/test.json new file mode 100644 index 000000000..f855578eb --- /dev/null +++ b/shared/test/data/expression-tests/in/invalid-haystack/test.json @@ -0,0 +1,28 @@ +{ + "expression": [ + "boolean", + ["in", ["get", "needle"], ["get", "haystack"]] + ], + "inputs": [ + [{}, {"properties": {"needle": 1, "haystack": 123}}], + [{}, {"properties": {"needle": "foo", "haystack": {}}}], + [{}, {"properties": {"needle": "foo", "haystack": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + {"error":"Expected second argument to be of type array or string, but found number instead."}, + {"error":"Expected second argument to be of type array or string, but found object instead."}, + false + ], + "serialized": [ + "boolean", + ["in", ["get", "needle"], ["get", "haystack"]] + ] + } +} diff --git a/shared/test/data/expression-tests/in/invalid-needle/test.json b/shared/test/data/expression-tests/in/invalid-needle/test.json new file mode 100644 index 000000000..0ff5cae1b --- /dev/null +++ b/shared/test/data/expression-tests/in/invalid-needle/test.json @@ -0,0 +1,26 @@ +{ + "expression": [ + "boolean", + ["in", ["get", "needle"], ["get", "haystack"]] + ], + "inputs": [ + [{}, {"properties": {"needle": {}, "haystack": [9, 8, 7]}}], + [{}, {"properties": {"needle": {}, "haystack": "helloworld"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + {"error":"Expected first argument to be of type boolean, string or number, but found object instead."}, + {"error":"Expected first argument to be of type boolean, string or number, but found object instead."} + ], + "serialized": [ + "boolean", + ["in", ["get", "needle"], ["get", "haystack"]] + ] + } +} diff --git a/shared/test/data/expression-tests/index-of/assert-array/test.json b/shared/test/data/expression-tests/index-of/assert-array/test.json new file mode 100644 index 000000000..698743ccb --- /dev/null +++ b/shared/test/data/expression-tests/index-of/assert-array/test.json @@ -0,0 +1,26 @@ +{ + "expression": ["index-of", ["get", "i"], ["array", ["get", "arr"]]], + "inputs": [ + [{}, {"properties": {"i": null, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": null, "arr": [9, 8, 7, null]}}], + [{}, {"properties": {"i": 1, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 9, "arr": [9, 8, 7, 9]}}], + [{}, {"properties": {"i": 1, "arr": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "serialized": ["index-of", ["get", "i"], ["array", ["get", "arr"]]], + "outputs": [ + -1, + 3, + -1, + 0, + {"error": "Expected value to be of type array, but found null instead."} + ] + } + } diff --git a/shared/test/data/expression-tests/index-of/assert-string/test.json b/shared/test/data/expression-tests/index-of/assert-string/test.json new file mode 100644 index 000000000..0add8e9b5 --- /dev/null +++ b/shared/test/data/expression-tests/index-of/assert-string/test.json @@ -0,0 +1,24 @@ +{ + "expression": ["index-of", ["get", "substr"], ["string", ["get", "str"]]], + "inputs": [ + [{}, {"properties": {"substr": null, "str": "helloworld"}}], + [{}, {"properties": {"substr": "foo", "str": "helloworld"}}], + [{}, {"properties": {"substr": "low", "str": "helloworld"}}], + [{}, {"properties": {"substr": "low", "str": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "serialized": ["index-of", ["get", "substr"], ["string", ["get", "str"]]], + "outputs": [ + -1, + -1, + 3, + {"error": "Expected value to be of type string, but found null instead."} + ] + } + } diff --git a/shared/test/data/expression-tests/index-of/basic-array/test.json b/shared/test/data/expression-tests/index-of/basic-array/test.json new file mode 100644 index 000000000..00fb9036c --- /dev/null +++ b/shared/test/data/expression-tests/index-of/basic-array/test.json @@ -0,0 +1,46 @@ +{ + "expression": ["index-of", ["get", "i"], ["get", "arr"]], + "inputs": [ + [{}, {"properties": {"i": null, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 1, "arr": [9, 8, 7]}}], + [{}, {"properties": {"i": 9, "arr": [9, 8, 7]}}], + [ + {}, + { + "properties": { + "i": "foo", + "arr": ["baz", "bar", "hello", "foo", "world"] + } + } + ], + [ + {}, + { + "properties": { + "i": true, + "arr": ["foo", 123, null, 456, false, {}, true] + } + } + ], + [{}, {"properties": {"i": 1, "arr": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "serialized": ["index-of", ["get", "i"], ["get", "arr"]], + "outputs": [ + -1, + -1, + 0, + 3, + 6, + { + "error": "Expected second argument to be of type array or string, but found null instead." + } + ] + } +} diff --git a/shared/test/data/expression-tests/index-of/basic-string/test.json b/shared/test/data/expression-tests/index-of/basic-string/test.json new file mode 100644 index 000000000..2f0e1eef9 --- /dev/null +++ b/shared/test/data/expression-tests/index-of/basic-string/test.json @@ -0,0 +1,32 @@ +{ + "expression": ["index-of", ["get", "substr"], ["get", "str"]], + "inputs": [ + [{}, {"properties": {"substr": null, "str": "helloworld"}}], + [{}, {"properties": {"substr": "foo", "str": "helloworld"}}], + [{}, {"properties": {"substr": "low", "str": "helloworld"}}], + [{}, {"properties": {"substr": true, "str": "falsetrue"}}], + [{}, {"properties": {"substr": false, "str": "falsetrue"}}], + [{}, {"properties": {"substr": 123, "str": "hello123world"}}], + [{}, {"properties": {"substr": "low", "str": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "serialized": ["index-of", ["get", "substr"], ["get", "str"]], + "outputs": [ + -1, + -1, + 3, + 5, + 0, + 5, + { + "error": "Expected second argument to be of type array or string, but found null instead." + } + ] + } + } diff --git a/shared/test/data/expression-tests/index-of/invalid-haystack/test.json b/shared/test/data/expression-tests/index-of/invalid-haystack/test.json new file mode 100644 index 000000000..a20ab8077 --- /dev/null +++ b/shared/test/data/expression-tests/index-of/invalid-haystack/test.json @@ -0,0 +1,28 @@ +{ + "expression": ["index-of", ["get", "needle"], ["get", "haystack"]], + "inputs": [ + [{}, {"properties": {"needle": 1, "haystack": 123}}], + [{}, {"properties": {"needle": "foo", "haystack": {}}}], + [{}, {"properties": {"needle": "foo", "haystack": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "serialized": ["index-of", ["get", "needle"], ["get", "haystack"]], + "outputs": [ + { + "error": "Expected second argument to be of type array or string, but found number instead." + }, + { + "error": "Expected second argument to be of type array or string, but found object instead." + }, + { + "error": "Expected second argument to be of type array or string, but found null instead." + } + ] + } + } diff --git a/shared/test/data/expression-tests/index-of/invalid-needle/test.json b/shared/test/data/expression-tests/index-of/invalid-needle/test.json new file mode 100644 index 000000000..fa7f3eca3 --- /dev/null +++ b/shared/test/data/expression-tests/index-of/invalid-needle/test.json @@ -0,0 +1,24 @@ +{ + "expression": ["index-of", ["get", "needle"], ["get", "haystack"]], + "inputs": [ + [{}, {"properties": {"needle": {}, "haystack": [9, 8, 7]}}], + [{}, {"properties": {"needle": {}, "haystack": "helloworld"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "serialized": ["index-of", ["get", "needle"], ["get", "haystack"]], + "outputs": [ + { + "error": "Expected first argument to be of type boolean, string, number or null, but found object instead." + }, + { + "error": "Expected first argument to be of type boolean, string, number or null, but found object instead." + } + ] + } + } diff --git a/shared/test/data/expression-tests/index-of/with-from-index/test.json b/shared/test/data/expression-tests/index-of/with-from-index/test.json new file mode 100644 index 000000000..18275f6d6 --- /dev/null +++ b/shared/test/data/expression-tests/index-of/with-from-index/test.json @@ -0,0 +1,50 @@ +{ + "expression": ["index-of", ["get", "needle"], ["get", "hay"], ["get", "i"]], + "inputs": [ + [{}, {"properties": {"needle": null, "hay": "helloworld", "i": 0}}], + [{}, {"properties": {"needle": "foo", "hay": "helloworld", "i": 0}}], + [{}, {"properties": {"needle": "low", "hay": "helloworldlow", "i": 4}}], + [{}, {"properties": {"needle": true, "hay": "falsetruetrue", "i": 6}}], + [{}, {"properties": {"needle": false, "hay": "falsetrue", "i": 0}}], + [{}, {"properties": {"needle": 123, "hay": "hello123world", "i": 6}}], + [{}, {"properties": {"needle": "low", "hay": null, "i": 0}}], + [{}, {"properties": {"needle": 7, "hay": [9, 8, 7, 8, 7, 7], "i": 3}}], + [{}, {"properties": {"needle": 9, "hay": [9, 8, 7, 8, 7, 7], "i": 1}}], + [{}, {"properties": {"needle": 8, "hay": [9, 8, 7, 8, 7, 7], "i": 1}}], + [{}, {"properties": {"needle": 8, "hay": [9, 8, 7, 8, 7, 7], "i": -1}}], + [{}, {"properties": {"needle": "foo", "hay": ["foo", "foo"], "i": -100}}], + [{}, {"properties": {"needle": "foo", "hay": "__foo__foo", "i": -100}}], + [{}, {"properties": {"needle": 8, "hay": [9, 8, 7, 8, 7, 7], "i": 10000}}], + [{}, {"properties": {"needle": 8, "hay": [9, 8, 7, 8, 7, 7], "i": "wrong"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "serialized": ["index-of", ["get", "needle"], ["get", "hay"], ["get", "i"]], + "outputs": [ + -1, + -1, + 10, + 9, + 0, + -1, + { + "error": "Expected second argument to be of type array or string, but found null instead." + }, + 4, + -1, + 1, + 1, + 0, + 2, + -1, + { + "error": "Expected third argument to be of type number, but found string instead." + } + ] + } + } diff --git a/shared/test/data/expression-tests/interpolate-hcl/linear/test.json b/shared/test/data/expression-tests/interpolate-hcl/linear/test.json new file mode 100644 index 000000000..53392e33b --- /dev/null +++ b/shared/test/data/expression-tests/interpolate-hcl/linear/test.json @@ -0,0 +1,40 @@ +{ + "expression": [ + "interpolate-hcl", + ["linear"], + ["get", "x"], + 1, + "red", + 11, + ["get", "color"] + ], + "inputs": [ + [{}, {"properties": {"x": 0, "color": "blue"}}], + [{}, {"properties": {"x": 5, "color": "blue"}}], + [{}, {"properties": {"x": 11, "color": "blue"}}], + [{}, {"properties": {"x": 11, "color": "oops blue"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [1, 0, 0, 1], + [0.870599, -0.0798922, 0.394264, 1], + [0, 0, 1, 1], + {"error": "Could not parse color from value 'oops blue'"} + ], + "serialized": [ + "interpolate-hcl", + ["linear"], + ["number", ["get", "x"]], + 1, + ["rgba", 255, 0, 0, 1], + 11, + ["to-color", ["get", "color"]] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate-lab/linear/test.json b/shared/test/data/expression-tests/interpolate-lab/linear/test.json new file mode 100644 index 000000000..8710e00ef --- /dev/null +++ b/shared/test/data/expression-tests/interpolate-lab/linear/test.json @@ -0,0 +1,40 @@ +{ + "expression": [ + "interpolate-lab", + ["linear"], + ["get", "x"], + 1, + "red", + 11, + ["get", "color"] + ], + "inputs": [ + [{}, {"properties": {"x": 0, "color": "blue"}}], + [{}, {"properties": {"x": 5, "color": "blue"}}], + [{}, {"properties": {"x": 11, "color": "blue"}}], + [{}, {"properties": {"x": 11, "color": "oops blue"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [1, 0, 0, 1], + [0.599999, 7.22057e-8, 0.4, 1], + [0, 0, 1, 1], + {"error": "Could not parse color from value 'oops blue'"} + ], + "serialized": [ + "interpolate-lab", + ["linear"], + ["number", ["get", "x"]], + 1, + ["rgba", 255, 0, 0, 1], + 11, + ["to-color", ["get", "color"]] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/cubic-bezier-3-args/test.json b/shared/test/data/expression-tests/interpolate/cubic-bezier-3-args/test.json new file mode 100644 index 000000000..b7155f43e --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/cubic-bezier-3-args/test.json @@ -0,0 +1,26 @@ +{ + "expression": [ + "number", + [ + "interpolate", + ["cubic-bezier", 0, 0, 1], + ["number", ["get", "x"]], + 0, + 0, + 100, + 100 + ] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1][1]", + "error": "Cubic bezier interpolation requires four numeric arguments with values between 0 and 1." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/interpolate/cubic-bezier-5-args/test.json b/shared/test/data/expression-tests/interpolate/cubic-bezier-5-args/test.json new file mode 100644 index 000000000..fa6a1c2d5 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/cubic-bezier-5-args/test.json @@ -0,0 +1,26 @@ +{ + "expression": [ + "number", + [ + "interpolate", + ["cubic-bezier", 0, 0, 1, 1, 1], + ["number", ["get", "x"]], + 0, + 0, + 100, + 100 + ] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1][1]", + "error": "Cubic bezier interpolation requires four numeric arguments with values between 0 and 1." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/interpolate/cubic-bezier-invalid-control-point/test.json b/shared/test/data/expression-tests/interpolate/cubic-bezier-invalid-control-point/test.json new file mode 100644 index 000000000..d61d2c096 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/cubic-bezier-invalid-control-point/test.json @@ -0,0 +1,26 @@ +{ + "expression": [ + "number", + [ + "interpolate", + ["cubic-bezier", 0, 1.75, 1, 1], + ["number", ["get", "x"]], + 0, + 0, + 100, + 100 + ] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1][1]", + "error": "Cubic bezier interpolation requires four numeric arguments with values between 0 and 1." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/interpolate/cubic-bezier/test.json b/shared/test/data/expression-tests/interpolate/cubic-bezier/test.json new file mode 100644 index 000000000..f723cc1f8 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/cubic-bezier/test.json @@ -0,0 +1,60 @@ +{ + "expression": [ + "number", + [ + "interpolate", + ["cubic-bezier", 0.42, 0, 0.58, 1], + ["number", ["get", "x"]], + 0, + 0, + 100, + 100 + ] + ], + "inputs": [ + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 10}}], + [{}, {"properties": {"x": 20}}], + [{}, {"properties": {"x": 30}}], + [{}, {"properties": {"x": 40}}], + [{}, {"properties": {"x": 50}}], + [{}, {"properties": {"x": 60}}], + [{}, {"properties": {"x": 70}}], + [{}, {"properties": {"x": 80}}], + [{}, {"properties": {"x": 90}}], + [{}, {"properties": {"x": 100}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 0, + 1.97224, + 8.16597, + 18.7395, + 33.1883, + 50, + 66.8116, + 81.2604, + 91.834, + 98.0277, + 100 + ], + "serialized": [ + "number", + [ + "interpolate", + ["cubic-bezier", 0.42, 0, 0.58, 1], + ["number", ["get", "x"]], + 0, + 0, + 100, + 100 + ] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/duplicate_stops/test.json b/shared/test/data/expression-tests/interpolate/duplicate_stops/test.json new file mode 100644 index 000000000..00888d775 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/duplicate_stops/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["interpolate", ["linear"], 0, 0, 1, 0, 2], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[5]", + "error": "Input/output pairs for \"interpolate\" expressions must be arranged with input values in strictly ascending order." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/interpolate/exponential-number-array/test.json b/shared/test/data/expression-tests/interpolate/exponential-number-array/test.json new file mode 100644 index 000000000..ee6b64ef5 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/exponential-number-array/test.json @@ -0,0 +1,36 @@ +{ + "expression": [ + "interpolate", + ["exponential", 2], + ["number", ["get", "x"]], + 1, + ["literal", [2, 1]], + 3, + ["literal", [6, 1]] + ], + "inputs": [ + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 2}}], + [{}, {"properties": {"x": 3}}], + [{}, {"properties": {"x": 4}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[2, 1], [2, 1], [3.33333, 1], [6, 1], [6, 1]], + "serialized": [ + "interpolate", + ["exponential", 2], + ["number", ["get", "x"]], + 1, + ["literal", [2, 1]], + 3, + ["literal", [6, 1]] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/exponential-single-stop/test.json b/shared/test/data/expression-tests/interpolate/exponential-single-stop/test.json new file mode 100644 index 000000000..68d35ef0d --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/exponential-single-stop/test.json @@ -0,0 +1,24 @@ +{ + "expression": [ + "number", + ["interpolate", ["exponential", 2], ["number", ["get", "x"]], 1, 2] + ], + "inputs": [ + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 2}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [2, 2, 2], + "serialized": [ + "number", + ["interpolate", ["exponential", 2], ["number", ["get", "x"]], 1, 2] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/exponential-string-array/test.json b/shared/test/data/expression-tests/interpolate/exponential-string-array/test.json new file mode 100644 index 000000000..10fac5af7 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/exponential-string-array/test.json @@ -0,0 +1,20 @@ +{ + "expression": [ + "interpolate", + ["exponential", 2], + ["number", ["get", "x"]], + 1, + ["literal", ["a"]], + 3, + ["literal", ["b"]] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Type array is not interpolatable."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/interpolate/exponential-uninterpolatable-numeric-array/test.json b/shared/test/data/expression-tests/interpolate/exponential-uninterpolatable-numeric-array/test.json new file mode 100644 index 000000000..5e9ed776c --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/exponential-uninterpolatable-numeric-array/test.json @@ -0,0 +1,20 @@ +{ + "expression": [ + "interpolate", + ["exponential", 2], + ["number", ["get", "x"]], + 1, + ["array", "number", ["get", "array"]], + 3, + ["array", "number", ["get", "array_two"]] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Type array is not interpolatable."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/interpolate/exponential/test.json b/shared/test/data/expression-tests/interpolate/exponential/test.json new file mode 100644 index 000000000..7db09899f --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/exponential/test.json @@ -0,0 +1,26 @@ +{ + "expression": [ + "number", + ["interpolate", ["exponential", 2], ["number", ["get", "x"]], 1, 2, 3, 6] + ], + "inputs": [ + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 2}}], + [{}, {"properties": {"x": 3}}], + [{}, {"properties": {"x": 4}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [2, 2, 3.33333, 6, 6], + "serialized": [ + "number", + ["interpolate", ["exponential", 2], ["number", ["get", "x"]], 1, 2, 3, 6] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/infer-array-type/test.json b/shared/test/data/expression-tests/interpolate/infer-array-type/test.json new file mode 100644 index 000000000..fa2b0ad14 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/infer-array-type/test.json @@ -0,0 +1,32 @@ +{ + "propertySpec": { + "type": "array", + "value": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": [ + "step", + ["number", ["get", "x"]], + ["literal", ["one"]], + 10, + ["literal", ["one", "two"]] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [], + "serialized": [ + "step", + ["number", ["get", "x"]], + ["literal", ["one"]], + 10, + ["literal", ["one", "two"]] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/linear-color/test.json b/shared/test/data/expression-tests/interpolate/linear-color/test.json new file mode 100644 index 000000000..39cb7bcc3 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/linear-color/test.json @@ -0,0 +1,46 @@ +{ + "expression": [ + "to-rgba", + [ + "interpolate", + ["exponential", 1], + ["get", "x"], + 1, + "red", + 11, + ["get", "color"] + ] + ], + "inputs": [ + [{}, {"properties": {"x": 0, "color": "blue"}}], + [{}, {"properties": {"x": 5, "color": "blue"}}], + [{}, {"properties": {"x": 11, "color": "blue"}}], + [{}, {"properties": {"x": 11, "color": "oops blue"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + [255, 0, 0, 1], + [153, 0, 102, 1], + [0, 0, 255, 1], + {"error": "Could not parse color from value 'oops blue'"} + ], + "serialized": [ + "to-rgba", + [ + "interpolate", + ["linear"], + ["number", ["get", "x"]], + 1, + ["rgba", 255, 0, 0, 1], + 11, + ["to-color", ["get", "color"]] + ] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/linear-many-stops/test.json b/shared/test/data/expression-tests/interpolate/linear-many-stops/test.json new file mode 100644 index 000000000..cd54491e5 --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/linear-many-stops/test.json @@ -0,0 +1,104 @@ +{ + "expression": [ + "number", + [ + "interpolate", + ["exponential", 1], + ["number", ["get", "x"]], + 2, + 100, + 55, + 200, + 132, + 300, + 607, + 400, + 1287, + 500, + 1985, + 600, + 2650, + 700, + 3299, + 800, + 3995, + 900, + 4927, + 1000, + 7147, + 10000, + 10028, + 100000, + 12889, + 1000000, + 40000, + 10000000 + ] + ], + "inputs": [ + [{}, {"properties": {"x": 2}}], + [{}, {"properties": {"x": 20}}], + [{}, {"properties": {"x": 607}}], + [{}, {"properties": {"x": 680}}], + [{}, {"properties": {"x": 4927}}], + [{}, {"properties": {"x": 7300}}], + [{}, {"properties": {"x": 10000}}], + [{}, {"properties": {"x": 20000}}], + [{}, {"properties": {"x": 40000}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 100, + 133.962, + 400, + 410.735, + 1000, + 14779.5, + 99125.3, + 3360628, + 10000000 + ], + "serialized": [ + "number", + [ + "interpolate", + ["linear"], + ["number", ["get", "x"]], + 2, + 100, + 55, + 200, + 132, + 300, + 607, + 400, + 1287, + 500, + 1985, + 600, + 2650, + 700, + 3299, + 800, + 3995, + 900, + 4927, + 1000, + 7147, + 10000, + 10028, + 100000, + 12889, + 1000000, + 40000, + 10000000 + ] + ] + } +} diff --git a/shared/test/data/expression-tests/interpolate/linear/test.json b/shared/test/data/expression-tests/interpolate/linear/test.json new file mode 100644 index 000000000..e23ff29bf --- /dev/null +++ b/shared/test/data/expression-tests/interpolate/linear/test.json @@ -0,0 +1,43 @@ +{ + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["interpolate", ["linear"], ["get", "x"], 0, 100, 10, 200], + "inputs": [ + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 5}}], + [{}, {"properties": {"x": 10}}], + [{}, {"properties": {"x": -1234}}], + [{}, {"properties": {"x": 1234}}], + [{}, {"properties": {"x": "abcd"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 100, + 150, + 200, + 100, + 200, + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate", + ["linear"], + ["number", ["get", "x"]], + 0, + 100, + 10, + 200 + ] + } +} diff --git a/shared/test/data/expression-tests/is-supported-script/default/test.json b/shared/test/data/expression-tests/is-supported-script/default/test.json new file mode 100644 index 000000000..55c098868 --- /dev/null +++ b/shared/test/data/expression-tests/is-supported-script/default/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["is-supported-script", ["get", "x"]], + "description": "'is-supported-script' always returns true when run without global context providing an 'isSupportedScript' function (as in the expression tests). The 'is-supported-script' render tests provide the necessary global context and exercise the functionality.", + "inputs": [ + [{}, {"properties": {"x": "שָׁלוֹם"}}], + [{}, {"properties": {"x": "देवनागरी"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true], + "serialized": ["is-supported-script", ["string", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/array-default/test.json b/shared/test/data/expression-tests/legacy/categorical/array-default/test.json new file mode 100644 index 000000000..5914ac934 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/array-default/test.json @@ -0,0 +1,39 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [[0, [0]], [1, [1]]], + "default": [-1] + }, + "propertySpec": { + "type": "array", + "value": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[-1], [0], [1], [-1], [-1]], + "serialized": [ + "match", + ["get", "p"], + 0, + ["literal", [0]], + 1, + ["literal", [1]], + ["literal", [-1]] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/array/test.json b/shared/test/data/expression-tests/legacy/categorical/array/test.json new file mode 100644 index 000000000..f61226de8 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/array/test.json @@ -0,0 +1,39 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [[0, [0]], [1, [1]]] + }, + "propertySpec": { + "type": "array", + "value": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]}, + "default": [-1] + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[-1], [0], [1], [-1], [-1]], + "serialized": [ + "match", + ["get", "p"], + 0, + ["literal", [0]], + 1, + ["literal", [1]], + ["literal", [-1]] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/boolean-default/test.json b/shared/test/data/expression-tests/legacy/categorical/boolean-default/test.json new file mode 100644 index 000000000..c7c8d866e --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/boolean-default/test.json @@ -0,0 +1,36 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [[true, true], [false, false]], + "default": true + }, + "propertySpec": { + "type": "boolean", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": true}}], + [{}, {"properties": {"p": false}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false, true], + "serialized": [ + "case", + ["==", ["get", "p"], true], + true, + ["==", ["get", "p"], false], + false, + true + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/boolean/test.json b/shared/test/data/expression-tests/legacy/categorical/boolean/test.json new file mode 100644 index 000000000..df84076f0 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/boolean/test.json @@ -0,0 +1,36 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [[true, true], [false, false]] + }, + "propertySpec": { + "type": "boolean", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]}, + "default": true + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": true}}], + [{}, {"properties": {"p": false}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false, true], + "serialized": [ + "case", + ["==", ["get", "p"], true], + true, + ["==", ["get", "p"], false], + false, + true + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/color-default/test.json b/shared/test/data/expression-tests/legacy/categorical/color-default/test.json new file mode 100644 index 000000000..33e72370d --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/color-default/test.json @@ -0,0 +1,37 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [["0", "red"], ["1", "lime"]], + "default": "blue" + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "0"}}], + [{}, {"properties": {"p": "1"}}], + [{}, {"properties": {"p": 0}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[0, 0, 1, 1], [1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1]], + "serialized": [ + "match", + ["get", "p"], + "0", + ["rgba", 255, 0, 0, 1], + "1", + ["rgba", 0, 255, 0, 1], + ["rgba", 0, 0, 255, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/color/test.json b/shared/test/data/expression-tests/legacy/categorical/color/test.json new file mode 100644 index 000000000..54c9e001a --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/color/test.json @@ -0,0 +1,37 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [["0", "red"], ["1", "lime"]] + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]}, + "default": "blue" + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "0"}}], + [{}, {"properties": {"p": "1"}}], + [{}, {"properties": {"p": 0}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[0, 0, 1, 1], [1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1]], + "serialized": [ + "match", + ["get", "p"], + "0", + ["rgba", 255, 0, 0, 1], + "1", + ["rgba", 0, 255, 0, 1], + ["rgba", 0, 0, 255, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/number-default/test.json b/shared/test/data/expression-tests/legacy/categorical/number-default/test.json new file mode 100644 index 000000000..09c9a2d4a --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/number-default/test.json @@ -0,0 +1,31 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [[0, 0], [1, 1]], + "default": -1 + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-1, -1, 0, 1, -1, -1], + "serialized": ["match", ["get", "p"], 0, 0, 1, 1, -1] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/number/test.json b/shared/test/data/expression-tests/legacy/categorical/number/test.json new file mode 100644 index 000000000..53c63247a --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/number/test.json @@ -0,0 +1,31 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [[0, 0], [1, 1]] + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]}, + "default": -1 + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-1, -1, 0, 1, -1, -1], + "serialized": ["match", ["get", "p"], 0, 0, 1, 1, -1] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/string-default/test.json b/shared/test/data/expression-tests/legacy/categorical/string-default/test.json new file mode 100644 index 000000000..98cf34d5c --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/string-default/test.json @@ -0,0 +1,29 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [["0", "0"], ["1", "1"]], + "default": "-1" + }, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "0"}}], + [{}, {"properties": {"p": "1"}}], + [{}, {"properties": {"p": 0}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["-1", "0", "1", "-1"], + "serialized": ["match", ["get", "p"], "0", "0", "1", "1", "-1"] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/string/test.json b/shared/test/data/expression-tests/legacy/categorical/string/test.json new file mode 100644 index 000000000..938b6102b --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/string/test.json @@ -0,0 +1,29 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [["0", "0"], ["1", "1"]] + }, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]}, + "default": "-1" + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "0"}}], + [{}, {"properties": {"p": "1"}}], + [{}, {"properties": {"p": 0}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["-1", "0", "1", "-1"], + "serialized": ["match", ["get", "p"], "0", "0", "1", "1", "-1"] + } +} diff --git a/shared/test/data/expression-tests/legacy/categorical/tokens/test.json b/shared/test/data/expression-tests/legacy/categorical/tokens/test.json new file mode 100644 index 000000000..bef9f23ca --- /dev/null +++ b/shared/test/data/expression-tests/legacy/categorical/tokens/test.json @@ -0,0 +1,30 @@ +{ + "expression": { + "type": "categorical", + "property": "p", + "stops": [["0", "0 {a}"], ["1", "1 {b}"]], + "default": "default" + }, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]}, + "tokens": true + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "0", "a": "a"}}], + [{}, {"properties": {"p": "1", "b": "b"}}], + [{}, {"properties": {"p": 0}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["default", "0 {a}", "1 {b}", "default"], + "serialized": ["match", ["get", "p"], "0", "0 {a}", "1", "1 {b}", "default"] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/array-default/test.json b/shared/test/data/expression-tests/legacy/exponential/array-default/test.json new file mode 100644 index 000000000..7b867c046 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/array-default/test.json @@ -0,0 +1,47 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, [0]], [1, [1]]], + "default": [-1] + }, + "propertySpec": { + "type": "array", + "value": "number", + "length": 1, + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[-1], [0], [0], [0.5], [1], [1], [-1]], + "serialized": [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + [ + "interpolate", + ["linear"], + ["number", ["get", "p"]], + 0, + ["literal", [0]], + 1, + ["literal", [1]] + ], + ["literal", [-1]] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/array/test.json b/shared/test/data/expression-tests/legacy/exponential/array/test.json new file mode 100644 index 000000000..8ac806db1 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/array/test.json @@ -0,0 +1,51 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, [0]], [1, [1]]] + }, + "propertySpec": { + "type": "array", + "value": "number", + "length": 1, + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + [0], + [0], + [0.5], + [1], + [1], + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate", + ["linear"], + ["number", ["get", "p"]], + 0, + ["literal", [0]], + 1, + ["literal", [1]] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/base/test.json b/shared/test/data/expression-tests/legacy/exponential/base/test.json new file mode 100644 index 000000000..43018f48b --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/base/test.json @@ -0,0 +1,19 @@ +{ + "expression": {"type": "exponential", "base": 0.5, "stops": [[0, 0], [1, 1]]}, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [[{"zoom": 0.5}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [0.585786], + "serialized": ["interpolate", ["exponential", 0.5], ["zoom"], 0, 0, 1, 1] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/color-default/test.json b/shared/test/data/expression-tests/legacy/exponential/color-default/test.json new file mode 100644 index 000000000..c3e353725 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/color-default/test.json @@ -0,0 +1,53 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, "black"], [1, "white"]], + "default": "red" + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [1, 0, 0, 1], + [0, 0, 0, 1], + [0, 0, 0, 1], + [0.5, 0.5, 0.5, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + [1, 0, 0, 1] + ], + "serialized": [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + [ + "interpolate", + ["linear"], + ["number", ["get", "p"]], + 0, + ["rgba", 0, 0, 0, 1], + 1, + ["rgba", 255, 255, 255, 1] + ], + ["rgba", 255, 0, 0, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/color-hcl/test.json b/shared/test/data/expression-tests/legacy/exponential/color-hcl/test.json new file mode 100644 index 000000000..58fdc2497 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/color-hcl/test.json @@ -0,0 +1,50 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, "black"], [1, "white"]], + "colorSpace": "hcl" + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + [0, 0, 0, 1], + [0, 0, 0, 1], + [0.5, 0.5, 0.499999, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate-hcl", + ["linear"], + ["number", ["get", "p"]], + 0, + ["rgba", 0, 0, 0, 1], + 1, + ["rgba", 255, 255, 255, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/color-lab/test.json b/shared/test/data/expression-tests/legacy/exponential/color-lab/test.json new file mode 100644 index 000000000..60ae68cdd --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/color-lab/test.json @@ -0,0 +1,50 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, "black"], [1, "white"]], + "colorSpace": "lab" + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + [0, 0, 0, 1], + [0, 0, 0, 1], + [0.499999, 0.5, 0.499999, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate-lab", + ["linear"], + ["number", ["get", "p"]], + 0, + ["rgba", 0, 0, 0, 1], + 1, + ["rgba", 255, 255, 255, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/color/test.json b/shared/test/data/expression-tests/legacy/exponential/color/test.json new file mode 100644 index 000000000..bbc8f6ecd --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/color/test.json @@ -0,0 +1,49 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, "black"], [1, "white"]] + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + [0, 0, 0, 1], + [0, 0, 0, 1], + [0.5, 0.5, 0.5, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate", + ["linear"], + ["number", ["get", "p"]], + 0, + ["rgba", 0, 0, 0, 1], + 1, + ["rgba", 255, 255, 255, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/composite-default/test.json b/shared/test/data/expression-tests/legacy/exponential/composite-default/test.json new file mode 100644 index 000000000..f6b66e77c --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/composite-default/test.json @@ -0,0 +1,55 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [ + [{"zoom": 0, "value": 0}, 0], + [{"zoom": 0, "value": 1}, 1], + [{"zoom": 1, "value": 0}, 2], + [{"zoom": 1, "value": 1}, 3] + ], + "default": -1 + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{"zoom": 0.5}, {"properties": {}}], + [{"zoom": 0.5}, {"properties": {"p": -1}}], + [{"zoom": 0.5}, {"properties": {"p": 0}}], + [{"zoom": 0.5}, {"properties": {"p": 0.5}}], + [{"zoom": 0.5}, {"properties": {"p": 1}}], + [{"zoom": 0.5}, {"properties": {"p": 2}}], + [{"zoom": 0.5}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [-1, 1, 1, 1.5, 2, 2, -1], + "serialized": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["interpolate", ["linear"], ["number", ["get", "p"]], 0, 0, 1, 1], + -1 + ], + 1, + [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["interpolate", ["linear"], ["number", ["get", "p"]], 0, 2, 1, 3], + -1 + ] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/composite/test.json b/shared/test/data/expression-tests/legacy/exponential/composite/test.json new file mode 100644 index 000000000..a032a0849 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/composite/test.json @@ -0,0 +1,54 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [ + [{"zoom": 0, "value": 0}, 0], + [{"zoom": 0, "value": 1}, 1], + [{"zoom": 1, "value": 0}, 2], + [{"zoom": 1, "value": 1}, 3] + ] + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{"zoom": 0.5}, {"properties": {}}], + [{"zoom": 0.5}, {"properties": {"p": -1}}], + [{"zoom": 0.5}, {"properties": {"p": 0}}], + [{"zoom": 0.5}, {"properties": {"p": 0.5}}], + [{"zoom": 0.5}, {"properties": {"p": 1}}], + [{"zoom": 0.5}, {"properties": {"p": 2}}], + [{"zoom": 0.5}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + 1, + 1, + 1.5, + 2, + 2, + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["interpolate", ["linear"], ["number", ["get", "p"]], 0, 0, 1, 1], + 1, + ["interpolate", ["linear"], ["number", ["get", "p"]], 0, 2, 1, 3] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/duplicate-stops/test.json b/shared/test/data/expression-tests/legacy/exponential/duplicate-stops/test.json new file mode 100644 index 000000000..af8e8f833 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/duplicate-stops/test.json @@ -0,0 +1,22 @@ +{ + "expression": { + "type": "exponential", + "stops": [[0, 10], [1, 20], [1, 25], [2, 30]] + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [[{"zoom": 1}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [20], + "serialized": ["interpolate", ["linear"], ["zoom"], 0, 10, 1, 20, 2, 30] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/implicit/test.json b/shared/test/data/expression-tests/legacy/exponential/implicit/test.json new file mode 100644 index 000000000..236c99d44 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/implicit/test.json @@ -0,0 +1,45 @@ +{ + "expression": {"property": "p", "stops": [[0, 0], [1, 1]]}, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + 0, + 0, + 0.5, + 1, + 1, + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate", + ["linear"], + ["number", ["get", "p"]], + 0, + 0, + 1, + 1 + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/number-default/test.json b/shared/test/data/expression-tests/legacy/exponential/number-default/test.json new file mode 100644 index 000000000..2441c6da3 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/number-default/test.json @@ -0,0 +1,37 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, 0], [1, 1]], + "default": -1 + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-1, 0, 0, 0.5, 1, 1, -1], + "serialized": [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["interpolate", ["linear"], ["number", ["get", "p"]], 0, 0, 1, 1], + -1 + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/exponential/number/test.json b/shared/test/data/expression-tests/legacy/exponential/number/test.json new file mode 100644 index 000000000..5287be633 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/exponential/number/test.json @@ -0,0 +1,49 @@ +{ + "expression": { + "type": "exponential", + "property": "p", + "stops": [[0, 0], [1, 1]] + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + 0, + 0, + 0.5, + 1, + 1, + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "interpolate", + ["linear"], + ["number", ["get", "p"]], + 0, + 0, + 1, + 1 + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/array-default/test.json b/shared/test/data/expression-tests/legacy/identity/array-default/test.json new file mode 100644 index 000000000..8e8f62829 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/array-default/test.json @@ -0,0 +1,25 @@ +{ + "expression": {"type": "identity", "property": "p", "default": [-1]}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": [0]}}], + [{}, {"properties": {"p": [1]}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "propertySpec": { + "type": "array", + "value": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[-1], [0], [1], [-1]], + "serialized": ["array", "number", null, ["get", "p"], ["literal", [-1]]] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/array/test.json b/shared/test/data/expression-tests/legacy/identity/array/test.json new file mode 100644 index 000000000..40c71deb9 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/array/test.json @@ -0,0 +1,34 @@ +{ + "expression": {"type": "identity", "property": "p"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": [0]}}], + [{}, {"properties": {"p": [1]}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "propertySpec": { + "type": "array", + "value": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + { + "error": "Expected value to be of type array, but found null instead." + }, + [0], + [1], + { + "error": "Expected value to be of type array, but found string instead." + } + ], + "serialized": ["array", "number", ["get", "p"]] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/boolean-default/test.json b/shared/test/data/expression-tests/legacy/identity/boolean-default/test.json new file mode 100644 index 000000000..05d420cc8 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/boolean-default/test.json @@ -0,0 +1,24 @@ +{ + "expression": {"type": "identity", "property": "p", "default": true}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": true}}], + [{}, {"properties": {"p": false}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "propertySpec": { + "type": "boolean", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false, true], + "serialized": ["boolean", ["get", "p"], true] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/boolean/test.json b/shared/test/data/expression-tests/legacy/identity/boolean/test.json new file mode 100644 index 000000000..0fcc53f98 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/boolean/test.json @@ -0,0 +1,33 @@ +{ + "expression": {"type": "identity", "property": "p"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": true}}], + [{}, {"properties": {"p": false}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "propertySpec": { + "type": "boolean", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + { + "error": "Expected value to be of type boolean, but found null instead." + }, + true, + false, + { + "error": "Expected value to be of type boolean, but found string instead." + } + ], + "serialized": ["boolean", ["get", "p"]] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/color-default/test.json b/shared/test/data/expression-tests/legacy/identity/color-default/test.json new file mode 100644 index 000000000..26e0f75f9 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/color-default/test.json @@ -0,0 +1,23 @@ +{ + "expression": {"type": "identity", "property": "p", "default": "red"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "blue"}}], + [{}, {"properties": {"p": 0}}] + ], + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[1, 0, 0, 1], [0, 0, 1, 1], [1, 0, 0, 1]], + "serialized": ["to-color", ["get", "p"], "red"] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/color/test.json b/shared/test/data/expression-tests/legacy/identity/color/test.json new file mode 100644 index 000000000..8e612e0ba --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/color/test.json @@ -0,0 +1,27 @@ +{ + "expression": {"type": "identity", "property": "p"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "blue"}}], + [{}, {"properties": {"p": 0}}] + ], + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + {"error": "Could not parse color from value 'null'"}, + [0, 0, 1, 1], + {"error": "Could not parse color from value '0'"} + ], + "serialized": ["to-color", ["get", "p"]] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/enum-default/test.json b/shared/test/data/expression-tests/legacy/identity/enum-default/test.json new file mode 100644 index 000000000..a3dab4843 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/enum-default/test.json @@ -0,0 +1,31 @@ +{ + "expression": {"type": "identity", "property": "p", "default": "a"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "a"}}], + [{}, {"properties": {"p": "b"}}], + [{}, {"properties": {"p": "c"}}] + ], + "propertySpec": { + "type": "enum", + "values": {"a": {}, "b": {}}, + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["a", "a", "b", "a"], + "serialized": [ + "match", + ["get", "p"], + ["a", "b"], + ["string", ["get", "p"]], + "a" + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/enum/test.json b/shared/test/data/expression-tests/legacy/identity/enum/test.json new file mode 100644 index 000000000..28e39fd5c --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/enum/test.json @@ -0,0 +1,30 @@ +{ + "expression": {"type": "identity", "property": "p"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "a"}}], + [{}, {"properties": {"p": "b"}}], + [{}, {"properties": {"p": "c"}}] + ], + "propertySpec": { + "type": "enum", + "values": {"a": {}, "b": {}}, + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + {"error": "Expected value to be of type string, but found null instead."}, + "a", + "b", + "c" + ], + "serialized": ["string", ["get", "p"]] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/number-default/test.json b/shared/test/data/expression-tests/legacy/identity/number-default/test.json new file mode 100644 index 000000000..85a4d0559 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/number-default/test.json @@ -0,0 +1,24 @@ +{ + "expression": {"type": "identity", "property": "p", "default": -1}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-1, 0, 1, -1], + "serialized": ["number", ["get", "p"], -1] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/number/test.json b/shared/test/data/expression-tests/legacy/identity/number/test.json new file mode 100644 index 000000000..979775ab9 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/number/test.json @@ -0,0 +1,31 @@ +{ + "expression": {"type": "identity", "property": "p"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": "wrong type"}}] + ], + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + 0, + 1, + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": ["number", ["get", "p"]] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/string-default/test.json b/shared/test/data/expression-tests/legacy/identity/string-default/test.json new file mode 100644 index 000000000..9525ee5f0 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/string-default/test.json @@ -0,0 +1,24 @@ +{ + "expression": {"type": "identity", "property": "p", "default": "default"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "0"}}], + [{}, {"properties": {"p": "1"}}], + [{}, {"properties": {"p": 0}}] + ], + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["default", "0", "1", "default"], + "serialized": ["string", ["get", "p"], "default"] + } +} diff --git a/shared/test/data/expression-tests/legacy/identity/string/test.json b/shared/test/data/expression-tests/legacy/identity/string/test.json new file mode 100644 index 000000000..70b9ef126 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/identity/string/test.json @@ -0,0 +1,31 @@ +{ + "expression": {"type": "identity", "property": "p"}, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": "0"}}], + [{}, {"properties": {"p": "1"}}], + [{}, {"properties": {"p": 0}}] + ], + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + {"error": "Expected value to be of type string, but found null instead."}, + "0", + "1", + { + "error": "Expected value to be of type string, but found number instead." + } + ], + "serialized": ["string", ["get", "p"]] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/array-default/test.json b/shared/test/data/expression-tests/legacy/interval/array-default/test.json new file mode 100644 index 000000000..c79cec3c8 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/array-default/test.json @@ -0,0 +1,39 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, [0]], [1, [1]]], + "default": [-1] + }, + "propertySpec": { + "type": "array", + "value": "number", + "length": 1, + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[-1], [0], [0], [0], [1], [1], [-1]], + "serialized": [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["step", ["number", ["get", "p"]], ["literal", [0]], 1, ["literal", [1]]], + ["literal", [-1]] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/array/test.json b/shared/test/data/expression-tests/legacy/interval/array/test.json new file mode 100644 index 000000000..26c4fd020 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/array/test.json @@ -0,0 +1,49 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, [0]], [1, [1]]] + }, + "propertySpec": { + "type": "array", + "value": "number", + "length": 1, + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + [0], + [0], + [0], + [1], + [1], + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "step", + ["number", ["get", "p"]], + ["literal", [0]], + 1, + ["literal", [1]] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/color-default/test.json b/shared/test/data/expression-tests/legacy/interval/color-default/test.json new file mode 100644 index 000000000..fa41b1f05 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/color-default/test.json @@ -0,0 +1,51 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, "black"], [1, "white"]], + "default": "red" + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [1, 0, 0, 1], + [0, 0, 0, 1], + [0, 0, 0, 1], + [0, 0, 0, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + [1, 0, 0, 1] + ], + "serialized": [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + [ + "step", + ["number", ["get", "p"]], + ["rgba", 0, 0, 0, 1], + 1, + ["rgba", 255, 255, 255, 1] + ], + ["rgba", 255, 0, 0, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/color/test.json b/shared/test/data/expression-tests/legacy/interval/color/test.json new file mode 100644 index 000000000..79ecf03ec --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/color/test.json @@ -0,0 +1,47 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, "black"], [1, "white"]] + }, + "propertySpec": { + "type": "color", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + [0, 0, 0, 1], + [0, 0, 0, 1], + [0, 0, 0, 1], + [1, 1, 1, 1], + [1, 1, 1, 1], + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "step", + ["number", ["get", "p"]], + ["rgba", 0, 0, 0, 1], + 1, + ["rgba", 255, 255, 255, 1] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/composite-default/test.json b/shared/test/data/expression-tests/legacy/interval/composite-default/test.json new file mode 100644 index 000000000..f9ec014f5 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/composite-default/test.json @@ -0,0 +1,53 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [ + [{"zoom": 0, "value": 0}, 0], + [{"zoom": 0, "value": 1}, 1], + [{"zoom": 1, "value": 0}, 2], + [{"zoom": 1, "value": 1}, 3] + ], + "default": -1 + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{"zoom": 0.5}, {"properties": {}}], + [{"zoom": 0.5}, {"properties": {"p": -1}}], + [{"zoom": 0.5}, {"properties": {"p": 0}}], + [{"zoom": 0.5}, {"properties": {"p": 0.5}}], + [{"zoom": 0.5}, {"properties": {"p": 1}}], + [{"zoom": 0.5}, {"properties": {"p": 2}}], + [{"zoom": 0.5}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [-1, 0, 0, 0, 1, 1, -1], + "serialized": [ + "step", + ["zoom"], + [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["step", ["number", ["get", "p"]], 0, 1, 1], + -1 + ], + 1, + [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["step", ["number", ["get", "p"]], 2, 1, 3], + -1 + ] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/composite/test.json b/shared/test/data/expression-tests/legacy/interval/composite/test.json new file mode 100644 index 000000000..6b182fb65 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/composite/test.json @@ -0,0 +1,52 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [ + [{"zoom": 0, "value": 0}, 0], + [{"zoom": 0, "value": 1}, 1], + [{"zoom": 1, "value": 0}, 2], + [{"zoom": 1, "value": 1}, 3] + ] + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{"zoom": 0.5}, {"properties": {}}], + [{"zoom": 0.5}, {"properties": {"p": -1}}], + [{"zoom": 0.5}, {"properties": {"p": 0}}], + [{"zoom": 0.5}, {"properties": {"p": 0.5}}], + [{"zoom": 0.5}, {"properties": {"p": 1}}], + [{"zoom": 0.5}, {"properties": {"p": 2}}], + [{"zoom": 0.5}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + 0, + 0, + 0, + 1, + 1, + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": [ + "step", + ["zoom"], + ["step", ["number", ["get", "p"]], 0, 1, 1], + 1, + ["step", ["number", ["get", "p"]], 2, 1, 3] + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/duplicate-stops/test.json b/shared/test/data/expression-tests/legacy/interval/duplicate-stops/test.json new file mode 100644 index 000000000..b68507971 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/duplicate-stops/test.json @@ -0,0 +1,22 @@ +{ + "expression": { + "type": "interval", + "stops": [[0, "a"], [1, "b"], [1, "c"], [2, "d"]] + }, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [[{"zoom": 1}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": false, + "type": "string" + }, + "outputs": ["b"], + "serialized": ["step", ["zoom"], "a", 1, "b", 2, "d"] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/implicit/test.json b/shared/test/data/expression-tests/legacy/interval/implicit/test.json new file mode 100644 index 000000000..f8ce664b9 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/implicit/test.json @@ -0,0 +1,37 @@ +{ + "expression": {"property": "p", "stops": [[0, "0"], [1, "1"]]}, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": false, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + "0", + "0", + "0", + "1", + "1", + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": ["step", ["number", ["get", "p"]], "0", 1, "1"] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/number-default/test.json b/shared/test/data/expression-tests/legacy/interval/number-default/test.json new file mode 100644 index 000000000..0399bf124 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/number-default/test.json @@ -0,0 +1,37 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, 0], [1, 1]], + "default": -1 + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-1, 0, 0, 0, 1, 1, -1], + "serialized": [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["step", ["number", ["get", "p"]], 0, 1, 1], + -1 + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/number/test.json b/shared/test/data/expression-tests/legacy/interval/number/test.json new file mode 100644 index 000000000..d08ca7f4a --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/number/test.json @@ -0,0 +1,41 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, 0], [1, 1]] + }, + "propertySpec": { + "type": "number", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + 0, + 0, + 0, + 1, + 1, + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": ["step", ["number", ["get", "p"]], 0, 1, 1] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/string-default/test.json b/shared/test/data/expression-tests/legacy/interval/string-default/test.json new file mode 100644 index 000000000..259a0a1c6 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/string-default/test.json @@ -0,0 +1,37 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, "0"], [1, "1"]], + "default": "default" + }, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["default", "0", "0", "0", "1", "1", "default"], + "serialized": [ + "case", + ["==", ["typeof", ["get", "p"]], "number"], + ["step", ["number", ["get", "p"]], "0", 1, "1"], + "default" + ] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/string/test.json b/shared/test/data/expression-tests/legacy/interval/string/test.json new file mode 100644 index 000000000..91740cb15 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/string/test.json @@ -0,0 +1,41 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, "0"], [1, "1"]] + }, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]} + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": -1}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": 0.5}}], + [{}, {"properties": {"p": 1}}], + [{}, {"properties": {"p": 2}}], + [{}, {"properties": {"p": "0"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + "0", + "0", + "0", + "1", + "1", + { + "error": "Expected value to be of type number, but found string instead." + } + ], + "serialized": ["step", ["number", ["get", "p"]], "0", 1, "1"] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/tokens-property/test.json b/shared/test/data/expression-tests/legacy/interval/tokens-property/test.json new file mode 100644 index 000000000..1980dcbbe --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/tokens-property/test.json @@ -0,0 +1,34 @@ +{ + "expression": { + "type": "interval", + "property": "p", + "stops": [[0, "0 {a}"], [1, "1 {b}"]] + }, + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]}, + "tokens": true + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0, "a": "a"}}], + [{}, {"properties": {"p": 1, "b": "b"}}], + [{}, {"properties": {"p": 0}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."}, + "0 {a}", + "1 {b}", + "0 {a}" + ], + "serialized": ["step", ["number", ["get", "p"]], "0 {a}", 1, "1 {b}"] + } +} diff --git a/shared/test/data/expression-tests/legacy/interval/tokens-zoom/test.json b/shared/test/data/expression-tests/legacy/interval/tokens-zoom/test.json new file mode 100644 index 000000000..fed8f4f31 --- /dev/null +++ b/shared/test/data/expression-tests/legacy/interval/tokens-zoom/test.json @@ -0,0 +1,30 @@ +{ + "expression": {"type": "interval", "stops": [[0, "0 {a}"], [1, "{b}"]]}, + "inputs": [ + [{"zoom": 0}, {"properties": {"a": "a", "b": 2}}], + [{"zoom": 1}, {"properties": {"a": "a", "b": 2}}], + [{"zoom": 0}, {"properties": {}}] + ], + "propertySpec": { + "type": "string", + "property-type": "data-driven", + "expression": {"interpolated": true, "parameters": ["zoom", "feature"]}, + "tokens": true + }, + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": false, + "type": "string" + }, + "outputs": ["0 a", "2", "0 "], + "serialized": [ + "step", + ["zoom"], + ["concat", "0 ", ["get", "a"]], + 1, + ["to-string", ["get", "b"]] + ] + } +} diff --git a/shared/test/data/expression-tests/length/array/test.json b/shared/test/data/expression-tests/length/array/test.json new file mode 100644 index 000000000..29f67e730 --- /dev/null +++ b/shared/test/data/expression-tests/length/array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["length", ["array", ["get", "x"]]], + "inputs": [[{}, {"properties": {"x": [1, 2, 3, 4, 5]}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [5], + "serialized": ["length", ["array", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/length/implicit/test.json b/shared/test/data/expression-tests/length/implicit/test.json new file mode 100644 index 000000000..a2708af32 --- /dev/null +++ b/shared/test/data/expression-tests/length/implicit/test.json @@ -0,0 +1,24 @@ +{ + "expression": ["length", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": "a string"}}], + [{}, {"properties": {"x": []}}], + [{}, {"properties": {"x": 0}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 8, + 0, + { + "error": "Expected value to be of type string or array, but found number instead." + } + ], + "serialized": ["length", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/length/invalid/test.json b/shared/test/data/expression-tests/length/invalid/test.json new file mode 100644 index 000000000..3fedfc70a --- /dev/null +++ b/shared/test/data/expression-tests/length/invalid/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["length", 0], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Expected argument of type string or array, but found number instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/length/string/test.json b/shared/test/data/expression-tests/length/string/test.json new file mode 100644 index 000000000..bcbba9efe --- /dev/null +++ b/shared/test/data/expression-tests/length/string/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["length", ["string", ["get", "x"]]], + "inputs": [[{}, {"properties": {"x": "a string"}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [8], + "serialized": ["length", ["string", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/less/boolean/test.json b/shared/test/data/expression-tests/less/boolean/test.json new file mode 100644 index 000000000..731d6dbb7 --- /dev/null +++ b/shared/test/data/expression-tests/less/boolean/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["<", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\"<\" comparisons are not supported for type 'boolean'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/less/mismatch/test.json b/shared/test/data/expression-tests/less/mismatch/test.json new file mode 100644 index 000000000..c33f34fea --- /dev/null +++ b/shared/test/data/expression-tests/less/mismatch/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["<", ["string", ["get", "x"]], ["number", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot compare types 'string' and 'number'."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/less/null/test.json b/shared/test/data/expression-tests/less/null/test.json new file mode 100644 index 000000000..ac9a426fd --- /dev/null +++ b/shared/test/data/expression-tests/less/null/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["<", null, null], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\"<\" comparisons are not supported for type 'null'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/less/number/test.json b/shared/test/data/expression-tests/less/number/test.json new file mode 100644 index 000000000..efe025199 --- /dev/null +++ b/shared/test/data/expression-tests/less/number/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["<", ["number", ["get", "x"]], ["number", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": 1, "y": 1}}], + [{}, {"properties": {"x": 1, "y": 2}}], + [{}, {"properties": {"x": 2, "y": 1}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, false], + "serialized": ["<", ["number", ["get", "x"]], ["number", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/less/string-and-value/test.json b/shared/test/data/expression-tests/less/string-and-value/test.json new file mode 100644 index 000000000..1674ece37 --- /dev/null +++ b/shared/test/data/expression-tests/less/string-and-value/test.json @@ -0,0 +1,26 @@ +{ + "expression": ["<", ["string", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "2"}}], + [{}, {"properties": {"x": "1", "y": 2}}], + [{}, {"properties": {"x": 1, "y": "2"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + { + "error": "Expected value to be of type string, but found number instead." + }, + { + "error": "Expected value to be of type string, but found number instead." + } + ], + "serialized": ["<", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/less/string/test.json b/shared/test/data/expression-tests/less/string/test.json new file mode 100644 index 000000000..42f4fda59 --- /dev/null +++ b/shared/test/data/expression-tests/less/string/test.json @@ -0,0 +1,21 @@ +{ + "expression": ["<", ["string", ["get", "x"]], ["string", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": "2"}}], + [{}, {"properties": {"x": "2", "y": "1"}}], + [{}, {"properties": {"x": "abc", "y": "azz"}}], + [{}, {"properties": {"x": "abc", "y": "aaa"}}], + [{}, {"properties": {"x": "abc", "y": "abc"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, false, true, false, false], + "serialized": ["<", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/less/value/test.json b/shared/test/data/expression-tests/less/value/test.json new file mode 100644 index 000000000..1d12eb582 --- /dev/null +++ b/shared/test/data/expression-tests/less/value/test.json @@ -0,0 +1,28 @@ +{ + "expression": ["<", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "10", "y": "2"}}], + [{}, {"properties": {"x": 1, "y": 10}}], + [{}, {"properties": {"x": "1", "y": 1}}], + [{}, {"properties": {"x": 1, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + true, + { + "error": "Expected arguments for \"<\" to be (string, string) or (number, number), but found (string, number) instead." + }, + { + "error": "Expected arguments for \"<\" to be (string, string) or (number, number), but found (number, string) instead." + } + ], + "serialized": ["<", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/less_or_equal/boolean/test.json b/shared/test/data/expression-tests/less_or_equal/boolean/test.json new file mode 100644 index 000000000..1b657359e --- /dev/null +++ b/shared/test/data/expression-tests/less_or_equal/boolean/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["<=", ["boolean", ["get", "x"]], ["boolean", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\"<=\" comparisons are not supported for type 'boolean'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/less_or_equal/mismatch/test.json b/shared/test/data/expression-tests/less_or_equal/mismatch/test.json new file mode 100644 index 000000000..40e257af4 --- /dev/null +++ b/shared/test/data/expression-tests/less_or_equal/mismatch/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["<=", ["string", ["get", "x"]], ["number", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot compare types 'string' and 'number'."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/less_or_equal/null/test.json b/shared/test/data/expression-tests/less_or_equal/null/test.json new file mode 100644 index 000000000..c16be2ca7 --- /dev/null +++ b/shared/test/data/expression-tests/less_or_equal/null/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["<=", null, null], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "\"<=\" comparisons are not supported for type 'null'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/less_or_equal/number/test.json b/shared/test/data/expression-tests/less_or_equal/number/test.json new file mode 100644 index 000000000..e835843af --- /dev/null +++ b/shared/test/data/expression-tests/less_or_equal/number/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["<=", ["number", ["get", "x"]], ["number", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": 1, "y": 1}}], + [{}, {"properties": {"x": 1, "y": 2}}], + [{}, {"properties": {"x": 2, "y": 1}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false], + "serialized": ["<=", ["number", ["get", "x"]], ["number", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/less_or_equal/string-and-value/test.json b/shared/test/data/expression-tests/less_or_equal/string-and-value/test.json new file mode 100644 index 000000000..24b4fe682 --- /dev/null +++ b/shared/test/data/expression-tests/less_or_equal/string-and-value/test.json @@ -0,0 +1,26 @@ +{ + "expression": ["<", ["string", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": 1}}], + [{}, {"properties": {"x": 1, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + false, + { + "error": "Expected value to be of type string, but found number instead." + }, + { + "error": "Expected value to be of type string, but found number instead." + } + ], + "serialized": ["<", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/less_or_equal/string/test.json b/shared/test/data/expression-tests/less_or_equal/string/test.json new file mode 100644 index 000000000..d0692038e --- /dev/null +++ b/shared/test/data/expression-tests/less_or_equal/string/test.json @@ -0,0 +1,21 @@ +{ + "expression": ["<=", ["string", ["get", "x"]], ["string", ["get", "y"]]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": "2"}}], + [{}, {"properties": {"x": "2", "y": "1"}}], + [{}, {"properties": {"x": "abc", "y": "azz"}}], + [{}, {"properties": {"x": "abc", "y": "aaa"}}], + [{}, {"properties": {"x": "abc", "y": "abc"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true, true, false, true, false, true], + "serialized": ["<=", ["string", ["get", "x"]], ["string", ["get", "y"]]] + } +} diff --git a/shared/test/data/expression-tests/less_or_equal/value/test.json b/shared/test/data/expression-tests/less_or_equal/value/test.json new file mode 100644 index 000000000..71b3fe810 --- /dev/null +++ b/shared/test/data/expression-tests/less_or_equal/value/test.json @@ -0,0 +1,28 @@ +{ + "expression": ["<=", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "10", "y": "2"}}], + [{}, {"properties": {"x": 1, "y": 10}}], + [{}, {"properties": {"x": "1", "y": 1}}], + [{}, {"properties": {"x": 1, "y": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + true, + { + "error": "Expected arguments for \"<=\" to be (string, string) or (number, number), but found (string, number) instead." + }, + { + "error": "Expected arguments for \"<=\" to be (string, string) or (number, number), but found (number, string) instead." + } + ], + "serialized": ["<=", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/let/basic/test.json b/shared/test/data/expression-tests/let/basic/test.json new file mode 100644 index 000000000..9c6ba7073 --- /dev/null +++ b/shared/test/data/expression-tests/let/basic/test.json @@ -0,0 +1,28 @@ +{ + "expression": [ + "let", + "a", + ["number", ["get", "a"]], + "b", + ["number", ["get", "b"]], + ["+", ["+", ["var", "a"], ["var", "b"]], ["var", "a"]] + ], + "inputs": [[{}, {"properties": {"a": 1, "b": 2}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [4], + "serialized": [ + "let", + "a", + ["number", ["get", "a"]], + "b", + ["number", ["get", "b"]], + ["+", ["+", ["var", "a"], ["var", "b"]], ["var", "a"]] + ] + } +} diff --git a/shared/test/data/expression-tests/let/expected-value/test.json b/shared/test/data/expression-tests/let/expected-value/test.json new file mode 100644 index 000000000..157652e8d --- /dev/null +++ b/shared/test/data/expression-tests/let/expected-value/test.json @@ -0,0 +1,58 @@ +{ + "expression": [ + "let", + "density", + ["/", ["get", "population"], ["get", "sq-km"]], + [ + "interpolate", + ["linear"], + ["var", "density"], + 1, + "#000000", + 100, + "#ffffff" + ] + ], + "propertySpec": { + "type": "color" + }, + "description": "let should preserve expected type for child expressions. If the expected 'color' type in this test were not preserved, it would not get passed into the interpolation and the literal strings wouldn't automatically coerce to the 'color' type", + "inputs": [[{}, {"properties": {"population": 100, "sq-km": 10}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [0.09090909090909091,0.09090909090909091,0.09090909090909091,1] + ], + "serialized": [ + "let", + "density", + ["/", ["number", ["get", "population"]], ["number", ["get", "sq-km"]]], + [ + "interpolate", + ["linear"], + ["var", "density"], + 1, + [ + "rgba", + 0, + 0, + 0, + 1 + ], + 100, + [ + "rgba", + 255, + 255, + 255, + 1 + ] + ] + ] + } +} diff --git a/shared/test/data/expression-tests/let/invalid-name/test.json b/shared/test/data/expression-tests/let/invalid-name/test.json new file mode 100644 index 000000000..085d6897c --- /dev/null +++ b/shared/test/data/expression-tests/let/invalid-name/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["let", "$a", 1, ["var", "$a"]], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1]", + "error": "Variable names must contain only alphanumeric characters or '_'." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/let/nested/test.json b/shared/test/data/expression-tests/let/nested/test.json new file mode 100644 index 000000000..63909c547 --- /dev/null +++ b/shared/test/data/expression-tests/let/nested/test.json @@ -0,0 +1,24 @@ +{ + "expression": [ + "let", + "a", + ["number", ["get", "a"]], + ["let", "b", ["+", 1, ["var", "a"]], ["+", ["var", "a"], ["var", "b"]]] + ], + "inputs": [[{}, {"properties": {"a": 1}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [3], + "serialized": [ + "let", + "a", + ["number", ["get", "a"]], + ["let", "b", ["+", 1, ["var", "a"]], ["+", ["var", "a"], ["var", "b"]]] + ] + } +} diff --git a/shared/test/data/expression-tests/let/property-function/test.json b/shared/test/data/expression-tests/let/property-function/test.json new file mode 100644 index 000000000..4de97803e --- /dev/null +++ b/shared/test/data/expression-tests/let/property-function/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["let", "a", ["get", "x"], ["+", 1, ["number", ["var", "a"]]]], + "inputs": [[{}, {"properties": {"x": 5}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [6], + "serialized": ["let", "a", ["get", "x"], ["+", 1, ["number", ["var", "a"]]]] + } +} diff --git a/shared/test/data/expression-tests/let/shadow/test.json b/shared/test/data/expression-tests/let/shadow/test.json new file mode 100644 index 000000000..07ec40979 --- /dev/null +++ b/shared/test/data/expression-tests/let/shadow/test.json @@ -0,0 +1,24 @@ +{ + "expression": [ + "let", + "a", + ["get", "one"], + ["let", "a", ["get", "two"], ["var", "a"]] + ], + "inputs": [[{}, {"properties": {"one": 1, "two": 2}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": [2], + "serialized": [ + "let", + "a", + ["get", "one"], + ["let", "a", ["get", "two"], ["var", "a"]] + ] + } +} diff --git a/shared/test/data/expression-tests/let/unbound/test.json b/shared/test/data/expression-tests/let/unbound/test.json new file mode 100644 index 000000000..14d430ed3 --- /dev/null +++ b/shared/test/data/expression-tests/let/unbound/test.json @@ -0,0 +1,19 @@ +{ + "expression": [ + "let", + "a", + 1, + ["+", ["+", ["var", "a"], ["var", "b"]], ["var", "a"]] + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[3][1][2][1]", + "error": "Unknown variable \"b\". Make sure \"b\" has been bound in an enclosing \"let\" expression before using it." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/let/zoom/test.json b/shared/test/data/expression-tests/let/zoom/test.json new file mode 100644 index 000000000..7a34f6843 --- /dev/null +++ b/shared/test/data/expression-tests/let/zoom/test.json @@ -0,0 +1,44 @@ +{ + "expression": [ + "let", + "z0_value", + ["number", ["get", "a"]], + "z20_value", + ["number", ["get", "b"]], + [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["var", "z0_value"], + 20, + ["var", "z20_value"] + ] + ], + "inputs": [[{"zoom": 10}, {"properties": {"a": 10, "b": 30}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [20], + "serialized": [ + "let", + "z0_value", + ["number", ["get", "a"]], + "z20_value", + ["number", ["get", "b"]], + [ + "interpolate", + ["linear"], + ["zoom"], + 0, + ["var", "z0_value"], + 20, + ["var", "z20_value"] + ] + ] + } +} diff --git a/shared/test/data/expression-tests/literal/boolean-array/test.json b/shared/test/data/expression-tests/literal/boolean-array/test.json new file mode 100644 index 000000000..f9bedc9d2 --- /dev/null +++ b/shared/test/data/expression-tests/literal/boolean-array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["literal", [true, false]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[true, false]], + "serialized": ["literal", [true, false]] + } +} diff --git a/shared/test/data/expression-tests/literal/empty/test.json b/shared/test/data/expression-tests/literal/empty/test.json new file mode 100644 index 000000000..3f7255afa --- /dev/null +++ b/shared/test/data/expression-tests/literal/empty/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["literal"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "'literal' expression requires exactly one argument, but found 0 instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/literal/infer-empty-array-type/test.json b/shared/test/data/expression-tests/literal/infer-empty-array-type/test.json new file mode 100644 index 000000000..8ad21ba86 --- /dev/null +++ b/shared/test/data/expression-tests/literal/infer-empty-array-type/test.json @@ -0,0 +1,20 @@ +{ + "propertySpec": { + "type": "array", + "value": "number", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["literal", []], + "inputs": [], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [], + "serialized": ["literal", []] + } +} diff --git a/shared/test/data/expression-tests/literal/mixed-primitive-array/test.json b/shared/test/data/expression-tests/literal/mixed-primitive-array/test.json new file mode 100644 index 000000000..602763f84 --- /dev/null +++ b/shared/test/data/expression-tests/literal/mixed-primitive-array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["literal", [1, "2"]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[1, "2"]], + "serialized": ["literal", [1, "2"]] + } +} diff --git a/shared/test/data/expression-tests/literal/multiple-args/test.json b/shared/test/data/expression-tests/literal/multiple-args/test.json new file mode 100644 index 000000000..922cd2701 --- /dev/null +++ b/shared/test/data/expression-tests/literal/multiple-args/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["literal", {}, []], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "'literal' expression requires exactly one argument, but found 2 instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/literal/nested-array/test.json b/shared/test/data/expression-tests/literal/nested-array/test.json new file mode 100644 index 000000000..1cdf9fde0 --- /dev/null +++ b/shared/test/data/expression-tests/literal/nested-array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["literal", [1, [3, 4]]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[1, [3, 4]]], + "serialized": ["literal", [1, [3, 4]]] + } +} diff --git a/shared/test/data/expression-tests/literal/number-array/test.json b/shared/test/data/expression-tests/literal/number-array/test.json new file mode 100644 index 000000000..c68af83e0 --- /dev/null +++ b/shared/test/data/expression-tests/literal/number-array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["literal", [1, 2]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[1, 2]], + "serialized": ["literal", [1, 2]] + } +} diff --git a/shared/test/data/expression-tests/literal/object/test.json b/shared/test/data/expression-tests/literal/object/test.json new file mode 100644 index 000000000..d273a9129 --- /dev/null +++ b/shared/test/data/expression-tests/literal/object/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["literal", {"x": 1}], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "object" + }, + "outputs": [{"x": 1}], + "serialized": ["literal", {"x": 1}] + } +} diff --git a/shared/test/data/expression-tests/literal/string-array/test.json b/shared/test/data/expression-tests/literal/string-array/test.json new file mode 100644 index 000000000..f6f8845b7 --- /dev/null +++ b/shared/test/data/expression-tests/literal/string-array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["literal", ["1", "2"]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [["1", "2"]], + "serialized": ["literal", ["1", "2"]] + } +} diff --git a/shared/test/data/expression-tests/literal/string/test.json b/shared/test/data/expression-tests/literal/string/test.json new file mode 100644 index 000000000..510dd85b8 --- /dev/null +++ b/shared/test/data/expression-tests/literal/string/test.json @@ -0,0 +1,14 @@ +{ + "expression": "ahoy!", + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["ahoy!"], + "serialized": "ahoy!" + } +} diff --git a/shared/test/data/expression-tests/literal/u2028u2029/test.json b/shared/test/data/expression-tests/literal/u2028u2029/test.json new file mode 100644 index 000000000..3818f9ad7 --- /dev/null +++ b/shared/test/data/expression-tests/literal/u2028u2029/test.json @@ -0,0 +1,14 @@ +{ + "expression": "ah\u2028\u2029oy!", + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["ah\u2028\u2029oy!"], + "serialized": "ah\u2028\u2029oy!" + } +} diff --git a/shared/test/data/expression-tests/ln/basic/test.json b/shared/test/data/expression-tests/ln/basic/test.json new file mode 100644 index 000000000..e96e292e6 --- /dev/null +++ b/shared/test/data/expression-tests/ln/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["ln", ["e"]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1], + "serialized": 1 + } +} diff --git a/shared/test/data/expression-tests/ln2/basic/test.json b/shared/test/data/expression-tests/ln2/basic/test.json new file mode 100644 index 000000000..655ea41cd --- /dev/null +++ b/shared/test/data/expression-tests/ln2/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["ln2"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0.693147], + "serialized": 0.6931471805599453 + } +} diff --git a/shared/test/data/expression-tests/log10/basic/test.json b/shared/test/data/expression-tests/log10/basic/test.json new file mode 100644 index 000000000..6ed428ed9 --- /dev/null +++ b/shared/test/data/expression-tests/log10/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["log10", 100], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [2], + "serialized": 2 + } +} diff --git a/shared/test/data/expression-tests/log2/basic/test.json b/shared/test/data/expression-tests/log2/basic/test.json new file mode 100644 index 000000000..db0af445b --- /dev/null +++ b/shared/test/data/expression-tests/log2/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["log2", 1024], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [10], + "serialized": 10 + } +} diff --git a/shared/test/data/expression-tests/match/arity-0/test.json b/shared/test/data/expression-tests/match/arity-0/test.json new file mode 100644 index 000000000..2a2822b16 --- /dev/null +++ b/shared/test/data/expression-tests/match/arity-0/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["match"], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Expected at least 4 arguments, but found only 0."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/arity-1/test.json b/shared/test/data/expression-tests/match/arity-1/test.json new file mode 100644 index 000000000..5b0ddcc0d --- /dev/null +++ b/shared/test/data/expression-tests/match/arity-1/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["match", "x"], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Expected at least 4 arguments, but found only 1."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/arity-2/test.json b/shared/test/data/expression-tests/match/arity-2/test.json new file mode 100644 index 000000000..07ba0590c --- /dev/null +++ b/shared/test/data/expression-tests/match/arity-2/test.json @@ -0,0 +1,12 @@ +{ + "expression": ["match", "x", "y"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Expected at least 4 arguments, but found only 2."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/arity-3/test.json b/shared/test/data/expression-tests/match/arity-3/test.json new file mode 100644 index 000000000..4c7fb31cc --- /dev/null +++ b/shared/test/data/expression-tests/match/arity-3/test.json @@ -0,0 +1,12 @@ +{ + "expression": ["match", "x", "y", "z"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Expected at least 4 arguments, but found only 3."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/basic/test.json b/shared/test/data/expression-tests/match/basic/test.json new file mode 100644 index 000000000..266eacdb3 --- /dev/null +++ b/shared/test/data/expression-tests/match/basic/test.json @@ -0,0 +1,28 @@ +{ + "expression": ["match", ["get", "x"], "a", "Apple", "b", "Banana", "Kumquat"], + "inputs": [ + [{}, {"properties": {"x": "a"}}], + [{}, {"properties": {"x": "b"}}], + [{}, {"properties": {"x": "c"}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["Apple", "Banana", "Kumquat", "Kumquat", "Kumquat"], + "serialized": [ + "match", + ["get", "x"], + "a", + "Apple", + "b", + "Banana", + "Kumquat" + ] + } +} diff --git a/shared/test/data/expression-tests/match/empty-case/test.json b/shared/test/data/expression-tests/match/empty-case/test.json new file mode 100644 index 000000000..61c7ba21d --- /dev/null +++ b/shared/test/data/expression-tests/match/empty-case/test.json @@ -0,0 +1,9 @@ +{ + "expression": ["match", ["get", "x"], [], "thing one", "thing two"], + "expected": { + "compiled": { + "result": "error", + "errors": [{"key": "[2]", "error": "Expected at least one branch label."}] + } + } +} diff --git a/shared/test/data/expression-tests/match/infer-array-type/test.json b/shared/test/data/expression-tests/match/infer-array-type/test.json new file mode 100644 index 000000000..2b1041fd3 --- /dev/null +++ b/shared/test/data/expression-tests/match/infer-array-type/test.json @@ -0,0 +1,36 @@ +{ + "propertySpec": { + "type": "array", + "value": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": [ + "match", + ["number", ["get", "x"]], + 0, + ["literal", ["one"]], + 10, + ["literal", ["one", "two"]], + ["literal", ["one", "two", "three"]] + ], + "inputs": [], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [], + "serialized": [ + "match", + ["number", ["get", "x"]], + 0, + ["literal", ["one"]], + 10, + ["literal", ["one", "two"]], + ["literal", ["one", "two", "three"]] + ] + } +} diff --git a/shared/test/data/expression-tests/match/label-array/test.json b/shared/test/data/expression-tests/match/label-array/test.json new file mode 100644 index 000000000..078d81657 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-array/test.json @@ -0,0 +1,17 @@ +{ + "expression": [ + "match", + "x", + ["string", ["get", "y"]], + "thing one", + "thing two" + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[2]", "error": "Branch labels must be numbers or strings."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/label-boolean/test.json b/shared/test/data/expression-tests/match/label-boolean/test.json new file mode 100644 index 000000000..5f5b0837e --- /dev/null +++ b/shared/test/data/expression-tests/match/label-boolean/test.json @@ -0,0 +1,25 @@ +{ + "expression": [ + "match", + ["boolean", ["get", "x"]], + true, + "match", + "otherwise" + ], + "inputs": [ + [{}, {"properties": {"x": true}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": "true"}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": null}}], + [{}, {"properties": {}}] + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[2]", "error": "Branch labels must be numbers or strings."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/label-non-integer/test.json b/shared/test/data/expression-tests/match/label-non-integer/test.json new file mode 100644 index 000000000..f89961f14 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-non-integer/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["match", 1, 1.5, "thing one", "thing two"], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[2]", "error": "Numeric branch labels must be integer values."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/label-null/test.json b/shared/test/data/expression-tests/match/label-null/test.json new file mode 100644 index 000000000..004cb8c75 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-null/test.json @@ -0,0 +1,12 @@ +{ + "expression": ["match", null, null, "match", "otherwise"], + "inputs": [[{}, {"properties": {}}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[2]", "error": "Branch labels must be numbers or strings."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/label-number/test.json b/shared/test/data/expression-tests/match/label-number/test.json new file mode 100644 index 000000000..2e1bad800 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-number/test.json @@ -0,0 +1,30 @@ +{ + "expression": ["match", ["get", "x"], 0, "match", "otherwise"], + "inputs": [ + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 0.5}}], + [{}, {"properties": {"x": "0"}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}], + [{}, {"properties": {}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "match", + "otherwise", + "otherwise", + "otherwise", + "otherwise", + "otherwise", + "otherwise" + ], + "serialized": ["match", ["get", "x"], 0, "match", "otherwise"] + } +} diff --git a/shared/test/data/expression-tests/match/label-object/test.json b/shared/test/data/expression-tests/match/label-object/test.json new file mode 100644 index 000000000..692106968 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-object/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["match", "x", {}, "thing one", "thing two"], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[2]", "error": "Branch labels must be numbers or strings."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/label-overflow/test.json b/shared/test/data/expression-tests/match/label-overflow/test.json new file mode 100644 index 000000000..9eac280f4 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-overflow/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["match", 0, 10000000000000000, "thing one", "thing two"], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[2]", + "error": "Branch labels must be integers no larger than 9007199254740991." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/label-string-invalid-identifier/test.json b/shared/test/data/expression-tests/match/label-string-invalid-identifier/test.json new file mode 100644 index 000000000..f68eb48e3 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-string-invalid-identifier/test.json @@ -0,0 +1,32 @@ +{ + "expression": [ + "match", + ["string", ["get", "x"]], + ["0-1", "a.b", "{}", "weird\u2028json\u2029issue"], + "match", + "otherwise" + ], + "inputs": [ + [{}, {"properties": {"x": "0-1"}}], + [{}, {"properties": {"x": "a.b"}}], + [{}, {"properties": {"x": "{}"}}], + [{}, {"properties": {"x": "weird\u2028json\u2029issue"}}], + [{}, {"properties": {"x": "1"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["match", "match", "match", "match", "otherwise"], + "serialized": [ + "match", + ["string", ["get", "x"]], + ["0-1", "a.b", "weird\u2028json\u2029issue", "{}"], + "match", + "otherwise" + ] + } +} diff --git a/shared/test/data/expression-tests/match/label-string/test.json b/shared/test/data/expression-tests/match/label-string/test.json new file mode 100644 index 000000000..01ffbe799 --- /dev/null +++ b/shared/test/data/expression-tests/match/label-string/test.json @@ -0,0 +1,32 @@ +{ + "expression": ["match", ["string", ["get", "x"]], "0", "match", "otherwise"], + "inputs": [ + [{}, {"properties": {"x": "0"}}], + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}], + [{}, {"properties": {}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "match", + "otherwise", + { + "error": "Expected value to be of type string, but found number instead." + }, + { + "error": "Expected value to be of type string, but found boolean instead." + }, + {"error": "Expected value to be of type string, but found null instead."}, + {"error": "Expected value to be of type string, but found null instead."} + ], + "serialized": ["match", ["string", ["get", "x"]], "0", "match", "otherwise"] + } +} diff --git a/shared/test/data/expression-tests/match/mismatch-input/test.json b/shared/test/data/expression-tests/match/mismatch-input/test.json new file mode 100644 index 000000000..804933ddd --- /dev/null +++ b/shared/test/data/expression-tests/match/mismatch-input/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["match", ["string", ["get", "x"]], 0, "match", "otherwise"], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[1]", "error": "Expected number but found string instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/mismatch-label-1/test.json b/shared/test/data/expression-tests/match/mismatch-label-1/test.json new file mode 100644 index 000000000..46d78cf40 --- /dev/null +++ b/shared/test/data/expression-tests/match/mismatch-label-1/test.json @@ -0,0 +1,21 @@ +{ + "expression": [ + "match", + ["get", "x"], + "a", + "the letter a", + 0, + "the number 0", + true, + "The Truth", + "otherwise" + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[4]", "error": "Expected string but found number instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/mismatch-label-2/test.json b/shared/test/data/expression-tests/match/mismatch-label-2/test.json new file mode 100644 index 000000000..67cef7ce7 --- /dev/null +++ b/shared/test/data/expression-tests/match/mismatch-label-2/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["match", ["get", "x"], ["0", 0], "zero", "otherwise"], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[2]", "error": "Expected string but found number instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/mismatch-output/test.json b/shared/test/data/expression-tests/match/mismatch-output/test.json new file mode 100644 index 000000000..2a95152d3 --- /dev/null +++ b/shared/test/data/expression-tests/match/mismatch-output/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["match", ["string", ["get", "x"]], "0", "match", false], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[4]", "error": "Expected string but found boolean instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/mixed-type/test.json b/shared/test/data/expression-tests/match/mixed-type/test.json new file mode 100644 index 000000000..7c4104f6b --- /dev/null +++ b/shared/test/data/expression-tests/match/mixed-type/test.json @@ -0,0 +1,27 @@ +{ + "expression": [ + "match", + ["get", "x"], + "a", + "the letter a", + 0, + "the number 0", + true, + "The Truth", + "otherwise" + ], + "inputs": [ + [{}, {"properties": {"x": "a"}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": "0"}}], + [{}, {"properties": {"x": true}}] + ], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "[4]", "error": "Expected string but found number instead."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/match/multi-value/test.json b/shared/test/data/expression-tests/match/multi-value/test.json new file mode 100644 index 000000000..28b430fbe --- /dev/null +++ b/shared/test/data/expression-tests/match/multi-value/test.json @@ -0,0 +1,42 @@ +{ + "expression": [ + "string", + [ + "match", + ["string", ["get", "x"]], + ["a", "A"], + "Apple", + ["b", "B"], + "Banana", + "Kumquat" + ] + ], + "inputs": [ + [{}, {"properties": {"x": "a"}}], + [{}, {"properties": {"x": "A"}}], + [{}, {"properties": {"x": "b"}}], + [{}, {"properties": {"x": "B"}}], + [{}, {"properties": {"x": "c"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["Apple", "Apple", "Banana", "Banana", "Kumquat"], + "serialized": [ + "string", + [ + "match", + ["string", ["get", "x"]], + ["A", "a"], + "Apple", + ["B", "b"], + "Banana", + "Kumquat" + ] + ] + } +} diff --git a/shared/test/data/expression-tests/match/unreachable-branch-1/test.json b/shared/test/data/expression-tests/match/unreachable-branch-1/test.json new file mode 100644 index 000000000..9fa886878 --- /dev/null +++ b/shared/test/data/expression-tests/match/unreachable-branch-1/test.json @@ -0,0 +1,17 @@ +{ + "expression": [ + "match", + ["string", ["get", "x"]], + "0", + "match", + "0", + "match", + "otherwise" + ], + "expected": { + "compiled": { + "result": "error", + "errors": [{"key": "[4]", "error": "Branch labels must be unique."}] + } + } +} diff --git a/shared/test/data/expression-tests/match/unreachable-branch-2/test.json b/shared/test/data/expression-tests/match/unreachable-branch-2/test.json new file mode 100644 index 000000000..34d6ca326 --- /dev/null +++ b/shared/test/data/expression-tests/match/unreachable-branch-2/test.json @@ -0,0 +1,17 @@ +{ + "expression": [ + "match", + ["string", ["get", "x"]], + ["0", "1"], + "match", + ["0", "2"], + "match", + "otherwise" + ], + "expected": { + "compiled": { + "result": "error", + "errors": [{"key": "[4]", "error": "Branch labels must be unique."}] + } + } +} diff --git a/shared/test/data/expression-tests/max/arity-0/test.json b/shared/test/data/expression-tests/max/arity-0/test.json new file mode 100644 index 000000000..04528b6ae --- /dev/null +++ b/shared/test/data/expression-tests/max/arity-0/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["all", ["<", ["max"], 0], ["==", 0, ["/", 1, ["max"]]]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true], + "serialized": true + } +} diff --git a/shared/test/data/expression-tests/max/arity-1/test.json b/shared/test/data/expression-tests/max/arity-1/test.json new file mode 100644 index 000000000..dcbb50880 --- /dev/null +++ b/shared/test/data/expression-tests/max/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["max", 1], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1], + "serialized": 1 + } +} diff --git a/shared/test/data/expression-tests/max/basic/test.json b/shared/test/data/expression-tests/max/basic/test.json new file mode 100644 index 000000000..0e16cfd8b --- /dev/null +++ b/shared/test/data/expression-tests/max/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["max", 0, -1, 100], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [100], + "serialized": 100 + } +} diff --git a/shared/test/data/expression-tests/min/arity-0/test.json b/shared/test/data/expression-tests/min/arity-0/test.json new file mode 100644 index 000000000..713715d55 --- /dev/null +++ b/shared/test/data/expression-tests/min/arity-0/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["all", [">", ["min"], 0], ["==", 0, ["/", 1, ["min"]]]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true], + "serialized": true + } +} diff --git a/shared/test/data/expression-tests/min/arity-1/test.json b/shared/test/data/expression-tests/min/arity-1/test.json new file mode 100644 index 000000000..f7d663ba7 --- /dev/null +++ b/shared/test/data/expression-tests/min/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["min", 1], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1], + "serialized": 1 + } +} diff --git a/shared/test/data/expression-tests/min/basic/test.json b/shared/test/data/expression-tests/min/basic/test.json new file mode 100644 index 000000000..cf8162f6f --- /dev/null +++ b/shared/test/data/expression-tests/min/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["min", 0, -1, 10], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-1], + "serialized": -1 + } +} diff --git a/shared/test/data/expression-tests/minus/arity-0/test.json b/shared/test/data/expression-tests/minus/arity-0/test.json new file mode 100644 index 000000000..cc5a6d94d --- /dev/null +++ b/shared/test/data/expression-tests/minus/arity-0/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["-"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Expected arguments of type (number, number) | (number), but found () instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/minus/arity-1/test.json b/shared/test/data/expression-tests/minus/arity-1/test.json new file mode 100644 index 000000000..55a3993fa --- /dev/null +++ b/shared/test/data/expression-tests/minus/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["-", 5], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-5], + "serialized": -5 + } +} diff --git a/shared/test/data/expression-tests/minus/basic/test.json b/shared/test/data/expression-tests/minus/basic/test.json new file mode 100644 index 000000000..415192cc8 --- /dev/null +++ b/shared/test/data/expression-tests/minus/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["-", 5, 7], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-2], + "serialized": -2 + } +} diff --git a/shared/test/data/expression-tests/minus/inference-arity-2/test.json b/shared/test/data/expression-tests/minus/inference-arity-2/test.json new file mode 100644 index 000000000..542027e41 --- /dev/null +++ b/shared/test/data/expression-tests/minus/inference-arity-2/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["-", ["get", "x"], 7], + "inputs": [[{}, {"properties": {"x": 0}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-7], + "serialized": ["-", ["number", ["get", "x"]], 7] + } +} diff --git a/shared/test/data/expression-tests/mod/basic/test.json b/shared/test/data/expression-tests/mod/basic/test.json new file mode 100644 index 000000000..391e61ba1 --- /dev/null +++ b/shared/test/data/expression-tests/mod/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["%", 18, 12], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [6], + "serialized": 6 + } +} diff --git a/shared/test/data/expression-tests/not/basic/test.json b/shared/test/data/expression-tests/not/basic/test.json new file mode 100644 index 000000000..22ab93d4e --- /dev/null +++ b/shared/test/data/expression-tests/not/basic/test.json @@ -0,0 +1,17 @@ +{ + "expression": ["!", ["boolean", ["get", "x"]]], + "inputs": [ + [{}, {"properties": {"x": true}}], + [{}, {"properties": {"x": false}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true], + "serialized": ["!", ["boolean", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/not_equal/mismatch/test.json b/shared/test/data/expression-tests/not_equal/mismatch/test.json new file mode 100644 index 000000000..8a455e01b --- /dev/null +++ b/shared/test/data/expression-tests/not_equal/mismatch/test.json @@ -0,0 +1,11 @@ +{ + "expression": ["!=", ["string", ["get", "x"]], ["number", ["get", "y"]]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + {"key": "", "error": "Cannot compare types 'string' and 'number'."} + ] + } + } +} diff --git a/shared/test/data/expression-tests/not_equal/number/test.json b/shared/test/data/expression-tests/not_equal/number/test.json new file mode 100644 index 000000000..4d8b1030d --- /dev/null +++ b/shared/test/data/expression-tests/not_equal/number/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["!=", ["number", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": 1, "y": 1}}], + [{}, {"properties": {"x": 1, "y": "1"}}], + [{}, {"properties": {"x": 1, "y": 2}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, true], + "serialized": ["!=", ["number", ["get", "x"]], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/not_equal/string/test.json b/shared/test/data/expression-tests/not_equal/string/test.json new file mode 100644 index 000000000..a76faf12f --- /dev/null +++ b/shared/test/data/expression-tests/not_equal/string/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["!=", ["string", ["get", "x"]], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "1", "y": "1"}}], + [{}, {"properties": {"x": "1", "y": 1}}], + [{}, {"properties": {"x": "1", "y": "2"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, true], + "serialized": ["!=", ["string", ["get", "x"]], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/not_equal/value/test.json b/shared/test/data/expression-tests/not_equal/value/test.json new file mode 100644 index 000000000..62951ff58 --- /dev/null +++ b/shared/test/data/expression-tests/not_equal/value/test.json @@ -0,0 +1,21 @@ +{ + "expression": ["!=", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": 0, "y": 0}}], + [{}, {"properties": {"x": "0", "y": "0"}}], + [{}, {"properties": {"x": 0, "y": false}}], + [{}, {"properties": {"x": 0, "y": "0"}}], + [{}, {"properties": {"x": 0, "y": null}}], + [{}, {"properties": {"x": "0", "y": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, false, true, true, true, true], + "serialized": ["!=", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/number-format/currency/test.json b/shared/test/data/expression-tests/number-format/currency/test.json new file mode 100644 index 000000000..a25b057ba --- /dev/null +++ b/shared/test/data/expression-tests/number-format/currency/test.json @@ -0,0 +1,31 @@ +{ + "expression": [ + "number-format", + 123456.789, + { + "locale": ["get", "locale"], + "currency": ["get", "currency"] + } + ], + "inputs": [ + [{}, {"properties": {"locale": "en-US", "currency": "JPY"}}], + [{}, {"properties": {"locale": "en-US", "currency": "EUR"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["¥123,457", "€123,456.79"], + "serialized": [ + "number-format", + 123456.789, + { + "locale": ["string", ["get", "locale"]], + "currency": ["string", ["get", "currency"]] + } + ] + } +} diff --git a/shared/test/data/expression-tests/number-format/default/test.json b/shared/test/data/expression-tests/number-format/default/test.json new file mode 100644 index 000000000..78f2e7786 --- /dev/null +++ b/shared/test/data/expression-tests/number-format/default/test.json @@ -0,0 +1,21 @@ + +{ + "expression": [ + "number-format", + 123456.789, + {} + ], + "inputs": [ + [{}, {}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["123,456.789"], + "serialized": "123,456.789" + } +} diff --git a/shared/test/data/expression-tests/number-format/precision/test.json b/shared/test/data/expression-tests/number-format/precision/test.json new file mode 100644 index 000000000..c4266201f --- /dev/null +++ b/shared/test/data/expression-tests/number-format/precision/test.json @@ -0,0 +1,33 @@ +{ + "expression": [ + "number-format", + 987654321.234567, + { + "locale": ["get", "locale"], + "min-fraction-digits": ["get", "min"], + "max-fraction-digits": ["get", "max"] + } + ], + "inputs": [ + [{}, {"properties": {"locale": "en-US", "min": 15, "max": 20}}], + [{}, {"properties": {"locale": "en-US", "min": 2, "max": 4}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["987,654,321.234567000000000", "987,654,321.2346"], + "serialized": [ + "number-format", + 987654321.234567, + { + "locale": ["string", ["get", "locale"]], + "min-fraction-digits": ["number", ["get", "min"]], + "max-fraction-digits": ["number", ["get", "max"]] + } + ] + } +} diff --git a/shared/test/data/expression-tests/number/basic/test.json b/shared/test/data/expression-tests/number/basic/test.json new file mode 100644 index 000000000..a428ac192 --- /dev/null +++ b/shared/test/data/expression-tests/number/basic/test.json @@ -0,0 +1,28 @@ +{ + "expression": ["number", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 1, + { + "error": "Expected value to be of type number, but found string instead." + }, + { + "error": "Expected value to be of type number, but found boolean instead." + }, + {"error": "Expected value to be of type number, but found null instead."} + ], + "serialized": ["number", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/number/default-value/test.json b/shared/test/data/expression-tests/number/default-value/test.json new file mode 100644 index 000000000..7f082ba09 --- /dev/null +++ b/shared/test/data/expression-tests/number/default-value/test.json @@ -0,0 +1,19 @@ +{ + "expression": ["number", ["get", "x"], -1], + "inputs": [ + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1, -1, -1, -1], + "serialized": ["number", ["get", "x"], -1] + } +} diff --git a/shared/test/data/expression-tests/object/basic/test.json b/shared/test/data/expression-tests/object/basic/test.json new file mode 100644 index 000000000..dc0dad4e7 --- /dev/null +++ b/shared/test/data/expression-tests/object/basic/test.json @@ -0,0 +1,32 @@ +{ + "expression": ["object", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": {"inner": "object"}}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "object" + }, + "outputs": [ + {"inner": "object"}, + { + "error": "Expected value to be of type object, but found number instead." + }, + { + "error": "Expected value to be of type object, but found string instead." + }, + { + "error": "Expected value to be of type object, but found boolean instead." + }, + {"error": "Expected value to be of type object, but found null instead."} + ], + "serialized": ["object", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/object/default-value/test.json b/shared/test/data/expression-tests/object/default-value/test.json new file mode 100644 index 000000000..384620c0a --- /dev/null +++ b/shared/test/data/expression-tests/object/default-value/test.json @@ -0,0 +1,26 @@ +{ + "expression": ["object", ["get", "x"], ["literal", {"default": "value"}]], + "inputs": [ + [{}, {"properties": {"x": {"inner": "object"}}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "object" + }, + "outputs": [ + {"inner": "object"}, + {"default": "value"}, + {"default": "value"}, + {"default": "value"}, + {"default": "value"} + ], + "serialized": ["object", ["get", "x"], ["literal", {"default": "value"}]] + } +} diff --git a/shared/test/data/expression-tests/object/implicit/test.json b/shared/test/data/expression-tests/object/implicit/test.json new file mode 100644 index 000000000..70dc100d2 --- /dev/null +++ b/shared/test/data/expression-tests/object/implicit/test.json @@ -0,0 +1,22 @@ +{ + "expression": ["get", "b", ["get", "a"]], + "inputs": [ + [{}, {"properties": {"a": {"b": 0}}}], + [{}, {"properties": {"a": "not"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": [ + 0, + { + "error": "Expected value to be of type object, but found string instead." + } + ], + "serialized": ["get", "b", ["object", ["get", "a"]]] + } +} diff --git a/shared/test/data/expression-tests/parse/empty/test.json b/shared/test/data/expression-tests/parse/empty/test.json new file mode 100644 index 000000000..737b33dc3 --- /dev/null +++ b/shared/test/data/expression-tests/parse/empty/test.json @@ -0,0 +1,14 @@ +{ + "expression": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Expected an array with at least one element. If you wanted a literal array, use [\"literal\", []]." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/parse/non-array/test.json b/shared/test/data/expression-tests/parse/non-array/test.json new file mode 100644 index 000000000..ce9ad3312 --- /dev/null +++ b/shared/test/data/expression-tests/parse/non-array/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["+", ["-", 0, {}], 10], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1][2]", + "error": "Bare objects invalid. Use [\"literal\", {...}] instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/parse/non-string/test.json b/shared/test/data/expression-tests/parse/non-string/test.json new file mode 100644 index 000000000..def3386e0 --- /dev/null +++ b/shared/test/data/expression-tests/parse/non-string/test.json @@ -0,0 +1,14 @@ +{ + "expression": [1, 2], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[0]", + "error": "Expression name must be a string, but found number instead. If you wanted a literal array, use [\"literal\", [...]]." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/parse/unknown-expression/test.json b/shared/test/data/expression-tests/parse/unknown-expression/test.json new file mode 100644 index 000000000..d4ba1782a --- /dev/null +++ b/shared/test/data/expression-tests/parse/unknown-expression/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["+", ["*", 1, 2, 3, ["FAKE-EXPRESSION", 1]], 10], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[1][4][0]", + "error": "Unknown expression \"FAKE-EXPRESSION\". If you wanted a literal array, use [\"literal\", [...]]." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/pi/basic/test.json b/shared/test/data/expression-tests/pi/basic/test.json new file mode 100644 index 000000000..8f17841fc --- /dev/null +++ b/shared/test/data/expression-tests/pi/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["pi"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [3.14159], + "serialized": 3.141592653589793 + } +} diff --git a/shared/test/data/expression-tests/plus/arity-0/test.json b/shared/test/data/expression-tests/plus/arity-0/test.json new file mode 100644 index 000000000..4a92b220c --- /dev/null +++ b/shared/test/data/expression-tests/plus/arity-0/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["+"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0], + "serialized": 0 + } +} diff --git a/shared/test/data/expression-tests/plus/arity-1/test.json b/shared/test/data/expression-tests/plus/arity-1/test.json new file mode 100644 index 000000000..cb7154d7f --- /dev/null +++ b/shared/test/data/expression-tests/plus/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["+", 1], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1], + "serialized": 1 + } +} diff --git a/shared/test/data/expression-tests/plus/basic/test.json b/shared/test/data/expression-tests/plus/basic/test.json new file mode 100644 index 000000000..3ecdf42fc --- /dev/null +++ b/shared/test/data/expression-tests/plus/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["+", 1, 2, 3, 4], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [10], + "serialized": 10 + } +} diff --git a/shared/test/data/expression-tests/pow/basic/test.json b/shared/test/data/expression-tests/pow/basic/test.json new file mode 100644 index 000000000..299f4cedc --- /dev/null +++ b/shared/test/data/expression-tests/pow/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["^", 4, ["number", ["get", "x"]]], + "inputs": [[{}, {"properties": {"x": 2}}], [{}, {"properties": {"x": 0.5}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [16, 2], + "serialized": ["^", 4, ["number", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/properties/basic/test.json b/shared/test/data/expression-tests/properties/basic/test.json new file mode 100644 index 000000000..ddbcdd831 --- /dev/null +++ b/shared/test/data/expression-tests/properties/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["properties"], + "inputs": [[{}, {"properties": {"x": 5}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "object" + }, + "outputs": [{"x": 5}], + "serialized": ["properties"] + } +} diff --git a/shared/test/data/expression-tests/resolved-locale/basic/test.json b/shared/test/data/expression-tests/resolved-locale/basic/test.json new file mode 100644 index 000000000..012a1520c --- /dev/null +++ b/shared/test/data/expression-tests/resolved-locale/basic/test.json @@ -0,0 +1,34 @@ +{ + "expression": [ + "==", + [ + "resolved-locale", + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": true, "locale": "en"} + ] + ], + "en" + ], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [true], + "serialized": [ + "==", + [ + "resolved-locale", + [ + "collator", + {"case-sensitive": true, "diacritic-sensitive": true, "locale": "en"} + ] + ], + "en" + ] + } +} diff --git a/shared/test/data/expression-tests/result_item.html.tmpl b/shared/test/data/expression-tests/result_item.html.tmpl new file mode 100644 index 000000000..c97552960 --- /dev/null +++ b/shared/test/data/expression-tests/result_item.html.tmpl @@ -0,0 +1,16 @@ +
+

<%- r.status %> <%- r.id %>

+
<%- r.expression %>
+ + <% if (r.error) { %>

Error: <%- r.error.message %>

<% } %> + + <% if (r.difference) { %> + Difference: +
<%- r.difference %>
+ <% } %> + + <% if (r.serialized) { %> + Serialized: +
<%- r.serialized %>
+ <% } %> +
diff --git a/shared/test/data/expression-tests/rgb/basic/test.json b/shared/test/data/expression-tests/rgb/basic/test.json new file mode 100644 index 000000000..ebd432dec --- /dev/null +++ b/shared/test/data/expression-tests/rgb/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["rgb", 0, 0, 255], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[0, 0, 1, 1]], + "serialized": ["rgba", 0, 0, 255, 1] + } +} diff --git a/shared/test/data/expression-tests/rgba/basic/test.json b/shared/test/data/expression-tests/rgba/basic/test.json new file mode 100644 index 000000000..9bbed51ee --- /dev/null +++ b/shared/test/data/expression-tests/rgba/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["rgba", 0, 0, 255, 1], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [[0, 0, 1, 1]], + "serialized": ["rgba", 0, 0, 255, 1] + } +} diff --git a/shared/test/data/expression-tests/rgba/out-of-bounds/test.json b/shared/test/data/expression-tests/rgba/out-of-bounds/test.json new file mode 100644 index 000000000..7d9f82421 --- /dev/null +++ b/shared/test/data/expression-tests/rgba/out-of-bounds/test.json @@ -0,0 +1,44 @@ +{ + "expression": [ + "rgba", + 0, + 0, + ["number", ["get", "b"]], + ["number", ["get", "a"]] + ], + "inputs": [ + [{}, {"properties": {"b": -1, "a": 1}}], + [{}, {"properties": {"b": 256, "a": 1}}], + [{}, {"properties": {"b": 255, "a": -0.5}}], + [{}, {"properties": {"b": 256, "a": 1.5}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + { + "error": "Invalid rgba value [0, 0, -1, 1]: 'r', 'g', and 'b' must be between 0 and 255." + }, + { + "error": "Invalid rgba value [0, 0, 256, 1]: 'r', 'g', and 'b' must be between 0 and 255." + }, + { + "error": "Invalid rgba value [0, 0, 255, -0.5]: 'a' must be between 0 and 1." + }, + { + "error": "Invalid rgba value [0, 0, 256, 1.5]: 'r', 'g', and 'b' must be between 0 and 255." + } + ], + "serialized": [ + "rgba", + 0, + 0, + ["number", ["get", "b"]], + ["number", ["get", "a"]] + ] + } +} diff --git a/shared/test/data/expression-tests/round/basic/test.json b/shared/test/data/expression-tests/round/basic/test.json new file mode 100644 index 000000000..5c6f4a6f4 --- /dev/null +++ b/shared/test/data/expression-tests/round/basic/test.json @@ -0,0 +1,23 @@ +{ + "expression": ["round", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": -2.6}}], + [{}, {"properties": {"x": -2.5}}], + [{}, {"properties": {"x": -2.4}}], + [{}, {"properties": {"x": -2}}], + [{}, {"properties": {"x": 2.6}}], + [{}, {"properties": {"x": 2.5}}], + [{}, {"properties": {"x": 2.4}}], + [{}, {"properties": {"x": 2}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [-3, -3, -2, -2, 3, 3, 2, 2], + "serialized": ["round", ["number", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/sin/basic/test.json b/shared/test/data/expression-tests/sin/basic/test.json new file mode 100644 index 000000000..ec3880135 --- /dev/null +++ b/shared/test/data/expression-tests/sin/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["sin", 0], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0], + "serialized": 0 + } +} diff --git a/shared/test/data/expression-tests/slice/array-one-index/test.json b/shared/test/data/expression-tests/slice/array-one-index/test.json new file mode 100644 index 000000000..138d7ee9e --- /dev/null +++ b/shared/test/data/expression-tests/slice/array-one-index/test.json @@ -0,0 +1,19 @@ +{ + "expression": ["slice", ["array", ["get", "val"]], ["get", "index"]], + "inputs": [ + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "index": 2}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "index": 0}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "index": 99}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "index": -2}}] + ], + "expected": { + "serialized": ["slice", ["array", ["get", "val"]], ["get", "index"]], + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[3, 4, 5], [1, 2, 3, 4, 5], [], [4, 5]] + } + } diff --git a/shared/test/data/expression-tests/slice/array-two-indexes/test.json b/shared/test/data/expression-tests/slice/array-two-indexes/test.json new file mode 100644 index 000000000..5b6173005 --- /dev/null +++ b/shared/test/data/expression-tests/slice/array-two-indexes/test.json @@ -0,0 +1,31 @@ +{ + "expression": [ + "slice", + ["array", ["get", "val"]], + ["get", "i1"], + ["get", "i2"] + ], + "inputs": [ + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "i1": 2, "i2": 4}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "i1": 1, "i2": 5}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "i1": 1, "i2": 99}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "i1": -4, "i2": -2}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "i1": 0, "i2": -1}}], + [{}, {"properties": {"val": [1, 2, 3, 4, 5], "i1": 0, "i2": 0}}] + ], + "expected": { + "serialized": [ + "slice", + ["array", ["get", "val"]], + ["get", "i1"], + ["get", "i2"] + ], + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[3, 4], [2, 3, 4, 5], [2, 3, 4, 5], [2, 3], [1, 2, 3, 4], []] + } + } diff --git a/shared/test/data/expression-tests/slice/invalid-inputs/test.json b/shared/test/data/expression-tests/slice/invalid-inputs/test.json new file mode 100644 index 000000000..3f428ecec --- /dev/null +++ b/shared/test/data/expression-tests/slice/invalid-inputs/test.json @@ -0,0 +1,40 @@ +{ + "expression": ["slice", ["get", "input"], ["get", "i1"]], + "inputs": [ + [{}, {"properties": {"input": false, "i1": 1}}], + [{}, {"properties": {"input": null, "i1": 1}}], + [{}, {"properties": {"input": 12, "i1": 1}}], + [{}, {"properties": {"input": {}, "i1": 1}}], + [{}, {"properties": {"other": 1, "i1": 1}}], + [{}, {"properties": {"input": "correct", "i1": "one"}}] + ], + "expected": { + "serialized": ["slice", ["get", "input"], ["get", "i1"]], + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": [ + { + "error": "Expected first argument to be of type array or string, but found boolean instead." + }, + { + "error": "Expected first argument to be of type array or string, but found null instead." + }, + { + "error": "Expected first argument to be of type array or string, but found number instead." + }, + { + "error": "Expected first argument to be of type array or string, but found object instead." + }, + { + "error": "Expected first argument to be of type array or string, but found null instead." + }, + { + "error": "Expected value to be of type number, but found string instead." + } + ] + } + } diff --git a/shared/test/data/expression-tests/slice/string-one-index/test.json b/shared/test/data/expression-tests/slice/string-one-index/test.json new file mode 100644 index 000000000..2d64fa71c --- /dev/null +++ b/shared/test/data/expression-tests/slice/string-one-index/test.json @@ -0,0 +1,19 @@ +{ + "expression": ["slice", ["get", "val"], ["get", "index"]], + "inputs": [ + [{}, {"properties": {"val": "0123456789", "index": 0}}], + [{}, {"properties": {"val": "0123456789", "index": 4}}], + [{}, {"properties": {"val": "0123456789", "index": 99}}], + [{}, {"properties": {"val": "0123456789", "index": -2}}] + ], + "expected": { + "serialized": ["slice", ["get", "val"], ["get", "index"]], + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": ["0123456789", "456789", "", "89"] + } + } diff --git a/shared/test/data/expression-tests/slice/string-two-indexes/test.json b/shared/test/data/expression-tests/slice/string-two-indexes/test.json new file mode 100644 index 000000000..3df97fcdf --- /dev/null +++ b/shared/test/data/expression-tests/slice/string-two-indexes/test.json @@ -0,0 +1,20 @@ +{ + "expression": ["slice", ["get", "val"], ["get", "i1"], ["get", "i2"]], + "inputs": [ + [{}, {"properties": {"val": "0123456789", "i1": 1, "i2": 8}}], + [{}, {"properties": {"val": "0123456789", "i1": 4, "i2": -2}}], + [{}, {"properties": {"val": "0123456789", "i1": -3, "i2": -1}}], + [{}, {"properties": {"val": "0123456789", "i1": 0, "i2": -1}}], + [{}, {"properties": {"val": "0123456789", "i1": 0, "i2": 99}}] + ], + "expected": { + "serialized": ["slice", ["get", "val"], ["get", "i1"], ["get", "i2"]], + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "value" + }, + "outputs": ["1234567", "4567", "78", "012345678", "0123456789"] + } + } diff --git a/shared/test/data/expression-tests/sqrt/basic/test.json b/shared/test/data/expression-tests/sqrt/basic/test.json new file mode 100644 index 000000000..38077afbc --- /dev/null +++ b/shared/test/data/expression-tests/sqrt/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["sqrt", ["get", "x"]], + "inputs": [[{}, {"properties": {"x": 4}}], [{}, {"properties": {"x": 0.25}}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [2, 0.5], + "serialized": ["sqrt", ["number", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/step/basic/test.json b/shared/test/data/expression-tests/step/basic/test.json new file mode 100644 index 000000000..723ae2e89 --- /dev/null +++ b/shared/test/data/expression-tests/step/basic/test.json @@ -0,0 +1,27 @@ +{ + "expression": [ + "number", + ["step", ["number", ["get", "x"]], 11, 0, 111, 1, 1111] + ], + "inputs": [ + [{}, {"properties": {"x": -1.5}}], + [{}, {"properties": {"x": -0.5}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 0.5}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": 1.5}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [11, 11, 111, 111, 1111, 1111], + "serialized": [ + "number", + ["step", ["number", ["get", "x"]], 11, 0, 111, 1, 1111] + ] + } +} diff --git a/shared/test/data/expression-tests/step/duplicate_stops/test.json b/shared/test/data/expression-tests/step/duplicate_stops/test.json new file mode 100644 index 000000000..de5212369 --- /dev/null +++ b/shared/test/data/expression-tests/step/duplicate_stops/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["step", 0, "a", 0, "b", 0, "c"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "[5]", + "error": "Input/output pairs for \"step\" expressions must be arranged with input values in strictly ascending order." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/string/basic/test.json b/shared/test/data/expression-tests/string/basic/test.json new file mode 100644 index 000000000..d40c2593c --- /dev/null +++ b/shared/test/data/expression-tests/string/basic/test.json @@ -0,0 +1,28 @@ +{ + "expression": ["string", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "1", + { + "error": "Expected value to be of type string, but found number instead." + }, + { + "error": "Expected value to be of type string, but found boolean instead." + }, + {"error": "Expected value to be of type string, but found null instead."} + ], + "serialized": ["string", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/string/default-value/test.json b/shared/test/data/expression-tests/string/default-value/test.json new file mode 100644 index 000000000..0f6cc8b0f --- /dev/null +++ b/shared/test/data/expression-tests/string/default-value/test.json @@ -0,0 +1,19 @@ +{ + "expression": ["string", ["get", "x"], "default"], + "inputs": [ + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["1", "default", "default", "default"], + "serialized": ["string", ["get", "x"], "default"] + } +} diff --git a/shared/test/data/expression-tests/tan/basic/test.json b/shared/test/data/expression-tests/tan/basic/test.json new file mode 100644 index 000000000..9016d430c --- /dev/null +++ b/shared/test/data/expression-tests/tan/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["tan", 0.7853981633974483], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0.999999], + "serialized": 0.9999999999999999 + } +} diff --git a/shared/test/data/expression-tests/times/arity-0/test.json b/shared/test/data/expression-tests/times/arity-0/test.json new file mode 100644 index 000000000..0cd892d63 --- /dev/null +++ b/shared/test/data/expression-tests/times/arity-0/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["*"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [1], + "serialized": 1 + } +} diff --git a/shared/test/data/expression-tests/times/arity-1/test.json b/shared/test/data/expression-tests/times/arity-1/test.json new file mode 100644 index 000000000..021b933cc --- /dev/null +++ b/shared/test/data/expression-tests/times/arity-1/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["*", 0], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [0], + "serialized": 0 + } +} diff --git a/shared/test/data/expression-tests/times/basic/test.json b/shared/test/data/expression-tests/times/basic/test.json new file mode 100644 index 000000000..09c7e54ff --- /dev/null +++ b/shared/test/data/expression-tests/times/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["*", 3, 2, 0.5, 2], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [6], + "serialized": 6 + } +} diff --git a/shared/test/data/expression-tests/to-boolean/2-ary/test.json b/shared/test/data/expression-tests/to-boolean/2-ary/test.json new file mode 100644 index 000000000..94de6a23d --- /dev/null +++ b/shared/test/data/expression-tests/to-boolean/2-ary/test.json @@ -0,0 +1,10 @@ +{ + "expression": ["to-boolean", ["get", "x"], ["get", "y"]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [{"key": "", "error": "Expected one argument."}] + } + } +} diff --git a/shared/test/data/expression-tests/to-boolean/basic/test.json b/shared/test/data/expression-tests/to-boolean/basic/test.json new file mode 100644 index 000000000..4cf336e57 --- /dev/null +++ b/shared/test/data/expression-tests/to-boolean/basic/test.json @@ -0,0 +1,23 @@ +{ + "expression": ["to-boolean", ["get", "x"]], + "inputs": [ + [{}, {}], + [{}, {"properties": {"x": true}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": ""}}], + [{}, {"properties": {"x": "false"}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": null}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [false, true, false, false, true, false, true, false], + "serialized": ["to-boolean", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/to-color/2-ary/test.json b/shared/test/data/expression-tests/to-color/2-ary/test.json new file mode 100644 index 000000000..ec301ce78 --- /dev/null +++ b/shared/test/data/expression-tests/to-color/2-ary/test.json @@ -0,0 +1,30 @@ +{ + "expression": ["to-color", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": "red", "y": "#000000"}}], + [{}, {"properties": {"x": "invalid", "y": "#000000"}}], + [{}, {"properties": {"x": "rgba(0, 255, 0, 1)", "y": "#000000"}}], + [{}, {"properties": {"x": [0, 255, 0, 1], "y": "#000000"}}], + [{}, {"properties": {"x": [0, 255, 0], "y": "#000000"}}], + [{}, {"properties": {"x": [0, 255], "y": "#000000"}}], + [{}, {"properties": {"x": [0, 255], "y": "invalid"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [1, 0, 0, 1], + [0, 0, 0, 1], + [0, 1, 0, 1], + [0, 1, 0, 1], + [0, 1, 0, 1], + [0, 0, 0, 1], + {"error": "Could not parse color from value 'invalid'"} + ], + "serialized": ["to-color", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/to-color/basic/test.json b/shared/test/data/expression-tests/to-color/basic/test.json new file mode 100644 index 000000000..6660157c7 --- /dev/null +++ b/shared/test/data/expression-tests/to-color/basic/test.json @@ -0,0 +1,30 @@ +{ + "expression": ["to-color", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": "red"}}], + [{}, {"properties": {"x": "invalid"}}], + [{}, {"properties": {"x": "rgba(0, 255, 0, 1)"}}], + [{}, {"properties": {"x": [0, 255, 0, 1]}}], + [{}, {"properties": {"x": [0, 255, 0]}}], + [{}, {"properties": {"x": [0, 255]}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [1, 0, 0, 1], + {"error": "Could not parse color from value 'invalid'"}, + [0, 1, 0, 1], + [0, 1, 0, 1], + [0, 1, 0, 1], + { + "error": "Invalid rbga value [0,255]: expected an array containing either three or four numeric values." + } + ], + "serialized": ["to-color", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/to-color/color/test.json b/shared/test/data/expression-tests/to-color/color/test.json new file mode 100644 index 000000000..c3ca158ca --- /dev/null +++ b/shared/test/data/expression-tests/to-color/color/test.json @@ -0,0 +1,18 @@ +{ + "expression": ["to-color", ["rgba", 0, 0, 0, 1]], + "inputs": [ + [{}, {}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "color" + }, + "outputs": [ + [0, 0, 0, 1] + ], + "serialized": ["rgba", 0, 0, 0, 1] + } +} diff --git a/shared/test/data/expression-tests/to-number/2-ary/test.json b/shared/test/data/expression-tests/to-number/2-ary/test.json new file mode 100644 index 000000000..bbed5b9cb --- /dev/null +++ b/shared/test/data/expression-tests/to-number/2-ary/test.json @@ -0,0 +1,34 @@ +{ + "expression": ["to-number", ["get", "x"], ["get", "y"]], + "inputs": [ + [{}, {"properties": {"x": 1, "y": -1}}], + [{}, {"properties": {"x": "1", "y": -1}}], + [{}, {"properties": {"x": "6.02e-23", "y": -1}}], + [{}, {"properties": {"x": "Not a number", "y": -1}}], + [{}, {"properties": {"x": null, "y": -1}}], + [{}, {"properties": {"x": [1, 2], "y": -1}}], + [{}, {"properties": {"x": {"y": 1}, "y": -1}}], + [{}, {"properties": {"y": -1}}], + [{}, {"properties": {"y": "bad fallback"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 1, + 1, + 6.02e-23, + -1, + 0, + -1, + -1, + 0, + 0 + ], + "serialized": ["to-number", ["get", "x"], ["get", "y"]] + } +} diff --git a/shared/test/data/expression-tests/to-number/basic/test.json b/shared/test/data/expression-tests/to-number/basic/test.json new file mode 100644 index 000000000..1d769c89f --- /dev/null +++ b/shared/test/data/expression-tests/to-number/basic/test.json @@ -0,0 +1,30 @@ +{ + "expression": ["to-number", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": "1"}}], + [{}, {"properties": {"x": "6.02e-23"}}], + [{}, {"properties": {"x": "Not a number"}}], + [{}, {"properties": {"x": null}}], + [{}, {"properties": {"x": [1, 2]}}], + [{}, {"properties": {"x": {"y": 1}}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "number" + }, + "outputs": [ + 1, + 1, + 6.02e-23, + {"error": "Could not convert \"Not a number\" to number."}, + 0, + {"error": "Could not convert [1,2] to number."}, + {"error": "Could not convert {\"y\":1} to number."} + ], + "serialized": ["to-number", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/to-rgba/alpha/test.json b/shared/test/data/expression-tests/to-rgba/alpha/test.json new file mode 100644 index 000000000..3cafddae2 --- /dev/null +++ b/shared/test/data/expression-tests/to-rgba/alpha/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["to-rgba", ["rgba", 0, 128, 255, 0.5]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[0, 128, 255, 0.5]], + "serialized": ["literal", [0, 128, 255, 0.5]] + } +} diff --git a/shared/test/data/expression-tests/to-rgba/basic/test.json b/shared/test/data/expression-tests/to-rgba/basic/test.json new file mode 100644 index 000000000..7f2175b54 --- /dev/null +++ b/shared/test/data/expression-tests/to-rgba/basic/test.json @@ -0,0 +1,19 @@ +{ + "expression": ["to-rgba", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": "red"}}], + [{}, {"properties": {"x": "rgba(0, 255, 0, 1)"}}], + [{}, {"properties": {"x": [0, 255, 0, 1]}}], + [{}, {"properties": {"x": [0, 0, 255]}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[255, 0, 0, 1], [0, 255, 0, 1], [0, 255, 0, 1], [0, 0, 255, 1]], + "serialized": ["to-rgba", ["to-color", ["get", "x"]]] + } +} diff --git a/shared/test/data/expression-tests/to-rgba/zero/test.json b/shared/test/data/expression-tests/to-rgba/zero/test.json new file mode 100644 index 000000000..1e206dc06 --- /dev/null +++ b/shared/test/data/expression-tests/to-rgba/zero/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["to-rgba", ["rgba", 0, 0, 0, 0]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [[0, 0, 0, 0]], + "serialized": ["literal", [0, 0, 0, 0]] + } +} diff --git a/shared/test/data/expression-tests/to-string/2-ary/test.json b/shared/test/data/expression-tests/to-string/2-ary/test.json new file mode 100644 index 000000000..4ee8bde79 --- /dev/null +++ b/shared/test/data/expression-tests/to-string/2-ary/test.json @@ -0,0 +1,10 @@ +{ + "expression": ["to-string", ["get", "x"], ["get", "y"]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [{"key": "", "error": "Expected one argument."}] + } + } +} diff --git a/shared/test/data/expression-tests/to-string/basic/test.json b/shared/test/data/expression-tests/to-string/basic/test.json new file mode 100644 index 000000000..7a17dc320 --- /dev/null +++ b/shared/test/data/expression-tests/to-string/basic/test.json @@ -0,0 +1,21 @@ +{ + "expression": ["to-string", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": 1}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": null}}], + [{}, {"properties": {"x": "string"}}], + [{}, {"properties": {"x": [1, 2]}}], + [{}, {"properties": {"x": {"y": 1}}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["1", "false", "", "string", "[1,2]", "{\"y\":1}"], + "serialized": ["to-string", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/to-string/color/test.json b/shared/test/data/expression-tests/to-string/color/test.json new file mode 100644 index 000000000..d22d9943f --- /dev/null +++ b/shared/test/data/expression-tests/to-string/color/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["to-string", ["rgba", 85, 255, 0, 0.5]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["rgba(85,255,0,0.5)"], + "serialized": "rgba(85,255,0,0.5)" + } +} diff --git a/shared/test/data/expression-tests/to-string/implicit/test.json b/shared/test/data/expression-tests/to-string/implicit/test.json new file mode 100644 index 000000000..d13d2b807 --- /dev/null +++ b/shared/test/data/expression-tests/to-string/implicit/test.json @@ -0,0 +1,24 @@ +{ + "expression": ["get", "p"], + "propertySpec": { + "type": "string" + }, + "inputs": [ + [{}, {"properties": {}}], + [{}, {"properties": {"p": 0}}], + [{}, {"properties": {"p": "a"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["", "0", "a"], + "serialized": [ + "to-string", + ["get", "p"] + ] + } +} diff --git a/shared/test/data/expression-tests/typecheck/array-invalid-item/test.json b/shared/test/data/expression-tests/typecheck/array-invalid-item/test.json new file mode 100644 index 000000000..07c9f8f17 --- /dev/null +++ b/shared/test/data/expression-tests/typecheck/array-invalid-item/test.json @@ -0,0 +1,22 @@ +{ + "propertySpec": { + "type": "array", + "value": "string", + "length": 2, + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["array", "number", 2, ["get", "x"]], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Expected array but found array instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/typecheck/array-item-subtyping/test.json b/shared/test/data/expression-tests/typecheck/array-item-subtyping/test.json new file mode 100644 index 000000000..a2859348c --- /dev/null +++ b/shared/test/data/expression-tests/typecheck/array-item-subtyping/test.json @@ -0,0 +1,19 @@ +{ + "propertySpec": { + "type": "array", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["array", "number", 2, ["get", "x"]], + "inputs": [], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [], + "serialized": ["array", "number", 2, ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/typecheck/array-length-subtyping--no-length/test.json b/shared/test/data/expression-tests/typecheck/array-length-subtyping--no-length/test.json new file mode 100644 index 000000000..d180e38ba --- /dev/null +++ b/shared/test/data/expression-tests/typecheck/array-length-subtyping--no-length/test.json @@ -0,0 +1,22 @@ +{ + "propertySpec": { + "type": "array", + "value": "number", + "length": 3, + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["array", "number", ["get", "x"]], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Expected array but found array instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/typecheck/array-length-subtyping/test.json b/shared/test/data/expression-tests/typecheck/array-length-subtyping/test.json new file mode 100644 index 000000000..2600dec7e --- /dev/null +++ b/shared/test/data/expression-tests/typecheck/array-length-subtyping/test.json @@ -0,0 +1,20 @@ +{ + "propertySpec": { + "type": "array", + "value": "string", + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["array", "string", 2, ["get", "x"]], + "inputs": [], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [], + "serialized": ["array", "string", 2, ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/typecheck/array-wrong-length/test.json b/shared/test/data/expression-tests/typecheck/array-wrong-length/test.json new file mode 100644 index 000000000..a5e08bd02 --- /dev/null +++ b/shared/test/data/expression-tests/typecheck/array-wrong-length/test.json @@ -0,0 +1,22 @@ +{ + "propertySpec": { + "type": "array", + "value": "number", + "length": 3, + "property-type": "data-driven", + "expression": {"parameters": ["zoom", "feature"]} + }, + "expression": ["array", "number", 2, ["get", "x"]], + "inputs": [], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Expected array but found array instead." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/typeof/basic/test.json b/shared/test/data/expression-tests/typeof/basic/test.json new file mode 100644 index 000000000..81b3b5e7d --- /dev/null +++ b/shared/test/data/expression-tests/typeof/basic/test.json @@ -0,0 +1,34 @@ +{ + "expression": ["typeof", ["get", "x"]], + "inputs": [ + [{}, {"properties": {"x": null}}], + [{}, {"properties": {"x": "s"}}], + [{}, {"properties": {"x": 0}}], + [{}, {"properties": {"x": false}}], + [{}, {"properties": {"x": [1, 2, 3]}}], + [{}, {"properties": {"x": ["a", "b", "c"]}}], + [{}, {"properties": {"x": [true, false]}}], + [{}, {"properties": {"x": [1, false]}}], + [{}, {"properties": {"x": {}}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "null", + "string", + "number", + "boolean", + "array", + "array", + "array", + "array", + "object" + ], + "serialized": ["typeof", ["get", "x"]] + } +} diff --git a/shared/test/data/expression-tests/upcase/basic/test.json b/shared/test/data/expression-tests/upcase/basic/test.json new file mode 100644 index 000000000..b4d05b85e --- /dev/null +++ b/shared/test/data/expression-tests/upcase/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["upcase", "string"], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": true, + "type": "string" + }, + "outputs": ["STRING"], + "serialized": "STRING" + } +} diff --git a/shared/test/data/expression-tests/within/invalid-geojson/test.json b/shared/test/data/expression-tests/within/invalid-geojson/test.json new file mode 100644 index 000000000..5a6ccfa38 --- /dev/null +++ b/shared/test/data/expression-tests/within/invalid-geojson/test.json @@ -0,0 +1,52 @@ +{ + "expression": ["within", { + "type": "LineString", + "coordinates": [[0, 0], [0, 5], [5, 5], [5, 0]] + }], + "inputs": [[{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "Point", + "coordinates": [6, 6] + } + }], [{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "Point", + "coordinates": [2, 2] + } + }], [{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "LineString", + "coordinates": [[3, 3], [4, 1]] + } + }]], + "expected": { + "compiled": { + "errors": [{ + "key": "", + "error": "'within' expression requires valid geojson source that contains polygon geometry type." + }], + "result": "error" + } + } +} diff --git a/shared/test/data/expression-tests/within/line-within-polygon/test.json b/shared/test/data/expression-tests/within/line-within-polygon/test.json new file mode 100644 index 000000000..b42c19c99 --- /dev/null +++ b/shared/test/data/expression-tests/within/line-within-polygon/test.json @@ -0,0 +1,44 @@ +{ + "expression": ["within", { + "type": "Polygon", + "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]] + }], + "inputs": [[{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "LineString", + "coordinates": [[3, 3], [4, 1]] + } + }], [{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "LineString", + "coordinates": [[3, 3], [6, 6]] + } + }]], + "expected": { + "compiled": { + "type": "boolean", + "isFeatureConstant": false, + "isZoomConstant": true, + "result": "success" + }, + "outputs": [true, false], + "serialized": ["within", { + "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]], + "type": "Polygon" + }] + } +} diff --git a/shared/test/data/expression-tests/within/non-supported/test.json b/shared/test/data/expression-tests/within/non-supported/test.json new file mode 100644 index 000000000..16659a5fc --- /dev/null +++ b/shared/test/data/expression-tests/within/non-supported/test.json @@ -0,0 +1,32 @@ +{ + "expression": ["within", { + "type": "Polygon", + "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]] + }], + "inputs": [[{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "Polygon", + "coordinates": [[[3, 3], [6, 6], [3, 3]]] + } + }]], + "expected": { + "compiled": { + "type": "boolean", + "isFeatureConstant": false, + "isZoomConstant": true, + "result": "success" + }, + "outputs": [false], + "serialized": ["within", { + "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]], + "type": "Polygon" + }] + } +} diff --git a/shared/test/data/expression-tests/within/point-within-polygon/test.json b/shared/test/data/expression-tests/within/point-within-polygon/test.json new file mode 100644 index 000000000..8da9fbdce --- /dev/null +++ b/shared/test/data/expression-tests/within/point-within-polygon/test.json @@ -0,0 +1,44 @@ +{ + "expression": ["within", { + "type": "Polygon", + "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]] + }], + "inputs": [[{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "Point", + "coordinates": [6, 6] + } + }], [{ + "zoom": 3, + "canonicalID": { + "z": 3, + "x": 3, + "y": 3 + } + }, { + "geometry": { + "type": "Point", + "coordinates": [2, 2] + } + }]], + "expected": { + "compiled": { + "type": "boolean", + "isFeatureConstant": false, + "isZoomConstant": true, + "result": "success" + }, + "outputs": [false, true], + "serialized": ["within", { + "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]], + "type": "Polygon" + }] + } +} diff --git a/shared/test/data/expression-tests/zoom/basic/test.json b/shared/test/data/expression-tests/zoom/basic/test.json new file mode 100644 index 000000000..a3ea663cd --- /dev/null +++ b/shared/test/data/expression-tests/zoom/basic/test.json @@ -0,0 +1,14 @@ +{ + "expression": ["interpolate", ["linear"], ["zoom"], 0, 0, 30, 30], + "inputs": [[{"zoom": 5}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [5], + "serialized": ["interpolate", ["linear"], ["zoom"], 0, 0, 30, 30] + } +} diff --git a/shared/test/data/expression-tests/zoom/invalid-nested-1/test.json b/shared/test/data/expression-tests/zoom/invalid-nested-1/test.json new file mode 100644 index 000000000..1f2601017 --- /dev/null +++ b/shared/test/data/expression-tests/zoom/invalid-nested-1/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["+", 0.5, ["interpolate", ["linear"], ["zoom"], 0, 0, 1, 1]], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/zoom/invalid-nested-2/test.json b/shared/test/data/expression-tests/zoom/invalid-nested-2/test.json new file mode 100644 index 000000000..06947e70d --- /dev/null +++ b/shared/test/data/expression-tests/zoom/invalid-nested-2/test.json @@ -0,0 +1,23 @@ +{ + "expression": [ + "interpolate", + ["linear"], + ["zoom"], + 0, + 0, + 1, + ["interpolate", ["linear"], ["zoom"], 0, 0, 1, 1] + ], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Only one zoom-based \"step\" or \"interpolate\" subexpression may be used in an expression." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/zoom/invalid-nested-3/test.json b/shared/test/data/expression-tests/zoom/invalid-nested-3/test.json new file mode 100644 index 000000000..277772c9d --- /dev/null +++ b/shared/test/data/expression-tests/zoom/invalid-nested-3/test.json @@ -0,0 +1,20 @@ +{ + "expression": [ + "let", + "x", + ["interpolate", ["linear"], ["zoom"], 0, 0, 1, 1], + ["interpolate", ["linear"], ["zoom"], 0, 0, 1, 1] + ], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Only one zoom-based \"step\" or \"interpolate\" subexpression may be used in an expression." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/zoom/invalid-nested-4/test.json b/shared/test/data/expression-tests/zoom/invalid-nested-4/test.json new file mode 100644 index 000000000..7f8005a02 --- /dev/null +++ b/shared/test/data/expression-tests/zoom/invalid-nested-4/test.json @@ -0,0 +1,19 @@ +{ + "expression": [ + "coalesce", + ["interpolate", ["linear"], ["zoom"], 0, 0, 1, 1], + ["interpolate", ["linear"], ["zoom"], 0, 0, 1, 1] + ], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "Only one zoom-based \"step\" or \"interpolate\" subexpression may be used in an expression." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/zoom/invalid-nested-5/test.json b/shared/test/data/expression-tests/zoom/invalid-nested-5/test.json new file mode 100644 index 000000000..d5e0619b9 --- /dev/null +++ b/shared/test/data/expression-tests/zoom/invalid-nested-5/test.json @@ -0,0 +1,20 @@ +{ + "expression": [ + "let", + "x", + ["interpolate", ["linear"], ["zoom"], 0, 0, 1, 1], + ["+", 0.5, ["get", "x"]] + ], + "inputs": [[{}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/zoom/invalid-no-curve/test.json b/shared/test/data/expression-tests/zoom/invalid-no-curve/test.json new file mode 100644 index 000000000..dc90f8289 --- /dev/null +++ b/shared/test/data/expression-tests/zoom/invalid-no-curve/test.json @@ -0,0 +1,15 @@ +{ + "expression": ["+", ["zoom"], 0], + "inputs": [[{"zoom": 5}, {}]], + "expected": { + "compiled": { + "result": "error", + "errors": [ + { + "key": "", + "error": "\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression." + } + ] + } + } +} diff --git a/shared/test/data/expression-tests/zoom/nested-coalesce/test.json b/shared/test/data/expression-tests/zoom/nested-coalesce/test.json new file mode 100644 index 000000000..664c53c1a --- /dev/null +++ b/shared/test/data/expression-tests/zoom/nested-coalesce/test.json @@ -0,0 +1,20 @@ +{ + "expression": [ + "coalesce", + ["interpolate", ["linear"], ["zoom"], 0, 0, 30, 30] + ], + "inputs": [[{"zoom": 5}, {}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": true, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [5], + "serialized": [ + "coalesce", + ["interpolate", ["linear"], ["zoom"], 0, 0, 30, 30] + ] + } +} diff --git a/shared/test/data/expression-tests/zoom/nested-let/test.json b/shared/test/data/expression-tests/zoom/nested-let/test.json new file mode 100644 index 000000000..480c46aa8 --- /dev/null +++ b/shared/test/data/expression-tests/zoom/nested-let/test.json @@ -0,0 +1,26 @@ +{ + "expression": [ + "let", + "x", + ["number", ["get", "a"]], + ["interpolate", ["linear"], ["zoom"], 0, 0, 30, ["var", "x"]] + ], + "inputs": [[{"zoom": 5}, {"a": 30}]], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": false, + "type": "number" + }, + "outputs": [ + {"error": "Expected value to be of type number, but found null instead."} + ], + "serialized": [ + "let", + "x", + ["number", ["get", "a"]], + ["interpolate", ["linear"], ["zoom"], 0, 0, 30, ["var", "x"]] + ] + } +} From 2a2d283eb7d75bcdf65a4111c6fe93c8b742f074 Mon Sep 17 00:00:00 2001 From: Stefan Mitterrutzner Date: Fri, 1 Aug 2025 11:49:20 +0200 Subject: [PATCH 2/2] fixes segmentation fault --- .../map/layers/tiled/vector/Tiled2dMapVectorStyleParser.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shared/src/map/layers/tiled/vector/Tiled2dMapVectorStyleParser.cpp b/shared/src/map/layers/tiled/vector/Tiled2dMapVectorStyleParser.cpp index d7777f3e8..4ef388d31 100644 --- a/shared/src/map/layers/tiled/vector/Tiled2dMapVectorStyleParser.cpp +++ b/shared/src/map/layers/tiled/vector/Tiled2dMapVectorStyleParser.cpp @@ -293,8 +293,8 @@ std::shared_ptr Tiled2dMapVectorStyleParser::parseValue(nlohmann::json js std::map, std::shared_ptr> mapping; - auto const countElements = json.size() - 3; - for (int i = 0; i != countElements; i += 2) { + auto const countElements = json.size() >= 3 ? json.size() - 3 : 0; + for (int i = 0; i < countElements; i += 2) { std::set values; if (json[2 + i].is_array()) { for(auto const value: json[2 + i]) { @@ -521,6 +521,8 @@ ValueVariant Tiled2dMapVectorStyleParser::getVariant(const nlohmann::json &json) return json.get(); } else if (json.is_boolean()) { return json.get(); + } else if (json.is_array() && json.empty()) { + return std::vector(); } else if (json.is_array() && json[0].is_number()) { auto floatVector = std::vector(); floatVector.reserve(json.size());