import { Cartesian2 } from "../../Source/Cesium.js"; import { Cartesian3 } from "../../Source/Cesium.js"; import { Cartesian4 } from "../../Source/Cesium.js"; import { Color } from "../../Source/Cesium.js"; import { Math as CesiumMath } from "../../Source/Cesium.js"; import { Expression } from "../../Source/Cesium.js"; import { ExpressionNodeType } from "../../Source/Cesium.js"; describe("Scene/Expression", function () { function MockFeature() { this._properties = {}; this._className = undefined; this._inheritedClassName = undefined; this.content = { tileset: { timeSinceLoad: 0.0, }, }; } MockFeature.prototype.addProperty = function (name, value) { this._properties[name] = value; }; MockFeature.prototype.getPropertyInherited = function (name) { return this._properties[name]; }; MockFeature.prototype.setClass = function (className) { this._className = className; }; MockFeature.prototype.setInheritedClass = function (className) { this._inheritedClassName = className; }; MockFeature.prototype.isExactClass = function (className) { return this._className === className; }; MockFeature.prototype.isClass = function (className) { return ( this._className === className || this._inheritedClassName === className ); }; MockFeature.prototype.getExactClassName = function () { return this._className; }; it("parses backslashes", function () { var expression = new Expression('"\\he\\\\\\ll\\\\o"'); expect(expression.evaluate(undefined)).toEqual("\\he\\\\\\ll\\\\o"); }); it("evaluates variable", function () { var feature = new MockFeature(); feature.addProperty("height", 10); feature.addProperty("width", 5); feature.addProperty("string", "hello"); feature.addProperty("boolean", true); feature.addProperty("vector", Cartesian3.UNIT_X); feature.addProperty("null", null); feature.addProperty("undefined", undefined); var expression = new Expression("${height}"); expect(expression.evaluate(feature)).toEqual(10); expression = new Expression("'${height}'"); expect(expression.evaluate(feature)).toEqual("10"); expression = new Expression("${height}/${width}"); expect(expression.evaluate(feature)).toEqual(2); expression = new Expression("${string}"); expect(expression.evaluate(feature)).toEqual("hello"); expression = new Expression("'replace ${string}'"); expect(expression.evaluate(feature)).toEqual("replace hello"); expression = new Expression("'replace ${string} multiple ${height}'"); expect(expression.evaluate(feature)).toEqual("replace hello multiple 10"); expression = new Expression('"replace ${string}"'); expect(expression.evaluate(feature)).toEqual("replace hello"); expression = new Expression("'replace ${string'"); expect(expression.evaluate(feature)).toEqual("replace ${string"); expression = new Expression("${boolean}"); expect(expression.evaluate(feature)).toEqual(true); expression = new Expression("'${boolean}'"); expect(expression.evaluate(feature)).toEqual("true"); expression = new Expression("${vector}"); expect(expression.evaluate(feature)).toEqual(Cartesian3.UNIT_X); expression = new Expression("'${vector}'"); expect(expression.evaluate(feature)).toEqual(Cartesian3.UNIT_X.toString()); expression = new Expression("${null}"); expect(expression.evaluate(feature)).toEqual(null); expression = new Expression("'${null}'"); expect(expression.evaluate(feature)).toEqual(""); expression = new Expression("${undefined}"); expect(expression.evaluate(feature)).toEqual(undefined); expression = new Expression("'${undefined}'"); expect(expression.evaluate(feature)).toEqual(""); expression = new Expression( "abs(-${height}) + max(${height}, ${width}) + clamp(${height}, 0, 2)" ); expect(expression.evaluate(feature)).toEqual(22); expect(function () { return new Expression("${height"); }).toThrowRuntimeError(); }); it("evaluates variable to undefined if feature is undefined", function () { var expression = new Expression("${height}"); expect(expression.evaluate(undefined)).toBeUndefined(); expression = new Expression("${vector.x}"); expect(expression.evaluate(undefined)).toBeUndefined(); expression = new Expression("${feature}"); expect(expression.evaluate(undefined)).toBeUndefined(); expression = new Expression("${feature.vector}"); expect(expression.evaluate(undefined)).toBeUndefined(); expression = new Expression('${vector["x"]}'); expect(expression.evaluate(undefined)).toBeUndefined(); expression = new Expression('${feature["vector"]}'); expect(expression.evaluate(undefined)).toBeUndefined(); // Evaluating inside a string is an exception. "" is returned instead of "undefined" expression = new Expression("'${height}'"); expect(expression.evaluate(undefined)).toBe(""); }); it("evaluates with defines", function () { var defines = { halfHeight: "${Height}/2", }; var feature = new MockFeature(); feature.addProperty("Height", 10); var expression = new Expression("${halfHeight}", defines); expect(expression.evaluate(feature)).toEqual(5); }); it("evaluates with defines, honoring order of operations", function () { var defines = { value: "1 + 2", }; var expression = new Expression("5.0 * ${value}", defines); expect(expression.evaluate(undefined)).toEqual(15); }); it("evaluate takes result argument", function () { var expression = new Expression("vec3(1.0)"); var result = new Cartesian3(); var value = expression.evaluate(undefined, result); expect(value).toEqual(new Cartesian3(1.0, 1.0, 1.0)); expect(value).toBe(result); }); it("evaluate takes a color result argument", function () { var expression = new Expression('color("red")'); var result = new Color(); var value = expression.evaluate(undefined, result); expect(value).toEqual(Color.RED); expect(value).toBe(result); }); it("gets expressions", function () { var expressionString = "(regExp('^Chest').test(${County})) && (${YearBuilt} >= 1970)"; var expression = new Expression(expressionString); expect(expression.expression).toEqual(expressionString); }); it("throws on invalid expressions", function () { expect(function () { return new Expression(false); }).toThrowDeveloperError(); expect(function () { return new Expression(""); }).toThrowRuntimeError(); expect(function () { return new Expression("this"); }).toThrowRuntimeError(); expect(function () { return new Expression("2; 3;"); }).toThrowRuntimeError(); }); it("throws on unknown characters", function () { expect(function () { return new Expression("#"); }).toThrowRuntimeError(); }); it("throws on unmatched parenthesis", function () { expect(function () { return new Expression("((true)"); }).toThrowRuntimeError(); expect(function () { return new Expression("(true))"); }).toThrowRuntimeError(); }); it("throws on unknown identifiers", function () { expect(function () { return new Expression("flse"); }).toThrowRuntimeError(); }); it("throws on unknown function calls", function () { expect(function () { return new Expression("unknown()"); }).toThrowRuntimeError(); }); it("throws on unknown member function calls", function () { expect(function () { return new Expression("regExp().unknown()"); }).toThrowRuntimeError(); }); it("throws with unsupported operators", function () { expect(function () { return new Expression("~1"); }).toThrowRuntimeError(); expect(function () { return new Expression("2 | 3"); }).toThrowRuntimeError(); expect(function () { return new Expression("2 & 3"); }).toThrowRuntimeError(); expect(function () { return new Expression("2 << 3"); }).toThrowRuntimeError(); expect(function () { return new Expression("2 >> 3"); }).toThrowRuntimeError(); expect(function () { return new Expression("2 >>> 3"); }).toThrowRuntimeError(); }); it("evaluates literal null", function () { var expression = new Expression("null"); expect(expression.evaluate(undefined)).toEqual(null); }); it("evaluates literal undefined", function () { var expression = new Expression("undefined"); expect(expression.evaluate(undefined)).toEqual(undefined); }); it("evaluates literal boolean", function () { var expression = new Expression("true"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("false"); expect(expression.evaluate(undefined)).toEqual(false); }); it("converts to literal boolean", function () { var expression = new Expression("Boolean()"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("Boolean(1)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('Boolean("true")'); expect(expression.evaluate(undefined)).toEqual(true); }); it("evaluates literal number", function () { var expression = new Expression("1"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("0"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("NaN"); expect(expression.evaluate(undefined)).toEqual(NaN); expression = new Expression("Infinity"); expect(expression.evaluate(undefined)).toEqual(Infinity); }); it("evaluates math constants", function () { var expression = new Expression("Math.PI"); expect(expression.evaluate(undefined)).toEqual(Math.PI); expression = new Expression("Math.E"); expect(expression.evaluate(undefined)).toEqual(Math.E); }); it("evaluates number constants", function () { var expression = new Expression("Number.POSITIVE_INFINITY"); expect(expression.evaluate(undefined)).toEqual(Number.POSITIVE_INFINITY); }); it("converts to literal number", function () { var expression = new Expression("Number()"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression('Number("1")'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("Number(true)"); expect(expression.evaluate(undefined)).toEqual(1); }); it("evaluates literal string", function () { var expression = new Expression("'hello'"); expect(expression.evaluate(undefined)).toEqual("hello"); expression = new Expression("'Cesium'"); expect(expression.evaluate(undefined)).toEqual("Cesium"); expression = new Expression('"Cesium"'); expect(expression.evaluate(undefined)).toEqual("Cesium"); }); it("converts to literal string", function () { var expression = new Expression("String()"); expect(expression.evaluate(undefined)).toEqual(""); expression = new Expression("String(1)"); expect(expression.evaluate(undefined)).toEqual("1"); expression = new Expression("String(true)"); expect(expression.evaluate(undefined)).toEqual("true"); }); it("evaluates literal color", function () { var expression = new Expression("color('#ffffff')"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("color('#00FFFF')"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.CYAN) ); expression = new Expression("color('#fff')"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("color('#0FF')"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.CYAN) ); expression = new Expression("color('white')"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("color('cyan')"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.CYAN) ); expression = new Expression("color('white', 0.5)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.fromAlpha(Color.WHITE, 0.5)) ); expression = new Expression("rgb(255, 255, 255)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("rgb(100, 255, 190)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.fromBytes(100, 255, 190)) ); expression = new Expression("hsl(0, 0, 1)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("hsl(1.0, 0.6, 0.7)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.fromHsl(1.0, 0.6, 0.7)) ); expression = new Expression("rgba(255, 255, 255, 0.5)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.fromAlpha(Color.WHITE, 0.5)) ); expression = new Expression("rgba(100, 255, 190, 0.25)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.fromBytes(100, 255, 190, 0.25 * 255)) ); expression = new Expression("hsla(0, 0, 1, 0.5)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(new Color(1.0, 1.0, 1.0, 0.5)) ); expression = new Expression("hsla(1.0, 0.6, 0.7, 0.75)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.fromHsl(1.0, 0.6, 0.7, 0.75)) ); expression = new Expression("color()"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.WHITE) ); }); it("evaluates literal color with result parameter", function () { var color = new Color(); var expression = new Expression("color('#0000ff')"); expect(expression.evaluate(undefined, color)).toEqual(Color.BLUE); expect(color).toEqual(Color.BLUE); expression = new Expression("color('#f00')"); expect(expression.evaluate(undefined, color)).toEqual(Color.RED); expect(color).toEqual(Color.RED); expression = new Expression("color('cyan')"); expect(expression.evaluate(undefined, color)).toEqual(Color.CYAN); expect(color).toEqual(Color.CYAN); expression = new Expression("color('white', 0.5)"); expect(expression.evaluate(undefined, color)).toEqual( new Color(1.0, 1.0, 1.0, 0.5) ); expect(color).toEqual(new Color(1.0, 1.0, 1.0, 0.5)); expression = new Expression("rgb(0, 0, 0)"); expect(expression.evaluate(undefined, color)).toEqual(Color.BLACK); expect(color).toEqual(Color.BLACK); expression = new Expression("hsl(0, 0, 1)"); expect(expression.evaluate(undefined, color)).toEqual(Color.WHITE); expect(color).toEqual(Color.WHITE); expression = new Expression("rgba(255, 0, 255, 0.5)"); expect(expression.evaluate(undefined, color)).toEqual( new Color(1.0, 0, 1.0, 0.5) ); expect(color).toEqual(new Color(1.0, 0, 1.0, 0.5)); expression = new Expression("hsla(0, 0, 1, 0.5)"); expect(expression.evaluate(undefined, color)).toEqual( new Color(1.0, 1.0, 1.0, 0.5) ); expect(color).toEqual(new Color(1.0, 1.0, 1.0, 0.5)); expression = new Expression("color()"); expect(expression.evaluate(undefined, color)).toEqual(Color.WHITE); expect(color).toEqual(Color.WHITE); }); it("evaluates color with expressions as arguments", function () { var feature = new MockFeature(); feature.addProperty("hex6", "#ffffff"); feature.addProperty("hex3", "#fff"); feature.addProperty("keyword", "white"); feature.addProperty("alpha", 0.2); var expression = new Expression("color(${hex6})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("color(${hex3})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("color(${keyword})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("color(${keyword}, ${alpha} + 0.6)"); expect(expression.evaluate(feature).x).toEqual(1.0); expect(expression.evaluate(feature).y).toEqual(1.0); expect(expression.evaluate(feature).z).toEqual(1.0); expect(expression.evaluate(feature).w).toEqual(0.8); }); it("evaluates rgb with expressions as arguments", function () { var feature = new MockFeature(); feature.addProperty("red", 100); feature.addProperty("green", 200); feature.addProperty("blue", 255); var expression = new Expression("rgb(${red}, ${green}, ${blue})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromBytes(100, 200, 255)) ); expression = new Expression("rgb(${red}/2, ${green}/2, ${blue})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromBytes(50, 100, 255)) ); }); it("evaluates hsl with expressions as arguments", function () { var feature = new MockFeature(); feature.addProperty("h", 0.0); feature.addProperty("s", 0.0); feature.addProperty("l", 1.0); var expression = new Expression("hsl(${h}, ${s}, ${l})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("hsl(${h} + 0.2, ${s} + 1.0, ${l} - 0.5)"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromHsl(0.2, 1.0, 0.5)) ); }); it("evaluates rgba with expressions as arguments", function () { var feature = new MockFeature(); feature.addProperty("red", 100); feature.addProperty("green", 200); feature.addProperty("blue", 255); feature.addProperty("a", 0.3); var expression = new Expression("rgba(${red}, ${green}, ${blue}, ${a})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromBytes(100, 200, 255, 0.3 * 255)) ); expression = new Expression( "rgba(${red}/2, ${green}/2, ${blue}, ${a} * 2)" ); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromBytes(50, 100, 255, 0.6 * 255)) ); }); it("evaluates hsla with expressions as arguments", function () { var feature = new MockFeature(); feature.addProperty("h", 0.0); feature.addProperty("s", 0.0); feature.addProperty("l", 1.0); feature.addProperty("a", 1.0); var expression = new Expression("hsla(${h}, ${s}, ${l}, ${a})"); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression( "hsla(${h} + 0.2, ${s} + 1.0, ${l} - 0.5, ${a} / 4)" ); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromHsl(0.2, 1.0, 0.5, 0.25)) ); }); it("evaluates rgba with expressions as arguments", function () { var feature = new MockFeature(); feature.addProperty("red", 100); feature.addProperty("green", 200); feature.addProperty("blue", 255); feature.addProperty("alpha", 0.5); var expression = new Expression( "rgba(${red}, ${green}, ${blue}, ${alpha})" ); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromBytes(100, 200, 255, 0.5 * 255)) ); expression = new Expression( "rgba(${red}/2, ${green}/2, ${blue}, ${alpha} + 0.1)" ); expect(expression.evaluate(feature)).toEqual( Cartesian4.fromColor(Color.fromBytes(50, 100, 255, 0.6 * 255)) ); }); it("color constructors throw with wrong number of arguments", function () { expect(function () { return new Expression("rgb(255, 255)"); }).toThrowRuntimeError(); expect(function () { return new Expression("hsl(1, 1)"); }).toThrowRuntimeError(); expect(function () { return new Expression("rgba(255, 255, 255)"); }).toThrowRuntimeError(); expect(function () { return new Expression("hsla(1, 1, 1)"); }).toThrowRuntimeError(); }); it("evaluates color properties (r, g, b, a)", function () { var expression = new Expression("color('#ffffff').r"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("rgb(255, 255, 0).g"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('color("cyan").b'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("rgba(255, 255, 0, 0.5).a"); expect(expression.evaluate(undefined)).toEqual(0.5); }); it("evaluates color properties (x, y, z, w)", function () { var expression = new Expression("color('#ffffff').x"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("rgb(255, 255, 0).y"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('color("cyan").z'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("rgba(255, 255, 0, 0.5).w"); expect(expression.evaluate(undefined)).toEqual(0.5); }); it("evaluates color properties ([0], [1], [2]. [3])", function () { var expression = new Expression("color('#ffffff')[0]"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("rgb(255, 255, 0)[1]"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('color("cyan")[2]'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("rgba(255, 255, 0, 0.5)[3]"); expect(expression.evaluate(undefined)).toEqual(0.5); }); it('evaluates color properties (["r"], ["g"], ["b"], ["a"])', function () { var expression = new Expression("color('#ffffff')[\"r\"]"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('rgb(255, 255, 0)["g"]'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('color("cyan")["b"]'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('rgba(255, 255, 0, 0.5)["a"]'); expect(expression.evaluate(undefined)).toEqual(0.5); }); it('evaluates color properties (["x"], ["y"], ["z"], ["w"])', function () { var expression = new Expression("color('#ffffff')[\"x\"]"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('rgb(255, 255, 0)["y"]'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('color("cyan")["z"]'); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression('rgba(255, 255, 0, 0.5)["w"]'); expect(expression.evaluate(undefined)).toEqual(0.5); }); it("evaluates vec2", function () { var expression = new Expression("vec2(2.0)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(2.0, 2.0)); expression = new Expression("vec2(3.0, 4.0)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(3.0, 4.0)); expression = new Expression("vec2(vec2(3.0, 4.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(3.0, 4.0)); expression = new Expression("vec2(vec3(3.0, 4.0, 5.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(3.0, 4.0)); expression = new Expression("vec2(vec4(3.0, 4.0, 5.0, 6.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(3.0, 4.0)); }); it("throws if vec2 has invalid number of arguments", function () { var expression = new Expression("vec2()"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec2(3.0, 4.0, 5.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec2(vec2(3.0, 4.0), 5.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("throws if vec2 has invalid argument", function () { var expression = new Expression('vec2("1")'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates vec3", function () { var expression = new Expression("vec3(2.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(2.0, 2.0, 2.0) ); expression = new Expression("vec3(3.0, 4.0, 5.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(3.0, 4.0, 5.0) ); expression = new Expression("vec3(vec2(3.0, 4.0), 5.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(3.0, 4.0, 5.0) ); expression = new Expression("vec3(3.0, vec2(4.0, 5.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(3.0, 4.0, 5.0) ); expression = new Expression("vec3(vec3(3.0, 4.0, 5.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(3.0, 4.0, 5.0) ); expression = new Expression("vec3(vec4(3.0, 4.0, 5.0, 6.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(3.0, 4.0, 5.0) ); }); it("throws if vec3 has invalid number of arguments", function () { var expression = new Expression("vec3()"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec3(3.0, 4.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec3(3.0, 4.0, 5.0, 6.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec3(vec2(3.0, 4.0), vec2(5.0, 6.0))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec3(vec4(3.0, 4.0, 5.0, 6.0), 1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("throws if vec3 has invalid argument", function () { var expression = new Expression('vec3(1.0, "1.0", 2.0)'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates vec4", function () { var expression = new Expression("vec4(2.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(2.0, 2.0, 2.0, 2.0) ); expression = new Expression("vec4(3.0, 4.0, 5.0, 6.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3.0, 4.0, 5.0, 6.0) ); expression = new Expression("vec4(vec2(3.0, 4.0), 5.0, 6.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3.0, 4.0, 5.0, 6.0) ); expression = new Expression("vec4(3.0, vec2(4.0, 5.0), 6.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3.0, 4.0, 5.0, 6.0) ); expression = new Expression("vec4(3.0, 4.0, vec2(5.0, 6.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3.0, 4.0, 5.0, 6.0) ); expression = new Expression("vec4(vec3(3.0, 4.0, 5.0), 6.0)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3.0, 4.0, 5.0, 6.0) ); expression = new Expression("vec4(3.0, vec3(4.0, 5.0, 6.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3.0, 4.0, 5.0, 6.0) ); expression = new Expression("vec4(vec4(3.0, 4.0, 5.0, 6.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3.0, 4.0, 5.0, 6.0) ); }); it("throws if vec4 has invalid number of arguments", function () { var expression = new Expression("vec4()"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec4(3.0, 4.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec4(3.0, 4.0, 5.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec4(3.0, 4.0, 5.0, 6.0, 7.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("vec4(vec3(3.0, 4.0, 5.0))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("throws if vec4 has invalid argument", function () { var expression = new Expression('vec4(1.0, "2.0", 3.0, 4.0)'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates vector with expressions as arguments", function () { var feature = new MockFeature(); feature.addProperty("height", 2); feature.addProperty("width", 4); feature.addProperty("depth", 3); feature.addProperty("scale", 1); var expression = new Expression( "vec4(${height}, ${width}, ${depth}, ${scale})" ); expect(expression.evaluate(feature)).toEqual( new Cartesian4(2.0, 4.0, 3.0, 1.0) ); }); it("evaluates expression with multiple nested vectors", function () { var expression = new Expression( "vec4(vec2(1, 2)[vec3(6, 1, 5).y], 2, vec4(1.0).w, 5)" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(2.0, 2.0, 1.0, 5.0) ); }); it("evaluates vector properties (x, y, z, w)", function () { var expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).x"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).y"); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).z"); expect(expression.evaluate(undefined)).toEqual(3.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).w"); expect(expression.evaluate(undefined)).toEqual(4.0); }); it("evaluates vector properties (r, g, b, a)", function () { var expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).r"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).g"); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).b"); expect(expression.evaluate(undefined)).toEqual(3.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0).a"); expect(expression.evaluate(undefined)).toEqual(4.0); }); it("evaluates vector properties ([0], [1], [2], [3])", function () { var expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0)[0]"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0)[1]"); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0)[2]"); expect(expression.evaluate(undefined)).toEqual(3.0); expression = new Expression("vec4(1.0, 2.0, 3.0, 4.0)[3]"); expect(expression.evaluate(undefined)).toEqual(4.0); }); it('evaluates vector properties (["x"], ["y"], ["z"]. ["w"])', function () { var expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["x"]'); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["y"]'); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["z"]'); expect(expression.evaluate(undefined)).toEqual(3.0); expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["w"]'); expect(expression.evaluate(undefined)).toEqual(4.0); }); it('evaluates vector properties (["r"], ["g"], ["b"]. ["a"])', function () { var expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["r"]'); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["g"]'); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["b"]'); expect(expression.evaluate(undefined)).toEqual(3.0); expression = new Expression('vec4(1.0, 2.0, 3.0, 4.0)["a"]'); expect(expression.evaluate(undefined)).toEqual(4.0); }); it("evaluates unary not", function () { var expression = new Expression("!true"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("!!true"); expect(expression.evaluate(undefined)).toEqual(true); }); it("throws if unary not takes invalid argument", function () { var expression = new Expression('!"true"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates unary negative", function () { var expression = new Expression("-5"); expect(expression.evaluate(undefined)).toEqual(-5); expression = new Expression("-(-5)"); expect(expression.evaluate(undefined)).toEqual(5); }); it("throws if unary negative takes invalid argument", function () { var expression = new Expression('-"56"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates unary positive", function () { var expression = new Expression("+5"); expect(expression.evaluate(undefined)).toEqual(5); }); it("throws if unary positive takes invalid argument", function () { var expression = new Expression('+"56"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary addition", function () { var expression = new Expression("1 + 2"); expect(expression.evaluate(undefined)).toEqual(3); expression = new Expression("1 + 2 + 3 + 4"); expect(expression.evaluate(undefined)).toEqual(10); }); it("evaluates binary addition with strings", function () { var expression = new Expression('1 + "10"'); expect(expression.evaluate(undefined)).toEqual("110"); expression = new Expression('"10" + 1'); expect(expression.evaluate(undefined)).toEqual("101"); expression = new Expression('"name_" + "building"'); expect(expression.evaluate(undefined)).toEqual("name_building"); expression = new Expression('"name_" + true'); expect(expression.evaluate(undefined)).toEqual("name_true"); expression = new Expression('"name_" + null'); expect(expression.evaluate(undefined)).toEqual("name_null"); expression = new Expression('"name_" + undefined'); expect(expression.evaluate(undefined)).toEqual("name_undefined"); expression = new Expression('"name_" + vec2(1.1)'); expect(expression.evaluate(undefined)).toEqual("name_(1.1, 1.1)"); expression = new Expression('"name_" + vec3(1.1)'); expect(expression.evaluate(undefined)).toEqual("name_(1.1, 1.1, 1.1)"); expression = new Expression('"name_" + vec4(1.1)'); expect(expression.evaluate(undefined)).toEqual("name_(1.1, 1.1, 1.1, 1.1)"); expression = new Expression('"name_" + regExp("a")'); expect(expression.evaluate(undefined)).toEqual("name_/a/"); }); it("throws if binary addition takes invalid arguments", function () { var expression = new Expression("vec2(1.0) + vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1.0 + vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary subtraction", function () { var expression = new Expression("2 - 1"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("4 - 3 - 2 - 1"); expect(expression.evaluate(undefined)).toEqual(-2); }); it("throws if binary subtraction takes invalid arguments", function () { var expression = new Expression("vec2(1.0) - vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1.0 - vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('"name1" - "name2"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary multiplication", function () { var expression = new Expression("1 * 2"); expect(expression.evaluate(undefined)).toEqual(2); expression = new Expression("1 * 2 * 3 * 4"); expect(expression.evaluate(undefined)).toEqual(24); }); it("throws if binary multiplication takes invalid arguments", function () { var expression = new Expression("vec2(1.0) * vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('vec2(1.0) * "name"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary division", function () { var expression = new Expression("2 / 1"); expect(expression.evaluate(undefined)).toEqual(2); expression = new Expression("1/2"); expect(expression.evaluate(undefined)).toEqual(0.5); expression = new Expression("24 / -4 / 2"); expect(expression.evaluate(undefined)).toEqual(-3); }); it("throws if binary division takes invalid arguments", function () { var expression = new Expression("vec2(1.0) / vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('vec2(1.0) / "2.0"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1.0 / vec4(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary modulus", function () { var expression = new Expression("2 % 1"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("6 % 4 % 3"); expect(expression.evaluate(undefined)).toEqual(2); }); it("throws if binary modulus takes invalid arguments", function () { var expression = new Expression("vec2(1.0) % vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('vec2(1.0) % "2.0"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1.0 % vec4(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary equals strict", function () { var expression = new Expression("'hello' === 'hello'"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("1 === 2"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("false === true === false"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('1 === "1"'); expect(expression.evaluate(undefined)).toEqual(false); }); it("evaluates binary not equals strict", function () { var expression = new Expression("'hello' !== 'hello'"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("1 !== 2"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("false !== true !== false"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('1 !== "1"'); expect(expression.evaluate(undefined)).toEqual(true); }); it("evaluates binary less than", function () { var expression = new Expression("2 < 3"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("2 < 2"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("3 < 2"); expect(expression.evaluate(undefined)).toEqual(false); }); it("throws if binary less than takes invalid arguments", function () { var expression = new Expression("vec2(1.0) < vec2(2.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1 < vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("true < false"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("color('blue') < 10"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary less than or equals", function () { var expression = new Expression("2 <= 3"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("2 <= 2"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("3 <= 2"); expect(expression.evaluate(undefined)).toEqual(false); }); it("throws if binary less than or equals takes invalid arguments", function () { var expression = new Expression("vec2(1.0) <= vec2(2.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1 <= vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('1.0 <= "5"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("true <= false"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("color('blue') <= 10"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary greater than", function () { var expression = new Expression("2 > 3"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("2 > 2"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("3 > 2"); expect(expression.evaluate(undefined)).toEqual(true); }); it("throws if binary greater than takes invalid arguments", function () { var expression = new Expression("vec2(1.0) > vec2(2.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1 > vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('1.0 > "5"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("true > false"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("color('blue') > 10"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates binary greater than or equals", function () { var expression = new Expression("2 >= 3"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("2 >= 2"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("3 >= 2"); expect(expression.evaluate(undefined)).toEqual(true); }); it("throws if binary greater than or equals takes invalid arguments", function () { var expression = new Expression("vec2(1.0) >= vec2(2.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1 >= vec3(1.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('1.0 >= "5"'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("true >= false"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("color('blue') >= 10"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates logical and", function () { var expression = new Expression("false && false"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("false && true"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("true && true"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("2 && color('red')"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("throws with invalid and operands", function () { var expression = new Expression("2 && true"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("true && color('red')"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates logical or", function () { var expression = new Expression("false || false"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("false || true"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("true || true"); expect(expression.evaluate(undefined)).toEqual(true); }); it("throws with invalid or operands", function () { var expression = new Expression("2 || false"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("false || color('red')"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates color operations", function () { var expression = new Expression("+rgba(255, 0, 0, 1.0)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.RED) ); expression = new Expression("rgba(255, 0, 0, 0.5) + rgba(0, 0, 255, 0.5)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.MAGENTA) ); expression = new Expression("rgba(0, 255, 255, 1.0) - rgba(0, 255, 0, 0)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.BLUE) ); expression = new Expression( "rgba(255, 255, 255, 1.0) * rgba(255, 0, 0, 1.0)" ); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.RED) ); expression = new Expression("rgba(255, 255, 0, 1.0) * 1.0"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.YELLOW) ); expression = new Expression("1 * rgba(255, 255, 0, 1.0)"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.YELLOW) ); expression = new Expression( "rgba(255, 255, 255, 1.0) / rgba(255, 255, 255, 1.0)" ); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(Color.WHITE) ); expression = new Expression("rgba(255, 255, 255, 1.0) / 2"); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(new Color(0.5, 0.5, 0.5, 0.5)) ); expression = new Expression( "rgba(255, 255, 255, 1.0) % rgba(255, 255, 255, 1.0)" ); expect(expression.evaluate(undefined)).toEqual( Cartesian4.fromColor(new Color(0, 0, 0, 0)) ); expression = new Expression("color('green') === color('green')"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("color('green') !== color('green')"); expect(expression.evaluate(undefined)).toEqual(false); }); it("evaluates vector operations", function () { var expression = new Expression("+vec2(1, 2)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(1, 2)); expression = new Expression("+vec3(1, 2, 3)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(1, 2, 3)); expression = new Expression("+vec4(1, 2, 3, 4)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian4(1, 2, 3, 4)); expression = new Expression("-vec2(1, 2)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(-1, -2)); expression = new Expression("-vec3(1, 2, 3)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(-1, -2, -3)); expression = new Expression("-vec4(1, 2, 3, 4)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(-1, -2, -3, -4) ); expression = new Expression("vec2(1, 2) + vec2(3, 4)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(4, 6)); expression = new Expression("vec3(1, 2, 3) + vec3(3, 4, 5)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(4, 6, 8)); expression = new Expression("vec4(1, 2, 3, 4) + vec4(3, 4, 5, 6)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian4(4, 6, 8, 10)); expression = new Expression("vec2(1, 2) - vec2(3, 4)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(-2, -2)); expression = new Expression("vec3(1, 2, 3) - vec3(3, 4, 5)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(-2, -2, -2)); expression = new Expression("vec4(1, 2, 3, 4) - vec4(3, 4, 5, 6)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(-2, -2, -2, -2) ); expression = new Expression("vec2(1, 2) * vec2(3, 4)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(3, 8)); expression = new Expression("vec2(1, 2) * 3.0"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(3, 6)); expression = new Expression("3.0 * vec2(1, 2)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(3, 6)); expression = new Expression("vec3(1, 2, 3) * vec3(3, 4, 5)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(3, 8, 15)); expression = new Expression("vec3(1, 2, 3) * 3.0"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(3, 6, 9)); expression = new Expression("3.0 * vec3(1, 2, 3)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(3, 6, 9)); expression = new Expression("vec4(1, 2, 3, 4) * vec4(3, 4, 5, 6)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(3, 8, 15, 24) ); expression = new Expression("vec4(1, 2, 3, 4) * 3.0"); expect(expression.evaluate(undefined)).toEqual(new Cartesian4(3, 6, 9, 12)); expression = new Expression("3.0 * vec4(1, 2, 3, 4)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian4(3, 6, 9, 12)); expression = new Expression("vec2(1, 2) / vec2(2, 5)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0.5, 0.4)); expression = new Expression("vec2(1, 2) / 2.0"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0.5, 1.0)); expression = new Expression("vec3(1, 2, 3) / vec3(2, 5, 3)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(0.5, 0.4, 1.0) ); expression = new Expression("vec3(1, 2, 3) / 2.0"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(0.5, 1.0, 1.5) ); expression = new Expression("vec4(1, 2, 3, 4) / vec4(2, 5, 3, 2)"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(0.5, 0.4, 1.0, 2.0) ); expression = new Expression("vec4(1, 2, 3, 4) / 2.0"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(0.5, 1.0, 1.5, 2.0) ); expression = new Expression("vec2(2, 3) % vec2(3, 3)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(2, 0)); expression = new Expression("vec3(2, 3, 4) % vec3(3, 3, 3)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(2, 0, 1)); expression = new Expression("vec4(2, 3, 4, 5) % vec4(3, 3, 3, 2)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian4(2, 0, 1, 1)); expression = new Expression("vec2(1, 2) === vec2(1, 2)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("vec3(1, 2, 3) === vec3(1, 2, 3)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("vec4(1, 2, 3, 4) === vec4(1, 2, 3, 4)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("vec2(1, 2) !== vec2(1, 2)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("vec3(1, 2, 3) !== vec3(1, 2, 3)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("vec4(1, 2, 3, 4) !== vec4(1, 2, 3, 4)"); expect(expression.evaluate(undefined)).toEqual(false); }); it("evaluates color toString function", function () { var expression = new Expression('color("red").toString()'); expect(expression.evaluate(undefined)).toEqual("(1, 0, 0, 1)"); expression = new Expression("rgba(0, 0, 255, 0.5).toString()"); expect(expression.evaluate(undefined)).toEqual("(0, 0, 1, 0.5)"); }); it("evaluates vector toString function", function () { var feature = new MockFeature(); feature.addProperty("property", new Cartesian4(1, 2, 3, 4)); var expression = new Expression("vec2(1, 2).toString()"); expect(expression.evaluate(undefined)).toEqual("(1, 2)"); expression = new Expression("vec3(1, 2, 3).toString()"); expect(expression.evaluate(undefined)).toEqual("(1, 2, 3)"); expression = new Expression("vec4(1, 2, 3, 4).toString()"); expect(expression.evaluate(undefined)).toEqual("(1, 2, 3, 4)"); expression = new Expression("${property}.toString()"); expect(expression.evaluate(feature)).toEqual("(1, 2, 3, 4)"); }); it("evaluates isNaN function", function () { var expression = new Expression("isNaN()"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("isNaN(NaN)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("isNaN(1)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("isNaN(Infinity)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("isNaN(null)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("isNaN(true)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression('isNaN("hello")'); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('isNaN(color("white"))'); expect(expression.evaluate(undefined)).toEqual(true); }); it("evaluates isFinite function", function () { var expression = new Expression("isFinite()"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("isFinite(NaN)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("isFinite(1)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("isFinite(Infinity)"); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("isFinite(null)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("isFinite(true)"); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('isFinite("hello")'); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression('isFinite(color("white"))'); expect(expression.evaluate(undefined)).toEqual(false); }); it("evaluates isExactClass function", function () { var feature = new MockFeature(); feature.setClass("door"); var expression = new Expression('isExactClass("door")'); expect(expression.evaluate(feature)).toEqual(true); expression = new Expression('isExactClass("roof")'); expect(expression.evaluate(feature)).toEqual(false); expect(expression.evaluate(undefined)).toEqual(false); }); it("throws if isExactClass takes an invalid number of arguments", function () { expect(function () { return new Expression("isExactClass()"); }).toThrowRuntimeError(); expect(function () { return new Expression('isExactClass("door", "roof")'); }).toThrowRuntimeError(); }); it("evaluates isClass function", function () { var feature = new MockFeature(); feature.setClass("door"); feature.setInheritedClass("building"); var expression = new Expression('isClass("door") && isClass("building")'); expect(expression.evaluate(feature)).toEqual(true); expect(expression.evaluate(undefined)).toEqual(false); }); it("throws if isClass takes an invalid number of arguments", function () { expect(function () { return new Expression("isClass()"); }).toThrowRuntimeError(); expect(function () { return new Expression('isClass("door", "building")'); }).toThrowRuntimeError(); }); it("evaluates getExactClassName function", function () { var feature = new MockFeature(); feature.setClass("door"); var expression = new Expression("getExactClassName()"); expect(expression.evaluate(feature)).toEqual("door"); expect(expression.evaluate(undefined)).toBeUndefined(); }); it("throws if getExactClassName takes an invalid number of arguments", function () { expect(function () { return new Expression('getExactClassName("door")'); }).toThrowRuntimeError(); }); it("throws if built-in unary function is given an invalid argument", function () { // Argument must be a number or vector var expression = new Expression('abs("-1")'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates abs function", function () { var expression = new Expression("abs(-1)"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("abs(1)"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("abs(vec2(-1.0, 1.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(1.0, 1.0)); expression = new Expression("abs(vec3(-1.0, 1.0, 0.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(1.0, 1.0, 0.0) ); expression = new Expression("abs(vec4(-1.0, 1.0, 0.0, -1.2))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(1.0, 1.0, 0.0, 1.2) ); }); it("throws if abs function takes an invalid number of arguments", function () { expect(function () { return new Expression("abs()"); }).toThrowRuntimeError(); expect(function () { return new Expression("abs(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates cos function", function () { var expression = new Expression("cos(0)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("cos(vec2(0, Math.PI))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(1.0, -1.0), CesiumMath.EPSILON7 ); expression = new Expression("cos(vec3(0, Math.PI, -Math.PI))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(1.0, -1.0, -1.0), CesiumMath.EPSILON7 ); expression = new Expression("cos(vec4(0, Math.PI, -Math.PI, 0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4(1.0, -1.0, -1.0, 1.0), CesiumMath.EPSILON7 ); }); it("throws if cos function takes an invalid number of arguments", function () { expect(function () { return new Expression("cos()"); }).toThrowRuntimeError(); expect(function () { return new Expression("cos(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates sin function", function () { var expression = new Expression("sin(0)"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("sin(vec2(0, Math.PI/2))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(0.0, 1.0), CesiumMath.EPSILON7 ); expression = new Expression("sin(vec3(0, Math.PI/2, -Math.PI/2))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(0.0, 1.0, -1.0), CesiumMath.EPSILON7 ); expression = new Expression("sin(vec4(0, Math.PI/2, -Math.PI/2, 0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4(0.0, 1.0, -1.0, 0.0), CesiumMath.EPSILON7 ); }); it("throws if sin function takes an invalid number of arguments", function () { expect(function () { return new Expression("sin()"); }).toThrowRuntimeError(); expect(function () { return new Expression("sin(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates tan function", function () { var expression = new Expression("tan(0)"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("tan(vec2(0, Math.PI/4))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(0.0, 1.0), CesiumMath.EPSILON7 ); expression = new Expression("tan(vec3(0, Math.PI/4, Math.PI))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(0.0, 1.0, 0.0), CesiumMath.EPSILON7 ); expression = new Expression("tan(vec4(0, Math.PI/4, Math.PI, -Math.PI/4))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4(0.0, 1.0, 0.0, -1.0), CesiumMath.EPSILON7 ); }); it("throws if tan function takes an invalid number of arguments", function () { expect(function () { return new Expression("tan()"); }).toThrowRuntimeError(); expect(function () { return new Expression("tan(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates acos function", function () { var expression = new Expression("acos(1)"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("acos(vec2(1, 0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(0.0, CesiumMath.PI_OVER_TWO), CesiumMath.EPSILON7 ); expression = new Expression("acos(vec3(1, 0, 1))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(0.0, CesiumMath.PI_OVER_TWO, 0.0, CesiumMath.PI_OVER_TWO), CesiumMath.EPSILON7 ); expression = new Expression("acos(vec4(1, 0, 1, 0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4( 0.0, CesiumMath.PI_OVER_TWO, 0.0, CesiumMath.PI_OVER_TWO, 0.0 ), CesiumMath.EPSILON7 ); }); it("throws if acos function takes an invalid number of arguments", function () { expect(function () { return new Expression("acos()"); }).toThrowRuntimeError(); expect(function () { return new Expression("acos(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates asin function", function () { var expression = new Expression("asin(0)"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("asin(vec2(0, 1))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(0.0, CesiumMath.PI_OVER_TWO), CesiumMath.EPSILON7 ); expression = new Expression("asin(vec3(0, 1, 0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(0.0, CesiumMath.PI_OVER_TWO, 0.0, CesiumMath.PI_OVER_TWO), CesiumMath.EPSILON7 ); expression = new Expression("asin(vec4(0, 1, 0, 1))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4( 0.0, CesiumMath.PI_OVER_TWO, 0.0, CesiumMath.PI_OVER_TWO, 0.0 ), CesiumMath.EPSILON7 ); }); it("throws if asin function takes an invalid number of arguments", function () { expect(function () { return new Expression("asin()"); }).toThrowRuntimeError(); expect(function () { return new Expression("asin(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates atan function", function () { var expression = new Expression("atan(0)"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("atan(vec2(0, 1))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(0.0, CesiumMath.PI_OVER_FOUR), CesiumMath.EPSILON7 ); expression = new Expression("atan(vec3(0, 1, 0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3( 0.0, CesiumMath.PI_OVER_FOUR, 0.0, CesiumMath.PI_OVER_FOUR ), CesiumMath.EPSILON7 ); expression = new Expression("atan(vec4(0, 1, 0, 1))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4( 0.0, CesiumMath.PI_OVER_FOUR, 0.0, CesiumMath.PI_OVER_FOUR, 0.0 ), CesiumMath.EPSILON7 ); }); it("throws if atan function takes an invalid number of arguments", function () { expect(function () { return new Expression("atan()"); }).toThrowRuntimeError(); expect(function () { return new Expression("atan(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates radians function", function () { var expression = new Expression("radians(180)"); expect(expression.evaluate(undefined)).toEqualEpsilon( Math.PI, CesiumMath.EPSILON10 ); expression = new Expression("radians(vec2(180, 90))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(Math.PI, CesiumMath.PI_OVER_TWO), CesiumMath.EPSILON7 ); expression = new Expression("radians(vec3(180, 90, 180))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(Math.PI, CesiumMath.PI_OVER_TWO, Math.PI), CesiumMath.EPSILON7 ); expression = new Expression("radians(vec4(180, 90, 180, 90))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4( Math.PI, CesiumMath.PI_OVER_TWO, Math.PI, CesiumMath.PI_OVER_TWO ), CesiumMath.EPSILON7 ); }); it("throws if radians function takes an invalid number of arguments", function () { expect(function () { return new Expression("radians()"); }).toThrowRuntimeError(); expect(function () { return new Expression("radians(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates degrees function", function () { var expression = new Expression("degrees(2 * Math.PI)"); expect(expression.evaluate(undefined)).toEqualEpsilon( 360, CesiumMath.EPSILON10 ); expression = new Expression("degrees(vec2(2 * Math.PI, Math.PI))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(360, 180), CesiumMath.EPSILON7 ); expression = new Expression( "degrees(vec3(2 * Math.PI, Math.PI, 2 * Math.PI))" ); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(360, 180, 360), CesiumMath.EPSILON7 ); expression = new Expression( "degrees(vec4(2 * Math.PI, Math.PI, 2 * Math.PI, Math.PI))" ); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4(360, 180, 360, 180), CesiumMath.EPSILON7 ); }); it("throws if degrees function takes an invalid number of arguments", function () { expect(function () { return new Expression("degrees()"); }).toThrowRuntimeError(); expect(function () { return new Expression("degrees(1, 2)"); }); }); it("evaluates sqrt function", function () { var expression = new Expression("sqrt(1.0)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("sqrt(4.0)"); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression("sqrt(-1.0)"); expect(expression.evaluate(undefined)).toEqual(NaN); expression = new Expression("sqrt(vec2(1.0, 4.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(1.0, 2.0)); expression = new Expression("sqrt(vec3(1.0, 4.0, 9.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(1.0, 2.0, 3.0) ); expression = new Expression("sqrt(vec4(1.0, 4.0, 9.0, 16.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(1.0, 2.0, 3.0, 4.0) ); }); it("throws if sqrt function takes an invalid number of arguments", function () { expect(function () { return new Expression("sqrt()"); }).toThrowRuntimeError(); expect(function () { return new Expression("sqrt(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates sign function", function () { var expression = new Expression("sign(5.0)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("sign(0.0)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("sign(-5.0)"); expect(expression.evaluate(undefined)).toEqual(-1.0); expression = new Expression("sign(vec2(5.0, -5.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(1.0, -1.0)); expression = new Expression("sign(vec3(5.0, -5.0, 0.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(1.0, -1.0, 0.0) ); expression = new Expression("sign(vec4(5.0, -5.0, 0.0, 1.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(1.0, -1.0, 0.0, 1.0) ); }); it("throws if sign function takes an invalid number of arguments", function () { expect(function () { return new Expression("sign()"); }).toThrowRuntimeError(); expect(function () { return new Expression("sign(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates floor function", function () { var expression = new Expression("floor(5.5)"); expect(expression.evaluate(undefined)).toEqual(5.0); expression = new Expression("floor(0.0)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("floor(-1.2)"); expect(expression.evaluate(undefined)).toEqual(-2.0); expression = new Expression("floor(vec2(5.5, -1.2))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(5.0, -2.0)); expression = new Expression("floor(vec3(5.5, -1.2, 0.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(5.0, -2.0, 0.0) ); expression = new Expression("floor(vec4(5.5, -1.2, 0.0, -2.9))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(5.0, -2.0, 0.0, -3.0) ); }); it("throws if floor function takes an invalid number of arguments", function () { expect(function () { return new Expression("floor()"); }).toThrowRuntimeError(); expect(function () { return new Expression("floor(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates ceil function", function () { var expression = new Expression("ceil(5.5)"); expect(expression.evaluate(undefined)).toEqual(6.0); expression = new Expression("ceil(0.0)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("ceil(-1.2)"); expect(expression.evaluate(undefined)).toEqual(-1.0); expression = new Expression("ceil(vec2(5.5, -1.2))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(6.0, -1.0)); expression = new Expression("ceil(vec3(5.5, -1.2, 0.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(6.0, -1.0, 0.0) ); expression = new Expression("ceil(vec4(5.5, -1.2, 0.0, -2.9))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(6.0, -1.0, 0.0, -2.0) ); }); it("throws if ceil function takes an invalid number of arguments", function () { expect(function () { return new Expression("ceil()"); }).toThrowRuntimeError(); expect(function () { return new Expression("ceil(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates round function", function () { var expression = new Expression("round(5.5)"); expect(expression.evaluate(undefined)).toEqual(6); expression = new Expression("round(0.0)"); expect(expression.evaluate(undefined)).toEqual(0); expression = new Expression("round(1.2)"); expect(expression.evaluate(undefined)).toEqual(1); expression = new Expression("round(vec2(5.5, -1.2))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(6.0, -1.0)); expression = new Expression("round(vec3(5.5, -1.2, 0.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(6.0, -1.0, 0.0) ); expression = new Expression("round(vec4(5.5, -1.2, 0.0, -2.9))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(6.0, -1.0, 0.0, -3.0) ); }); it("throws if round function takes an invalid number of arguments", function () { expect(function () { return new Expression("round()"); }).toThrowRuntimeError(); expect(function () { return new Expression("round(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates exp function", function () { var expression = new Expression("exp(1.0)"); expect(expression.evaluate(undefined)).toEqualEpsilon( Math.E, CesiumMath.EPSILON10 ); expression = new Expression("exp(0.0)"); expect(expression.evaluate(undefined)).toEqualEpsilon( 1.0, CesiumMath.EPSILON10 ); expression = new Expression("exp(vec2(1.0, 0.0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(Math.E, 1.0), CesiumMath.EPSILON10 ); expression = new Expression("exp(vec3(1.0, 0.0, 1.0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(Math.E, 1.0, Math.E), CesiumMath.EPSILON10 ); expression = new Expression("exp(vec4(1.0, 0.0, 1.0, 0.0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4(Math.E, 1.0, Math.E, 1.0), CesiumMath.EPSILON10 ); }); it("throws if exp function takes an invalid number of arguments", function () { expect(function () { return new Expression("exp()"); }).toThrowRuntimeError(); expect(function () { return new Expression("exp(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates exp2 function", function () { var expression = new Expression("exp2(1.0)"); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression("exp2(0.0)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("exp2(2.0)"); expect(expression.evaluate(undefined)).toEqual(4.0); expression = new Expression("exp2(vec2(1.0, 0.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(2.0, 1.0)); expression = new Expression("exp2(vec3(1.0, 0.0, 2.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(2.0, 1.0, 4.0) ); expression = new Expression("exp2(vec4(1.0, 0.0, 2.0, 3.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(2.0, 1.0, 4.0, 8.0) ); }); it("throws if exp2 function takes an invalid number of arguments", function () { expect(function () { return new Expression("exp2()"); }).toThrowRuntimeError(); expect(function () { return new Expression("exp2(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates log function", function () { var expression = new Expression("log(1.0)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("log(10.0)"); expect(expression.evaluate(undefined)).toEqualEpsilon( 2.302585092994046, CesiumMath.EPSILON7 ); expression = new Expression("log(vec2(1.0, Math.E))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0.0, 1.0)); expression = new Expression("log(vec3(1.0, Math.E, 1.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(0.0, 1.0, 0.0) ); expression = new Expression("log(vec4(1.0, Math.E, 1.0, Math.E))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(0.0, 1.0, 0.0, 1.0) ); }); it("throws if log function takes an invalid number of arguments", function () { expect(function () { return new Expression("log()"); }).toThrowRuntimeError(); expect(function () { return new Expression("log(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates log2 function", function () { var expression = new Expression("log2(1.0)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("log2(2.0)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("log2(4.0)"); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression("log2(vec2(1.0, 2.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0.0, 1.0)); expression = new Expression("log2(vec3(1.0, 2.0, 4.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(0.0, 1.0, 2.0) ); expression = new Expression("log2(vec4(1.0, 2.0, 4.0, 8.0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4(0.0, 1.0, 2.0, 3.0), CesiumMath.EPSILON10 ); }); it("throws if log2 function takes an invalid number of arguments", function () { expect(function () { return new Expression("log2()"); }).toThrowRuntimeError(); expect(function () { return new Expression("log2(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates fract function", function () { var expression = new Expression("fract(1.0)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("fract(2.25)"); expect(expression.evaluate(undefined)).toEqual(0.25); expression = new Expression("fract(-2.25)"); expect(expression.evaluate(undefined)).toEqual(0.75); expression = new Expression("fract(vec2(1.0, 2.25))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0.0, 0.25)); expression = new Expression("fract(vec3(1.0, 2.25, -2.25))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(0.0, 0.25, 0.75) ); expression = new Expression("fract(vec4(1.0, 2.25, -2.25, 1.0))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(0.0, 0.25, 0.75, 0.0) ); }); it("throws if fract function takes an invalid number of arguments", function () { expect(function () { return new Expression("fract()"); }).toThrowRuntimeError(); expect(function () { return new Expression("fract(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates length function", function () { var expression = new Expression("length(-3.0)"); expect(expression.evaluate(undefined)).toEqual(3.0); expression = new Expression("length(vec2(-3.0, 4.0))"); expect(expression.evaluate(undefined)).toEqual(5.0); expression = new Expression("length(vec3(2.0, 3.0, 6.0))"); expect(expression.evaluate(undefined)).toEqual(7.0); expression = new Expression("length(vec4(2.0, 4.0, 7.0, 10.0))"); expect(expression.evaluate(undefined)).toEqual(13.0); }); it("throws if length function takes an invalid number of arguments", function () { expect(function () { return new Expression("length()"); }).toThrowRuntimeError(); expect(function () { return new Expression("length(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates normalize function", function () { var expression = new Expression("normalize(5.0)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("normalize(vec2(3.0, 4.0))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0.6, 0.8)); expression = new Expression("normalize(vec3(2.0, 3.0, -4.0))"); var length = Math.sqrt(2 * 2 + 3 * 3 + 4 * 4); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(2.0 / length, 3.0 / length, -4.0 / length), CesiumMath.EPSILON10 ); expression = new Expression("normalize(vec4(-2.0, 3.0, -4.0, 5.0))"); length = Math.sqrt(2 * 2 + 3 * 3 + 4 * 4 + 5 * 5); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(-2.0 / length, 3.0 / length, -4.0 / length, 5.0 / length), CesiumMath.EPSILON10 ); }); it("throws if normalize function takes an invalid number of arguments", function () { expect(function () { return new Expression("fract()"); }).toThrowRuntimeError(); expect(function () { return new Expression("fract(1, 2)"); }).toThrowRuntimeError(); }); it("evaluates clamp function", function () { var expression = new Expression("clamp(50.0, 0.0, 100.0)"); expect(expression.evaluate(undefined)).toEqual(50.0); expression = new Expression("clamp(50.0, 0.0, 25.0)"); expect(expression.evaluate(undefined)).toEqual(25.0); expression = new Expression("clamp(50.0, 75.0, 100.0)"); expect(expression.evaluate(undefined)).toEqual(75.0); expression = new Expression( "clamp(vec2(50.0,50.0), vec2(0.0,75.0), 100.0)" ); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(50.0, 75.0)); expression = new Expression( "clamp(vec2(50.0,50.0), vec2(0.0,75.0), vec2(25.0,100.0))" ); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(25.0, 75.0)); expression = new Expression( "clamp(vec3(50.0, 50.0, 50.0), vec3(0.0, 0.0, 75.0), vec3(100.0, 25.0, 100.0))" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(50.0, 25.0, 75.0) ); expression = new Expression( "clamp(vec4(50.0, 50.0, 50.0, 100.0), vec4(0.0, 0.0, 75.0, 75.0), vec4(100.0, 25.0, 100.0, 85.0))" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(50.0, 25.0, 75.0, 85.0) ); }); it("throws if clamp function takes an invalid number of arguments", function () { expect(function () { return new Expression("clamp()"); }).toThrowRuntimeError(); expect(function () { return new Expression("clamp(1)"); }).toThrowRuntimeError(); expect(function () { return new Expression("clamp(1, 2)"); }).toThrowRuntimeError(); expect(function () { return new Expression("clamp(1, 2, 3, 4)"); }).toThrowRuntimeError(); }); it("throws if clamp function takes mismatching types", function () { var expression = new Expression("clamp(0.0,vec2(0,1),0.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("clamp(vec2(0,1),vec3(0,1,2),0.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("clamp(vec2(0,1),vec2(0,1), vec3(1,2,3))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates mix function", function () { var expression = new Expression("mix(0.0, 2.0, 0.5)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("mix(vec2(0.0,1.0), vec2(2.0,3.0), 0.5)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(1.0, 2.0)); expression = new Expression( "mix(vec2(0.0,1.0), vec2(2.0,3.0), vec2(0.5,4.0))" ); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(1.0, 9.0)); expression = new Expression( "mix(vec3(0.0,1.0,2.0), vec3(2.0,3.0,4.0), vec3(0.5,4.0,5.0))" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(1.0, 9.0, 12.0) ); expression = new Expression( "mix(vec4(0.0,1.0,2.0,1.5), vec4(2.0,3.0,4.0,2.5), vec4(0.5,4.0,5.0,3.5))" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(1.0, 9.0, 12.0, 5.0) ); }); it("throws if mix function takes mismatching types", function () { var expression = new Expression("mix(0.0,vec2(0,1),0.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("mix(vec2(0,1),vec3(0,1,2),0.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("mix(vec2(0,1),vec2(0,1), vec3(1,2,3))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("throws if mix function takes an invalid number of arguments", function () { expect(function () { return new Expression("mix()"); }).toThrowRuntimeError(); expect(function () { return new Expression("mix(1)"); }).toThrowRuntimeError(); expect(function () { return new Expression("mix(1, 2)"); }).toThrowRuntimeError(); expect(function () { return new Expression("mix(1, 2, 3, 4)"); }).toThrowRuntimeError(); }); it("evaluates atan2 function", function () { var expression = new Expression("atan2(0,1)"); expect(expression.evaluate(undefined)).toEqualEpsilon( 0.0, CesiumMath.EPSILON10 ); expression = new Expression("atan2(1,0)"); expect(expression.evaluate(undefined)).toEqualEpsilon( 0.5 * Math.PI, CesiumMath.EPSILON10 ); expression = new Expression("atan2(vec2(0,1),vec2(1,0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian2(0.0, 0.5 * Math.PI), CesiumMath.EPSILON10 ); expression = new Expression("atan2(vec3(0,1,0.5),vec3(1,0,0.5))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian3(0.0, 0.5 * Math.PI, 0.25 * Math.PI), CesiumMath.EPSILON10 ); expression = new Expression("atan2(vec4(0,1,0.5,1),vec4(1,0,0.5,0))"); expect(expression.evaluate(undefined)).toEqualEpsilon( new Cartesian4(0.0, 0.5 * Math.PI, 0.25 * Math.PI, 0.5 * Math.PI), CesiumMath.EPSILON10 ); }); it("throws if atan2 function takes an invalid number of arguments", function () { expect(function () { return new Expression("atan2(0.0)"); }).toThrowRuntimeError(); expect(function () { return new Expression("atan2(1, 2, 0)"); }).toThrowRuntimeError(); }); it("throws if atan2 function takes mismatching types", function () { var expression = new Expression("atan2(0.0,vec2(0,1))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("atan2(vec2(0,1),0.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("atan2(vec2(0,1),vec3(0,1,2))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates pow function", function () { var expression = new Expression("pow(5,0)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("pow(4,2)"); expect(expression.evaluate(undefined)).toEqual(16.0); expression = new Expression("pow(vec2(5,4),vec2(0,2))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(1.0, 16.0)); expression = new Expression("pow(vec3(5,4,3),vec3(0,2,3))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(1.0, 16.0, 27.0) ); expression = new Expression("pow(vec4(5,4,3,2),vec4(0,2,3,5))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(1.0, 16.0, 27.0, 32.0) ); }); it("throws if pow function takes an invalid number of arguments", function () { expect(function () { return new Expression("pow(0.0)"); }).toThrowRuntimeError(); expect(function () { return new Expression("pow(1, 2, 0)"); }).toThrowRuntimeError(); }); it("throws if pow function takes mismatching types", function () { var expression = new Expression("pow(0.0, vec2(0,1))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("pow(vec2(0,1),0.0)"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("pow(vec2(0,1),vec3(0,1,2))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates min function", function () { var expression = new Expression("min(0,1)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("min(-1,0)"); expect(expression.evaluate(undefined)).toEqual(-1.0); expression = new Expression("min(vec2(-1,1),0)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(-1.0, 0)); expression = new Expression("min(vec2(-1,2),vec2(0,1))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(-1.0, 1.0)); expression = new Expression("min(vec3(-1,2,1),vec3(0,1,2))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(-1.0, 1.0, 1.0) ); expression = new Expression("min(vec4(-1,2,1,4),vec4(0,1,2,3))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(-1.0, 1.0, 1.0, 3.0) ); }); it("throws if min function takes an invalid number of arguments", function () { expect(function () { return new Expression("min(0.0)"); }).toThrowRuntimeError(); expect(function () { return new Expression("min(1, 2, 0)"); }).toThrowRuntimeError(); }); it("throws if min function takes mismatching types", function () { var expression = new Expression("min(0.0, vec2(0,1))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("min(vec2(0,1),vec3(0,1,2))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates max function", function () { var expression = new Expression("max(0,1)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("max(-1,0)"); expect(expression.evaluate(undefined)).toEqual(0.0); expression = new Expression("max(vec2(-1,1),0)"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0, 1.0)); expression = new Expression("max(vec2(-1,2),vec2(0,1))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian2(0, 2.0)); expression = new Expression("max(vec3(-1,2,1),vec3(0,1,2))"); expect(expression.evaluate(undefined)).toEqual(new Cartesian3(0, 2.0, 2.0)); expression = new Expression("max(vec4(-1,2,1,4),vec4(0,1,2,3))"); expect(expression.evaluate(undefined)).toEqual( new Cartesian4(0, 2.0, 2.0, 4.0) ); }); it("throws if max function takes an invalid number of arguments", function () { expect(function () { return new Expression("max(0.0)"); }).toThrowRuntimeError(); expect(function () { return new Expression("max(1, 2, 0)"); }).toThrowRuntimeError(); }); it("throws if max function takes mismatching types", function () { var expression = new Expression("max(0.0, vec2(0,1))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("max(vec2(0,1),vec3(0,1,2))"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates the distance function", function () { var expression = new Expression("distance(0, 1)"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression("distance(vec2(1.0, 0.0), vec2(0.0, 0.0))"); expect(expression.evaluate(undefined)).toEqual(1.0); expression = new Expression( "distance(vec3(3.0, 2.0, 1.0), vec3(1.0, 0.0, 0.0))" ); expect(expression.evaluate(undefined)).toEqual(3.0); expression = new Expression( "distance(vec4(5.0, 5.0, 5.0, 5.0), vec4(0.0, 0.0, 0.0, 0.0))" ); expect(expression.evaluate(undefined)).toEqual(10.0); }); it("throws if distance function takes an invalid number of arguments", function () { expect(function () { return new Expression("distance(0.0)"); }).toThrowRuntimeError(); expect(function () { return new Expression("distance(1, 3, 0)"); }).toThrowRuntimeError(); }); it("throws if distance function takes mismatching types of arguments", function () { expect(function () { return new Expression("distance(1, vec2(3.0, 2.0)").evaluate(undefined); }).toThrowRuntimeError(); expect(function () { return new Expression( "distance(vec4(5.0, 2.0, 3.0, 1.0), vec3(4.0, 4.0, 4.0))" ).evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates the dot function", function () { var expression = new Expression("dot(1, 2)"); expect(expression.evaluate(undefined)).toEqual(2.0); expression = new Expression("dot(vec2(1.0, 1.0), vec2(2.0, 2.0))"); expect(expression.evaluate(undefined)).toEqual(4.0); expression = new Expression( "dot(vec3(1.0, 2.0, 3.0), vec3(2.0, 2.0, 1.0))" ); expect(expression.evaluate(undefined)).toEqual(9.0); expression = new Expression( "dot(vec4(5.0, 5.0, 2.0, 3.0), vec4(1.0, 2.0, 1.0, 1.0))" ); expect(expression.evaluate(undefined)).toEqual(20.0); }); it("throws if dot function takes an invalid number of arguments", function () { expect(function () { return new Expression("dot(0.0)"); }).toThrowRuntimeError(); expect(function () { return new Expression("dot(1, 3, 0)"); }).toThrowRuntimeError(); }); it("throws if dot function takes mismatching types of arguments", function () { expect(function () { return new Expression("dot(1, vec2(3.0, 2.0)").evaluate(undefined); }).toThrowRuntimeError(); expect(function () { return new Expression( "dot(vec4(5.0, 2.0, 3.0, 1.0), vec3(4.0, 4.0, 4.0))" ).evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates the cross function", function () { var expression = new Expression( "cross(vec3(1.0, 1.0, 1.0), vec3(2.0, 2.0, 2.0))" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(0.0, 0.0, 0.0) ); expression = new Expression( "cross(vec3(-1.0, -1.0, -1.0), vec3(0.0, -2.0, -5.0))" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(3.0, -5.0, 2.0) ); expression = new Expression( "cross(vec3(5.0, -2.0, 1.0), vec3(-2.0, -6.0, -8.0))" ); expect(expression.evaluate(undefined)).toEqual( new Cartesian3(22.0, 38.0, -34.0) ); }); it("throws if cross function takes an invalid number of arguments", function () { expect(function () { return new Expression("cross(vec3(0.0, 0.0, 0.0))"); }).toThrowRuntimeError(); expect(function () { return new Expression( "cross(vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0), vec3(2.0, 2.0, 2.0))" ); }).toThrowRuntimeError(); }); it("throws if cross function does not take vec3 arguments", function () { expect(function () { return new Expression("cross(vec2(1.0, 2.0), vec2(3.0, 2.0)").evaluate( undefined ); }).toThrowRuntimeError(); expect(function () { return new Expression( "cross(vec4(5.0, 2.0, 3.0, 1.0), vec3(4.0, 4.0, 4.0))" ).evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates ternary conditional", function () { var expression = new Expression('true ? "first" : "second"'); expect(expression.evaluate(undefined)).toEqual("first"); expression = new Expression('false ? "first" : "second"'); expect(expression.evaluate(undefined)).toEqual("second"); expression = new Expression( "(!(1 + 2 > 3)) ? (2 > 1 ? 1 + 1 : 0) : (2 > 1 ? -1 + -1 : 0)" ); expect(expression.evaluate(undefined)).toEqual(2); }); it("evaluates member expression with dot", function () { var feature = new MockFeature(); feature.addProperty("height", 10); feature.addProperty("width", 5); feature.addProperty("string", "hello"); feature.addProperty("boolean", true); feature.addProperty("vector", Cartesian4.UNIT_X); feature.addProperty("vector.x", "something else"); feature.addProperty("feature.vector", Cartesian4.UNIT_Y); feature.addProperty("feature", { vector: Cartesian4.UNIT_Z, }); feature.addProperty("null", null); feature.addProperty("undefined", undefined); feature.addProperty("address", { street: "Example Street", city: "Example City", }); var expression = new Expression("${vector.x}"); expect(expression.evaluate(feature)).toEqual(1.0); expression = new Expression("${vector.z}"); expect(expression.evaluate(feature)).toEqual(0.0); expression = new Expression("${height.z}"); expect(expression.evaluate(feature)).toEqual(undefined); expression = new Expression("${undefined.z}"); expect(expression.evaluate(feature)).toEqual(undefined); expression = new Expression("${feature}"); expect(expression.evaluate(feature)).toEqual({ vector: Cartesian4.UNIT_Z, }); expression = new Expression("${feature.vector}"); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_X); expression = new Expression("${feature.feature.vector}"); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_Z); expression = new Expression("${feature.vector.x}"); expect(expression.evaluate(feature)).toEqual(1.0); expression = new Expression("${address.street}"); expect(expression.evaluate(feature)).toEqual("Example Street"); expression = new Expression("${address.city}"); expect(expression.evaluate(feature)).toEqual("Example City"); }); it("evaluates member expression with brackets", function () { var feature = new MockFeature(); feature.addProperty("height", 10); feature.addProperty("width", 5); feature.addProperty("string", "hello"); feature.addProperty("boolean", true); feature.addProperty("vector", Cartesian4.UNIT_X); feature.addProperty("vector.x", "something else"); feature.addProperty("feature.vector", Cartesian4.UNIT_Y); feature.addProperty("feature", { vector: Cartesian4.UNIT_Z, }); feature.addProperty("null", null); feature.addProperty("undefined", undefined); feature.addProperty("address.street", "Other Street"); feature.addProperty("address", { street: "Example Street", city: "Example City", }); var expression = new Expression('${vector["x"]}'); expect(expression.evaluate(feature)).toEqual(1.0); expression = new Expression('${vector["z"]}'); expect(expression.evaluate(feature)).toEqual(0.0); expression = new Expression('${height["z"]}'); expect(expression.evaluate(feature)).toEqual(undefined); expression = new Expression('${undefined["z"]}'); expect(expression.evaluate(feature)).toEqual(undefined); expression = new Expression('${feature["vector"]}'); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_X); expression = new Expression('${feature.vector["x"]}'); expect(expression.evaluate(feature)).toEqual(1.0); expression = new Expression('${feature["vector"].x}'); expect(expression.evaluate(feature)).toEqual(1.0); expression = new Expression('${feature["vector.x"]}'); expect(expression.evaluate(feature)).toEqual("something else"); expression = new Expression('${feature.feature["vector"]}'); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_Z); expression = new Expression('${feature["feature.vector"]}'); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_Y); expression = new Expression("${address.street}"); expect(expression.evaluate(feature)).toEqual("Example Street"); expression = new Expression("${feature.address.street}"); expect(expression.evaluate(feature)).toEqual("Example Street"); expression = new Expression('${feature["address"].street}'); expect(expression.evaluate(feature)).toEqual("Example Street"); expression = new Expression('${feature["address.street"]}'); expect(expression.evaluate(feature)).toEqual("Other Street"); expression = new Expression('${address["street"]}'); expect(expression.evaluate(feature)).toEqual("Example Street"); expression = new Expression('${address["city"]}'); expect(expression.evaluate(feature)).toEqual("Example City"); }); it("member expressions throw without variable notation", function () { expect(function () { return new Expression("color.r"); }).toThrowRuntimeError(); expect(function () { return new Expression('color["r"]'); }).toThrowRuntimeError(); }); it("member expression throws with variable property", function () { var feature = new MockFeature(); feature.addProperty("vector", Cartesian4.UNIT_X); feature.addProperty("vectorName", "UNIT_X"); expect(function () { return new Expression("${vector[${vectorName}]}"); }).toThrowRuntimeError(); }); it("evaluates feature property", function () { var feature = new MockFeature(); feature.addProperty("feature", { vector: Cartesian4.UNIT_X, }); var expression = new Expression("${feature}"); expect(expression.evaluate(feature)).toEqual({ vector: Cartesian4.UNIT_X, }); expression = new Expression("${feature} === ${feature.feature}"); expect(expression.evaluate(feature)).toEqual(true); }); it("constructs regex", function () { var feature = new MockFeature(); feature.addProperty("pattern", "[abc]"); var expression = new Expression('regExp("a")'); expect(expression.evaluate(undefined)).toEqual(/a/); expect(expression._runtimeAst._type).toEqual( ExpressionNodeType.LITERAL_REGEX ); expression = new Expression('regExp("\\w")'); expect(expression.evaluate(undefined)).toEqual(/\w/); expect(expression._runtimeAst._type).toEqual( ExpressionNodeType.LITERAL_REGEX ); expression = new Expression("regExp(1 + 1)"); expect(expression.evaluate(undefined)).toEqual(/2/); expect(expression._runtimeAst._type).toEqual(ExpressionNodeType.REGEX); expression = new Expression("regExp(true)"); expect(expression.evaluate(undefined)).toEqual(/true/); expect(expression._runtimeAst._type).toEqual( ExpressionNodeType.LITERAL_REGEX ); expression = new Expression("regExp()"); expect(expression.evaluate(undefined)).toEqual(/(?:)/); expect(expression._runtimeAst._type).toEqual( ExpressionNodeType.LITERAL_REGEX ); expression = new Expression("regExp(${pattern})"); expect(expression.evaluate(feature)).toEqual(/[abc]/); expect(expression._runtimeAst._type).toEqual(ExpressionNodeType.REGEX); }); it("constructs regex with flags", function () { var expression = new Expression('regExp("a", "i")'); expect(expression.evaluate(undefined)).toEqual(/a/i); expect(expression._runtimeAst._type).toEqual( ExpressionNodeType.LITERAL_REGEX ); expression = new Expression('regExp("a", "m" + "g")'); expect(expression.evaluate(undefined)).toEqual(/a/gm); expect(expression._runtimeAst._type).toEqual(ExpressionNodeType.REGEX); }); it("does not throw SyntaxError if regex constructor has invalid pattern", function () { var expression = new Expression('regExp("(?<=\\s)" + ".")'); expect(function () { expression.evaluate(undefined); }).not.toThrowSyntaxError(); expect(function () { return new Expression('regExp("(?<=\\s)")'); }).not.toThrowSyntaxError(); }); it("throws if regex constructor has invalid flags", function () { var expression = new Expression('regExp("a" + "b", "q")'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expect(function () { return new Expression('regExp("a", "q")'); }).toThrowRuntimeError(); }); it("evaluates regex test function", function () { var feature = new MockFeature(); feature.addProperty("property", "abc"); var expression = new Expression('regExp("a").test("abc")'); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('regExp("a").test("bcd")'); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression( 'regExp("quick\\s(brown).+?(jumps)", "ig").test("The Quick Brown Fox Jumps Over The Lazy Dog")' ); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('regExp("a").test()'); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("regExp(${property}).test(${property})"); expect(expression.evaluate(feature)).toEqual(true); }); it("throws if regex test function has invalid arguments", function () { var expression = new Expression('regExp("1").test(1)'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('regExp("a").test(regExp("b"))'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates regex exec function", function () { var feature = new MockFeature(); feature.addProperty("property", "abc"); feature.addProperty("Name", "Building 1"); var expression = new Expression('regExp("a(.)", "i").exec("Abc")'); expect(expression.evaluate(undefined)).toEqual("b"); expression = new Expression('regExp("a(.)").exec("qbc")'); expect(expression.evaluate(undefined)).toEqual(null); expression = new Expression('regExp("a(.)").exec()'); expect(expression.evaluate(undefined)).toEqual(null); expression = new Expression( 'regExp("quick\\s(b.*n).+?(jumps)", "ig").exec("The Quick Brown Fox Jumps Over The Lazy Dog")' ); expect(expression.evaluate(undefined)).toEqual("Brown"); expression = new Expression( 'regExp("(" + ${property} + ")").exec(${property})' ); expect(expression.evaluate(feature)).toEqual("abc"); expression = new Expression('regExp("Building\\s(\\d)").exec(${Name})'); expect(expression.evaluate(feature)).toEqual("1"); }); it("throws if regex exec function has invalid arguments", function () { var expression = new Expression('regExp("1").exec(1)'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('regExp("a").exec(regExp("b"))'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates regex match operator", function () { var feature = new MockFeature(); feature.addProperty("property", "abc"); var expression = new Expression('regExp("a") =~ "abc"'); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('"abc" =~ regExp("a")'); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('regExp("a") =~ "bcd"'); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression('"bcd" =~ regExp("a")'); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression( 'regExp("quick\\s(brown).+?(jumps)", "ig") =~ "The Quick Brown Fox Jumps Over The Lazy Dog"' ); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression("regExp(${property}) =~ ${property}"); expect(expression.evaluate(feature)).toEqual(true); }); it("throws if regex match operator has invalid arguments", function () { var feature = new MockFeature(); feature.addProperty("property", "abc"); var expression = new Expression('regExp("a") =~ 1'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('1 =~ regExp("a")'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1 =~ 1"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("evaluates regex not match operator", function () { var feature = new MockFeature(); feature.addProperty("property", "abc"); var expression = new Expression('regExp("a") !~ "abc"'); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression('"abc" !~ regExp("a")'); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression('regExp("a") !~ "bcd"'); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression('"bcd" !~ regExp("a")'); expect(expression.evaluate(undefined)).toEqual(true); expression = new Expression( 'regExp("quick\\s(brown).+?(jumps)", "ig") !~ "The Quick Brown Fox Jumps Over The Lazy Dog"' ); expect(expression.evaluate(undefined)).toEqual(false); expression = new Expression("regExp(${property}) !~ ${property}"); expect(expression.evaluate(feature)).toEqual(false); }); it("throws if regex not match operator has invalid arguments", function () { var expression = new Expression('regExp("a") !~ 1'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression('1 !~ regExp("a")'); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); expression = new Expression("1 !~ 1"); expect(function () { expression.evaluate(undefined); }).toThrowRuntimeError(); }); it("throws if test is not called with a RegExp", function () { expect(function () { return new Expression('color("blue").test()'); }).toThrowRuntimeError(); expect(function () { return new Expression('"blue".test()'); }).toThrowRuntimeError(); }); it("evaluates regExp toString function", function () { var feature = new MockFeature(); feature.addProperty("property", "abc"); var expression = new Expression("regExp().toString()"); expect(expression.evaluate(undefined)).toEqual("/(?:)/"); expression = new Expression('regExp("\\d\\s\\d", "ig").toString()'); expect(expression.evaluate(undefined)).toEqual("/\\d\\s\\d/gi"); expression = new Expression("regExp(${property}).toString()"); expect(expression.evaluate(feature)).toEqual("/abc/"); }); it("throws when using toString on other type", function () { var feature = new MockFeature(); feature.addProperty("property", "abc"); var expression = new Expression("${property}.toString()"); expect(function () { return expression.evaluate(feature); }).toThrowRuntimeError(); }); it("evaluates array expression", function () { var feature = new MockFeature(); feature.addProperty("property", "value"); feature.addProperty("array", [ Cartesian4.UNIT_X, Cartesian4.UNIT_Y, Cartesian4.UNIT_Z, ]); feature.addProperty("complicatedArray", [ { subproperty: Cartesian4.UNIT_X, anotherproperty: Cartesian4.UNIT_Y, }, { subproperty: Cartesian4.UNIT_Z, anotherproperty: Cartesian4.UNIT_W, }, ]); feature.addProperty("temperatures", { scale: "fahrenheit", values: [70, 80, 90], }); var expression = new Expression("[1, 2, 3]"); expect(expression.evaluate(undefined)).toEqual([1, 2, 3]); expression = new Expression( '[1+2, "hello", 2 < 3, color("blue"), ${property}]' ); expect(expression.evaluate(feature)).toEqual([ 3, "hello", true, Cartesian4.fromColor(Color.BLUE), "value", ]); expression = new Expression("${array[1]}"); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_Y); expression = new Expression("${complicatedArray[1].subproperty}"); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_Z); expression = new Expression('${complicatedArray[0]["anotherproperty"]}'); expect(expression.evaluate(feature)).toEqual(Cartesian4.UNIT_Y); expression = new Expression('${temperatures["scale"]}'); expect(expression.evaluate(feature)).toEqual("fahrenheit"); expression = new Expression("${temperatures.values[0]}"); expect(expression.evaluate(feature)).toEqual(70); expression = new Expression('${temperatures["values"][0]}'); expect(expression.evaluate(feature)).toEqual(70); }); it("evaluates tiles3d_tileset_time expression", function () { var feature = new MockFeature(); var expression = new Expression("${tiles3d_tileset_time}"); expect(expression.evaluate(feature)).toEqual(0.0); feature.content.tileset.timeSinceLoad = 1.0; expect(expression.evaluate(feature)).toEqual(1.0); expect(expression.evaluate(undefined)).toEqual(0.0); }); it("gets shader function", function () { var expression = new Expression("true"); var shaderFunction = expression.getShaderFunction( "getShow()", {}, {}, "bool" ); var expected = "bool getShow()\n" + "{\n" + " return true;\n" + "}\n"; expect(shaderFunction).toEqual(expected); }); it("gets shader expression for variable", function () { var expression = new Expression("${property}"); var variableSubstitutionMap = { property: "a_property", }; var shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); var expected = "a_property"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for feature variable with bracket notation", function () { var expression = new Expression("${feature['property']}"); var variableSubstitutionMap = { property: "a_property", }; var shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); var expected = "a_property"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for feature variable with dot notation", function () { var expression = new Expression("${feature.property}"); var variableSubstitutionMap = { property: "a_property", }; var shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); var expected = "a_property"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for unary not", function () { var expression = new Expression("!true"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "!true"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for unary negative", function () { var expression = new Expression("-5.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "-5.0"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for unary positive", function () { var expression = new Expression("+5.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "+5.0"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for converting to literal boolean", function () { var expression = new Expression("Boolean(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "bool(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for converting to literal number", function () { var expression = new Expression("Number(true)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "float(true)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary addition", function () { var expression = new Expression("1.0 + 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 + 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary subtraction", function () { var expression = new Expression("1.0 - 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 - 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary multiplication", function () { var expression = new Expression("1.0 * 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 * 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary division", function () { var expression = new Expression("1.0 / 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 / 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary modulus", function () { var expression = new Expression("1.0 % 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "mod(1.0, 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary equals strict", function () { var expression = new Expression("1.0 === 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 == 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary not equals strict", function () { var expression = new Expression("1.0 !== 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 != 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary less than", function () { var expression = new Expression("1.0 < 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 < 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary less than or equals", function () { var expression = new Expression("1.0 <= 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 <= 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary greater than", function () { var expression = new Expression("1.0 > 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 > 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for binary greater than or equals", function () { var expression = new Expression("1.0 >= 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 >= 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for logical and", function () { var expression = new Expression("true && false"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(true && false)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for logical or", function () { var expression = new Expression("true || false"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(true || false)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for ternary conditional", function () { var expression = new Expression("true ? 1.0 : 2.0"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(true ? 1.0 : 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for array indexing", function () { var variableSubstitutionMap = { property: "property" }; var expression = new Expression("${property[0]}"); var shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); var expected = "property[0]"; expect(shaderExpression).toEqual(expected); expression = new Expression("${property[4 / 2]}"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); expected = "property[int((4.0 / 2.0))]"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for array", function () { var expression = new Expression("[1.0, 2.0]"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "vec2(1.0, 2.0)"; expect(shaderExpression).toEqual(expected); expression = new Expression("[1.0, 2.0, 3.0]"); shaderExpression = expression.getShaderExpression({}, {}); expected = "vec3(1.0, 2.0, 3.0)"; expect(shaderExpression).toEqual(expected); expression = new Expression("[1.0, 2.0, 3.0, 4.0]"); shaderExpression = expression.getShaderExpression({}, {}); expected = "vec4(1.0, 2.0, 3.0, 4.0)"; expect(shaderExpression).toEqual(expected); }); it("throws when getting shader expression for array of invalid length", function () { var expression = new Expression("[]"); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); expression = new Expression("[1.0]"); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); expression = new Expression("[1.0, 2.0, 3.0, 4.0, 5.0]"); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("gets shader expression for boolean", function () { var expression = new Expression("true || false"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(true || false)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for integer", function () { var expression = new Expression("1"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "1.0"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for float", function () { var expression = new Expression("1.02"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "1.02"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for color", function () { var variableSubstitutionMap = { property: "property" }; var shaderState = { translucent: false }; var expression = new Expression("color()"); var shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); var expected = "vec4(1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression('color("red")'); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(vec3(1.0, 0.0, 0.0), 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression('color("#FFF")'); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(vec3(1.0, 1.0, 1.0), 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression('color("#FF0000")'); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(vec3(1.0, 0.0, 0.0), 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression('color("rgb(255, 0, 0)")'); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(vec3(1.0, 0.0, 0.0), 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression('color("red", 0.5)'); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(vec3(1.0, 0.0, 0.0), 0.5)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(true); shaderState = { translucent: false }; expression = new Expression("rgb(255, 0, 0)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(1.0, 0.0, 0.0, 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression("rgb(255, ${property}, 0)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(255.0 / 255.0, property / 255.0, 0.0 / 255.0, 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression("rgba(255, 0, 0, 0.5)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(1.0, 0.0, 0.0, 0.5)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(true); shaderState = { translucent: false }; expression = new Expression("rgba(255, ${property}, 0, 0.5)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(255.0 / 255.0, property / 255.0, 0.0 / 255.0, 0.5)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(true); shaderState = { translucent: false }; expression = new Expression("hsl(1.0, 0.5, 0.5)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(0.75, 0.25, 0.25, 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression("hsla(1.0, 0.5, 0.5, 0.5)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(0.75, 0.25, 0.25, 0.5)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(true); shaderState = { translucent: false }; expression = new Expression("hsl(1.0, ${property}, 0.5)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(czm_HSLToRGB(vec3(1.0, property, 0.5)), 1.0)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(false); shaderState = { translucent: false }; expression = new Expression("hsla(1.0, ${property}, 0.5, 0.5)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, shaderState ); expected = "vec4(czm_HSLToRGB(vec3(1.0, property, 0.5)), 0.5)"; expect(shaderExpression).toEqual(expected); expect(shaderState.translucent).toBe(true); }); it("gets shader expression for color components", function () { // .r, .g, .b, .a var expression = new Expression( "color().r + color().g + color().b + color().a" ); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(((vec4(1.0)[0] + vec4(1.0)[1]) + vec4(1.0)[2]) + vec4(1.0)[3])"; expect(shaderExpression).toEqual(expected); // .x, .y, .z, .w expression = new Expression( "color().x + color().y + color().z + color().w" ); shaderExpression = expression.getShaderExpression({}, {}); expect(shaderExpression).toEqual(expected); // [0], [1], [2], [3] expression = new Expression( "color()[0] + color()[1] + color()[2] + color()[3]" ); shaderExpression = expression.getShaderExpression({}, {}); expect(shaderExpression).toEqual(expected); }); it("gets shader expression for vector", function () { var variableSubstitutionMap = { property: "property", }; var expression = new Expression("vec4(1, 2, 3, 4)"); var shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); expect(shaderExpression).toEqual("vec4(1.0, 2.0, 3.0, 4.0)"); expression = new Expression("vec4(1) + vec4(2)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); expect(shaderExpression).toEqual("(vec4(1.0) + vec4(2.0))"); expression = new Expression("vec4(1, ${property}, vec2(1, 2).x, 0)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); expect(shaderExpression).toEqual( "vec4(1.0, property, vec2(1.0, 2.0)[0], 0.0)" ); expression = new Expression("vec4(vec3(2), 1.0)"); shaderExpression = expression.getShaderExpression( variableSubstitutionMap, {} ); expect(shaderExpression).toEqual("vec4(vec3(2.0), 1.0)"); }); it("gets shader expression for vector components", function () { // .x, .y, .z, .w var expression = new Expression( "vec4(1).x + vec4(1).y + vec4(1).z + vec4(1).w" ); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(((vec4(1.0)[0] + vec4(1.0)[1]) + vec4(1.0)[2]) + vec4(1.0)[3])"; expect(shaderExpression).toEqual(expected); // [0], [1], [2], [3] expression = new Expression( "vec4(1)[0] + vec4(1)[1] + vec4(1)[2] + vec4(1)[3]" ); shaderExpression = expression.getShaderExpression({}, {}); expect(shaderExpression).toEqual(expected); }); it("gets shader expression for tiles3d_tileset_time", function () { var expression = new Expression("${tiles3d_tileset_time}"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "u_time"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for abs", function () { var expression = new Expression("abs(-1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "abs(-1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for cos", function () { var expression = new Expression("cos(0.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "cos(0.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for sin", function () { var expression = new Expression("sin(0.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "sin(0.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for tan", function () { var expression = new Expression("tan(0.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "tan(0.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for acos", function () { var expression = new Expression("acos(0.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "acos(0.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for asin", function () { var expression = new Expression("asin(0.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "asin(0.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for atan", function () { var expression = new Expression("atan(0.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "atan(0.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for sqrt", function () { var expression = new Expression("sqrt(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "sqrt(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for sign", function () { var expression = new Expression("sign(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "sign(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for floor", function () { var expression = new Expression("floor(1.5)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "floor(1.5)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for ceil", function () { var expression = new Expression("ceil(1.2)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "ceil(1.2)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for round", function () { var expression = new Expression("round(1.2)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "floor(1.2 + 0.5)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for exp", function () { var expression = new Expression("exp(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "exp(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for exp2", function () { var expression = new Expression("exp2(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "exp2(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for log", function () { var expression = new Expression("log(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "log(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for log2", function () { var expression = new Expression("log2(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "log2(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for fract", function () { var expression = new Expression("fract(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "fract(1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for clamp", function () { var expression = new Expression("clamp(50.0, 0.0, 100.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "clamp(50.0, 0.0, 100.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for mix", function () { var expression = new Expression("mix(0.0, 2.0, 0.5)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "mix(0.0, 2.0, 0.5)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for atan2", function () { var expression = new Expression("atan2(0.0,1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "atan(0.0, 1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for pow", function () { var expression = new Expression("pow(2.0,2.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "pow(2.0, 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for min", function () { var expression = new Expression("min(3.0,5.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "min(3.0, 5.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for max", function () { var expression = new Expression("max(3.0,5.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "max(3.0, 5.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for length", function () { var expression = new Expression("length(3.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "length(3.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for normalize", function () { var expression = new Expression("normalize(3.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "normalize(3.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for distance", function () { var expression = new Expression("distance(0.0, 1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "distance(0.0, 1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for dot", function () { var expression = new Expression("dot(1.0, 2.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "dot(1.0, 2.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for cross", function () { var expression = new Expression( "cross(vec3(1.0, 1.0, 1.0), vec3(2.0, 2.0, 2.0))" ); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "cross(vec3(1.0, 1.0, 1.0), vec3(2.0, 2.0, 2.0))"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for isNaN", function () { var expression = new Expression("isNaN(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(1.0 != 1.0)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for isFinite", function () { var expression = new Expression("isFinite(1.0)"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "(abs(1.0) < czm_infinity)"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for null", function () { var expression = new Expression("null"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "czm_infinity"; expect(shaderExpression).toEqual(expected); }); it("gets shader expression for undefined", function () { var expression = new Expression("undefined"); var shaderExpression = expression.getShaderExpression({}, {}); var expected = "czm_infinity"; expect(shaderExpression).toEqual(expected); }); it("gets variables", function () { var expression = new Expression( '${feature["w"]} + ${feature.x} + ${y} + ${y} + "${z}"' ); var variables = expression.getVariables(); expect(variables.sort()).toEqual(["w", "x", "y", "z"]); }); it("throws when getting shader expression for regex", function () { var expression = new Expression('regExp("a").test("abc")'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); expression = new Expression('regExp("a(.)", "i").exec("Abc")'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); expression = new Expression('regExp("a") =~ "abc"'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); expression = new Expression('regExp("a") !~ "abc"'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for member expression with dot", function () { var expression = new Expression("${property.name}"); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for string member expression with brackets", function () { var expression = new Expression('${property["name"]}'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for String", function () { var expression = new Expression("String(1.0)"); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for toString", function () { var expression = new Expression('color("red").toString()'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for literal string", function () { var expression = new Expression('"name"'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for variable in string", function () { var expression = new Expression('"${property}"'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for isExactClass", function () { var expression = new Expression('isExactClass("door")'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for isClass", function () { var expression = new Expression('isClass("door")'); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); it("throws when getting shader expression for getExactClassName", function () { var expression = new Expression("getExactClassName()"); expect(function () { return expression.getShaderExpression({}, {}); }).toThrowRuntimeError(); }); });