diff --git a/test/expression.test.js b/test/expression.test.js index 5225b075679..1270eb185a4 100644 --- a/test/expression.test.js +++ b/test/expression.test.js @@ -14,55 +14,66 @@ expressionSuite.run('js', { ignores, tests }, (fixture) => { spec['function'] = true; spec['property-function'] = true; - let expression = createPropertyExpression(fixture.expression, spec); - if (expression.result === 'error') { - return { - compiled: { - result: 'error', - errors: expression.value.map((err) => ({ - key: err.key, - error: err.message - })) - } - }; - } + const evaluateExpression = (expression, compilationResult) => { + if (expression.result === 'error') { + compilationResult.result = 'error'; + compilationResult.errors = expression.value.map((err) => ({ + key: err.key, + error: err.message + })); + return; + } - expression = expression.value; + const evaluationResult = []; - const type = expression._styleExpression.expression.type; // :scream: + expression = expression.value; + const type = expression._styleExpression.expression.type; // :scream: - const outputs = []; - const result = { - outputs, - compiled: { - result: 'success', - isFeatureConstant: expression.kind === 'constant' || expression.kind === 'camera', - isZoomConstant: expression.kind === 'constant' || expression.kind === 'source', - type: toString(type) - } - }; + compilationResult.result = 'success'; + compilationResult.isFeatureConstant = expression.kind === 'constant' || expression.kind === 'camera'; + compilationResult.isZoomConstant = expression.kind === 'constant' || expression.kind === 'source'; + compilationResult.type = toString(type); - for (const input of fixture.inputs || []) { - try { - const feature = { properties: input[1].properties || {} }; - if ('id' in input[1]) { - feature.id = input[1].id; - } - if ('geometry' in input[1]) { - feature.type = input[1].geometry.type; - } - let value = expression.evaluateWithoutErrorHandling(input[0], feature); - if (type.kind === 'color') { - value = [value.r, value.g, value.b, value.a]; - } - outputs.push(value); - } catch (error) { - if (error.name === 'ExpressionEvaluationError') { - outputs.push({ error: error.toJSON() }); - } else { - outputs.push({ error: error.message }); + for (const input of fixture.inputs || []) { + try { + const feature = { properties: input[1].properties || {} }; + if ('id' in input[1]) { + feature.id = input[1].id; + } + if ('geometry' in input[1]) { + feature.type = input[1].geometry.type; + } + let value = expression.evaluateWithoutErrorHandling(input[0], feature); + if (type.kind === 'color') { + value = [value.r, value.g, value.b, value.a]; + } + evaluationResult.push(value); + } catch (error) { + if (error.name === 'ExpressionEvaluationError') { + evaluationResult.push({ error: error.toJSON() }); + } else { + evaluationResult.push({ error: error.message }); + } } } + + if (fixture.inputs) { + return evaluationResult; + } + }; + + const result = { compiled: {}, recompiled: {} }; + const expression = createPropertyExpression(fixture.expression, spec); + result.outputs = evaluateExpression(expression, result.compiled); + if (expression.result === 'success') { + result.serialized = expression.value._styleExpression.expression.serialize(); + result.roundTripOutputs = evaluateExpression( + createPropertyExpression(result.serialized, spec), + result.recompiled); + // Type is allowed to change through serialization + // (eg "array" -> "array") + // Override the round-tripped type here so that the equality check passes + result.recompiled.type = result.compiled.type; } return result; diff --git a/test/integration/lib/expression.js b/test/integration/lib/expression.js index b028a1503dd..13abf61d16c 100644 --- a/test/integration/lib/expression.js +++ b/test/integration/lib/expression.js @@ -95,20 +95,10 @@ exports.run = function (implementation, options, runExpressionTest) { const dir = path.join(directory, params.group, params.test); if (process.env.UPDATE) { - // If we're updating from GL JS, where `result.serialized` will not exist, - // just copy the existing expected value, or default to expect the - // serialized form to be identical to the input expression - const previousSerialized = - (fixture.expected && fixture.expected.serialized !== undefined) ? - fixture.expected.serialized : - undefined; - fixture.expected = { compiled: result.compiled, outputs: stripPrecision(result.outputs), - serialized: implementation === 'native' ? - result.serialized : - previousSerialized + serialized: result.serialized }; fs.writeFile(path.join(dir, 'test.json'), `${stringify(fixture, null, 2)}\n`, done); @@ -119,12 +109,10 @@ exports.run = function (implementation, options, runExpressionTest) { const compileOk = deepEqual(result.compiled, expected.compiled); const evalOk = compileOk && deepEqual(result.outputs, expected.outputs); - // Serialization/round-tripping only exists on native let recompileOk = true; let roundTripOk = true; let serializationOk = true; - - if (implementation === 'native' && expected.compiled.result !== 'error') { + if (expected.compiled.result !== 'error') { serializationOk = compileOk && deepEqual(expected.serialized, result.serialized); recompileOk = compileOk && deepEqual(result.recompiled, expected.compiled); roundTripOk = recompileOk && deepEqual(result.roundTripOutputs, expected.outputs);