From 992114f7a7f5f39778753e0c49458f14b6290ffc Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Sat, 18 Apr 2015 21:29:43 +0100 Subject: [PATCH] fix(ngMessageFormat): ensure bindings are valid for Protractor Closes #11644 Closes #11649 --- src/ngMessageFormat/messageFormatCommon.js | 4 ++-- .../messageFormatInterpolationParts.js | 6 +++--- src/ngMessageFormat/messageFormatParser.js | 13 ++++++++----- src/ngMessageFormat/messageFormatSelector.js | 2 ++ src/ngMessageFormat/messageFormatService.js | 14 +++++++------- test/ngMessageFormat/messageFormatSpec.js | 8 ++++++++ 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/ngMessageFormat/messageFormatCommon.js b/src/ngMessageFormat/messageFormatCommon.js index 7831c82b1924..19af9d30f208 100644 --- a/src/ngMessageFormat/messageFormatCommon.js +++ b/src/ngMessageFormat/messageFormatCommon.js @@ -51,8 +51,8 @@ function parseTextLiteral(text) { return unwatch; }; PARSE_CACHE_FOR_TEXT_LITERALS[text] = parsedFn; - parsedFn.exp = text; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - parsedFn.expressions = []; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. + parsedFn['exp'] = text; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + parsedFn['expressions'] = []; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. return parsedFn; } diff --git a/src/ngMessageFormat/messageFormatInterpolationParts.js b/src/ngMessageFormat/messageFormatInterpolationParts.js index 0be2386a1d5d..3a31d427c8f6 100644 --- a/src/ngMessageFormat/messageFormatInterpolationParts.js +++ b/src/ngMessageFormat/messageFormatInterpolationParts.js @@ -95,10 +95,10 @@ InterpolationParts.prototype.toParsedFn = function toParsedFn(mustHaveExpression return self.watchDelegate(scope, listener, objectEquality); }; - parsedFn.exp = originalText; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - parsedFn.expressions = new Array(this.expressionFns.length); // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. + parsedFn['exp'] = originalText; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + parsedFn['expressions'] = new Array(this.expressionFns.length); // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. for (var i = 0; i < this.expressionFns.length; i++) { - parsedFn.expressions[i] = this.expressionFns[i].exp; + parsedFn['expressions'][i] = this.expressionFns[i]['exp']; } return parsedFn; diff --git a/src/ngMessageFormat/messageFormatParser.js b/src/ngMessageFormat/messageFormatParser.js index 75327ffedc80..7bca41c98409 100644 --- a/src/ngMessageFormat/messageFormatParser.js +++ b/src/ngMessageFormat/messageFormatParser.js @@ -412,8 +412,8 @@ MessageFormatParser.prototype.ruleEndMustache = function ruleEndMustache() { // such a case we do not want to unnecessarily stringify something if it's not going to be used // in a string context. this.parsedFn = this.$parse(this.expressionFn, this.stringifier); - this.parsedFn.exp = this.expressionFn.exp; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.parsedFn.expressions = this.expressionFn.expressions; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. + this.parsedFn['exp'] = this.expressionFn['exp']; // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js + this.parsedFn['expressions'] = this.expressionFn['expressions']; // Require this to call $compile.$$addBindingInfo() which allows Protractor to find elements by binding. } this.rule = null; }; @@ -461,7 +461,8 @@ MessageFormatParser.prototype.ruleInAngularExpression = function ruleInAngularEx this.index = this.text.length; this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, this.index)); // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.expressionFn.exp = this.text.substring(this.expressionStartIndex, this.index); + this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, this.index); + this.expressionFn['expressions'] = this.expressionFn['expressions']; this.rule = null; return; } @@ -488,7 +489,8 @@ MessageFormatParser.prototype.ruleInAngularExpression = function ruleInAngularEx // todo: does this need to be trimmed? this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, match.index)); // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.expressionFn.exp = this.text.substring(this.expressionStartIndex, match.index); + this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, match.index); + this.expressionFn['expressions'] = this.expressionFn['expressions']; this.rule = null; this.rule = this.rulePluralOrSelect; } @@ -516,6 +518,7 @@ MessageFormatParser.prototype.ruleInAngularExpression = function ruleInAngularEx this.index = match.index; this.expressionFn = this.$parse(this.text.substring(this.expressionStartIndex, this.index)); // Needed to pretend to be $interpolate for tests copied from interpolateSpec.js - this.expressionFn.exp = this.text.substring(this.expressionStartIndex, this.index); + this.expressionFn['exp'] = this.text.substring(this.expressionStartIndex, this.index); + this.expressionFn['expressions'] = this.expressionFn['expressions']; this.rule = null; }; diff --git a/src/ngMessageFormat/messageFormatSelector.js b/src/ngMessageFormat/messageFormatSelector.js index 6997354594f3..b7cc52e37957 100644 --- a/src/ngMessageFormat/messageFormatSelector.js +++ b/src/ngMessageFormat/messageFormatSelector.js @@ -24,6 +24,8 @@ function MessageSelectorBase(expressionFn, choices) { this.parsedFn['$$watchDelegate'] = function $$watchDelegate(scope, listener, objectEquality) { return self.watchDelegate(scope, listener, objectEquality); }; + this.parsedFn['exp'] = expressionFn['exp']; + this.parsedFn['expressions'] = expressionFn['expressions']; } MessageSelectorBase.prototype.getMessageFn = function getMessageFn(value) { diff --git a/src/ngMessageFormat/messageFormatService.js b/src/ngMessageFormat/messageFormatService.js index 6f3abfc0f892..98baf9d3143f 100644 --- a/src/ngMessageFormat/messageFormatService.js +++ b/src/ngMessageFormat/messageFormatService.js @@ -24,12 +24,12 @@ * *
*
- * {{recipients.length, plural, offset:1 - * =0 {{{sender.name}} gave no gifts (\#=#)} - * =1 {{{sender.name}} gave one gift to {{recipients[0].name}} (\#=#)} - * one {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\#=#)} - * other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\#=#)} - * }} + * {{recipients.length, plural, offset:1 + * =0 {{{sender.name}} gave no gifts (\#=#)} + * =1 {{{sender.name}} gave one gift to {{recipients[0].name}} (\#=#)} + * one {{{sender.name}} gave {{recipients[0].name}} and one other person a gift (\#=#)} + * other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\#=#)} + * }} *
*
* @@ -57,7 +57,7 @@ * * describe('MessageFormat plural', function() { * it('should pluralize initial values', function() { - * var messageElem = element(by.id('message')), decreaseRecipientsBtn = element(by.id('decreaseRecipients')); + * var messageElem = element(by.binding('recipients.length')), decreaseRecipientsBtn = element(by.id('decreaseRecipients')); * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and 2 other people a gift (#=2)'); * decreaseRecipientsBtn.click(); * expect(messageElem.getText()).toEqual('Harry Potter gave Alice and one other person a gift (#=1)'); diff --git a/test/ngMessageFormat/messageFormatSpec.js b/test/ngMessageFormat/messageFormatSpec.js index 86bbc824ad7f..d8bda839975f 100644 --- a/test/ngMessageFormat/messageFormatSpec.js +++ b/test/ngMessageFormat/messageFormatSpec.js @@ -126,6 +126,8 @@ describe('$$ngMessageFormat', function() { " other {You gave some people gifts}\n" + "}}"; var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); + expect(parsedFn.expressions.length).toBe(1); + expect(parsedFn.expressions[0]).toEqual("recipients.length"); $rootScope.recipients.length=2; expect(parsedFn($rootScope)).toEqual("You gave some people gifts"); @@ -147,6 +149,8 @@ describe('$$ngMessageFormat', function() { " other {{{sender.name}} gave them a gift}\n" + "}}"; var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); + expect(parsedFn.expressions.length).toBe(1); + expect(parsedFn.expressions[0]).toEqual("recipients.length"); $rootScope.recipients.length=2; expect(parsedFn($rootScope)).toEqual("Harry Potter gave them a gift"); @@ -168,6 +172,8 @@ describe('$$ngMessageFormat', function() { " other {{{sender.name}} gave {{recipients[0].name}} and # other people a gift (\\#=#)}\n" + "}}"; var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); + expect(parsedFn.expressions.length).toBe(1); + expect(parsedFn.expressions[0]).toEqual("recipients.length"); $rootScope.recipients.length=3; // "#" should get replaced with the value of "recipients.length - offset" @@ -197,6 +203,8 @@ describe('$$ngMessageFormat', function() { " other {You gave {{recipients.length}} people gifts. -{{sender.name}}}\n" + "}}"; var parsedFn = $interpolate(text, /*mustHaveExpression=*/true); + expect(parsedFn.expressions.length).toBe(1); + expect(parsedFn.expressions[0]).toEqual("recipients.length"); var result = parsedFn($rootScope); expect(result).toEqual("You gave 3 people gifts. -Harry Potter"); });