diff --git a/src/ol/expression/expression.js b/src/ol/expression/expression.js index b309730135..cee19e79c3 100644 --- a/src/ol/expression/expression.js +++ b/src/ol/expression/expression.js @@ -1,10 +1,7 @@ -goog.provide('ol.expression.BooleanLiteral'); goog.provide('ol.expression.Expression'); goog.provide('ol.expression.Identifier'); +goog.provide('ol.expression.Literal'); goog.provide('ol.expression.Not'); -goog.provide('ol.expression.NullLiteral'); -goog.provide('ol.expression.NumericLiteral'); -goog.provide('ol.expression.StringLiteral'); /** @@ -28,40 +25,12 @@ ol.expression.Expression = function() {}; * * @param {Object} scope Evaluation scope. All properties of this object * will be available as variables when evaluating the expression. - * @return {string|number|boolean|null} Result of the expression. + * @return {*} Result of the expression. */ ol.expression.Expression.prototype.evaluate = goog.abstractMethod; -/** - * A boolean literal expression (e.g. `true`). - * - * @constructor - * @extends {ol.expression.Expression} - * @param {boolean} value A boolean value. - */ -ol.expression.BooleanLiteral = function(value) { - - /** - * @type {boolean} - * @private - */ - this.value_ = value; - -}; -goog.inherits(ol.expression.BooleanLiteral, ol.expression.Expression); - - -/** - * @inheritDoc - */ -ol.expression.BooleanLiteral.prototype.evaluate = function(scope) { - return this.value_; -}; - - - /** * An identifier expression (e.g. `foo`). * @@ -90,6 +59,34 @@ ol.expression.Identifier.prototype.evaluate = function(scope) { +/** + * A literal expression (e.g. `"chicken"`, `42`, `true`, `null`). + * + * @constructor + * @extends {ol.expression.Expression} + * @param {string|number|boolean|null} value A literal value. + */ +ol.expression.Literal = function(value) { + + /** + * @type {string|number|boolean|null} + * @private + */ + this.value_ = value; + +}; +goog.inherits(ol.expression.Literal, ol.expression.Expression); + + +/** + * @inheritDoc + */ +ol.expression.Literal.prototype.evaluate = function(scope) { + return this.value_; +}; + + + /** * A logical not expression (e.g. `!foo`). * @@ -116,78 +113,3 @@ ol.expression.Not.prototype.evaluate = function(scope) { return !this.expr_.evaluate(scope); }; - - -/** - * A numeric literal expression (e.g. `42`). - * - * @constructor - * @extends {ol.expression.Expression} - * @param {number} value A numeric value. - */ -ol.expression.NumericLiteral = function(value) { - - /** - * @type {number} - * @private - */ - this.value_ = value; - -}; -goog.inherits(ol.expression.NumericLiteral, ol.expression.Expression); - - -/** - * @inheritDoc - */ -ol.expression.NumericLiteral.prototype.evaluate = function(scope) { - return this.value_; -}; - - - -/** - * A null literal expression (i.e. `null`). - * - * @constructor - * @extends {ol.expression.Expression} - */ -ol.expression.NullLiteral = function() { -}; -goog.inherits(ol.expression.NullLiteral, ol.expression.Expression); - - -/** - * @inheritDoc - */ -ol.expression.NullLiteral.prototype.evaluate = function(scope) { - return null; -}; - - - -/** - * A string literal expression (e.g. `"chicken"`). - * - * @constructor - * @extends {ol.expression.Expression} - * @param {string} value A string. - */ -ol.expression.StringLiteral = function(value) { - - /** - * @type {string} - * @private - */ - this.value_ = value; - -}; -goog.inherits(ol.expression.StringLiteral, ol.expression.Expression); - - -/** - * @inheritDoc - */ -ol.expression.StringLiteral.prototype.evaluate = function(scope) { - return this.value_; -}; diff --git a/src/ol/expression/parser.js b/src/ol/expression/parser.js index 632cf24674..33de610eb0 100644 --- a/src/ol/expression/parser.js +++ b/src/ol/expression/parser.js @@ -2,14 +2,11 @@ goog.provide('ol.expression.Parser'); goog.require('goog.asserts'); -goog.require('ol.expression.BooleanLiteral'); goog.require('ol.expression.Expression'); goog.require('ol.expression.Identifier'); goog.require('ol.expression.Lexer'); +goog.require('ol.expression.Literal'); goog.require('ol.expression.Not'); -goog.require('ol.expression.NullLiteral'); -goog.require('ol.expression.NumericLiteral'); -goog.require('ol.expression.StringLiteral'); goog.require('ol.expression.Token'); goog.require('ol.expression.TokenType'); @@ -159,24 +156,11 @@ ol.expression.Parser.prototype.createIdentifier_ = function(name) { * Create a literal expression. * * @param {string|number|boolean|null} value Literal value. - * @return {ol.expression.StringLiteral|ol.expression.NumericLiteral| - * ol.expression.BooleanLiteral|ol.expression.NullLiteral} The - * expression. + * @return {ol.expression.Literal} The literal expression. * @private */ ol.expression.Parser.prototype.createLiteral_ = function(value) { - var expr; - if (goog.isString(value)) { - expr = new ol.expression.StringLiteral(value); - } else if (goog.isNumber(value)) { - expr = new ol.expression.NumericLiteral(value); - } else if (goog.isBoolean(value)) { - expr = new ol.expression.BooleanLiteral(value); - } else { - goog.asserts.assert(goog.isNull(value)); - expr = new ol.expression.NullLiteral(); - } - return expr; + return new ol.expression.Literal(value); }; diff --git a/test/spec/ol/expression/expression.test.js b/test/spec/ol/expression/expression.test.js index 60a2838abc..99fbc234f9 100644 --- a/test/spec/ol/expression/expression.test.js +++ b/test/spec/ol/expression/expression.test.js @@ -1,19 +1,6 @@ goog.provide('ol.test.expression.Expression'); -describe('ol.expression.BooleanLiteral', function() { - - describe('constructor', function() { - it('creates a new expression', function() { - var expr = new ol.expression.BooleanLiteral(true); - expect(expr).to.be.a(ol.expression.Expression); - expect(expr).to.be.a(ol.expression.BooleanLiteral); - }); - }); - -}); - - describe('ol.expression.Identifier', function() { describe('constructor', function() { @@ -24,62 +11,115 @@ describe('ol.expression.Identifier', function() { }); }); + describe('#evaluate()', function() { + it('returns a number from the scope', function() { + var expr = new ol.expression.Identifier('foo'); + expect(expr.evaluate({foo: 42})).to.be(42); + }); + + it('returns a string from the scope', function() { + var expr = new ol.expression.Identifier('foo'); + expect(expr.evaluate({foo: 'chicken'})).to.be('chicken'); + }); + + it('returns a boolean from the scope', function() { + var expr = new ol.expression.Identifier('bar'); + expect(expr.evaluate({bar: false})).to.be(false); + expect(expr.evaluate({bar: true})).to.be(true); + }); + + it('returns a null from the scope', function() { + var expr = new ol.expression.Identifier('nada'); + expect(expr.evaluate({nada: null})).to.be(null); + }); + + it('works for unicode identifiers', function() { + var expr = new ol.expression.Identifier('\u03c0'); + expect(expr.evaluate({'\u03c0': Math.PI})).to.be(Math.PI); + }); + }); + }); +describe('ol.expression.Literal', function() { + + describe('constructor', function() { + it('creates a new expression', function() { + var expr = new ol.expression.Literal(true); + expect(expr).to.be.a(ol.expression.Expression); + expect(expr).to.be.a(ol.expression.Literal); + }); + }); + + describe('#evaluate()', function() { + it('works for numeric literal', function() { + var expr = new ol.expression.Literal(42e-11); + expect(expr.evaluate({})).to.be(4.2e-10); + }); + + it('works for string literal', function() { + var expr = new ol.expression.Literal('asdf'); + expect(expr.evaluate({})).to.be('asdf'); + }); + + it('works for boolean literal', function() { + var expr = new ol.expression.Literal(true); + expect(expr.evaluate({})).to.be(true); + }); + + it('works for null literal', function() { + var expr = new ol.expression.Literal(null); + expect(expr.evaluate({})).to.be(null); + }); + }); +}); + + describe('ol.expression.Not', function() { describe('constructor', function() { it('creates a new expression', function() { var expr = new ol.expression.Not( - new ol.expression.BooleanLiteral(true)); + new ol.expression.Literal(true)); expect(expr).to.be.a(ol.expression.Expression); expect(expr).to.be.a(ol.expression.Not); }); }); -}); + describe('#evaluate()', function() { + it('returns the logical complement', function() { + var expr = new ol.expression.Not(new ol.expression.Literal(true)); + expect(expr.evaluate({})).to.be(false); -describe('ol.expression.NullLiteral', function() { - - describe('constructor', function() { - it('creates a new expression', function() { - var expr = new ol.expression.NullLiteral(); - expect(expr).to.be.a(ol.expression.Expression); - expect(expr).to.be.a(ol.expression.NullLiteral); + expr = new ol.expression.Not(new ol.expression.Literal(false)); + expect(expr.evaluate({})).to.be(true); }); - }); -}); - -describe('ol.expression.NumericLiteral', function() { - - describe('constructor', function() { - it('creates a new expression', function() { - var expr = new ol.expression.NumericLiteral(42); - expect(expr).to.be.a(ol.expression.Expression); - expect(expr).to.be.a(ol.expression.NumericLiteral); + it('negates a truthy string', function() { + var expr = new ol.expression.Not(new ol.expression.Literal('asdf')); + expect(expr.evaluate({})).to.be(false); }); - }); -}); + it('negates a falsy string', function() { + var expr = new ol.expression.Not(new ol.expression.Literal('')); + expect(expr.evaluate({})).to.be(true); + }); -describe('ol.expression.StringLiteral', function() { + it('negates a truthy number', function() { + var expr = new ol.expression.Not(new ol.expression.Literal(42)); + expect(expr.evaluate({})).to.be(false); + }); - describe('constructor', function() { - it('creates a new expression', function() { - var expr = new ol.expression.StringLiteral('bar'); - expect(expr).to.be.a(ol.expression.Expression); - expect(expr).to.be.a(ol.expression.StringLiteral); + it('negates a falsy number', function() { + var expr = new ol.expression.Not(new ol.expression.Literal(NaN)); + expect(expr.evaluate({})).to.be(true); }); }); }); -goog.require('ol.expression.BooleanLiteral'); goog.require('ol.expression.Expression'); goog.require('ol.expression.Identifier'); +goog.require('ol.expression.Literal'); goog.require('ol.expression.Not'); -goog.require('ol.expression.NullLiteral'); -goog.require('ol.expression.NumericLiteral'); -goog.require('ol.expression.StringLiteral');