aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDhruv Manek2011-09-30 16:55:01 -0700
committerIgor Minar2011-10-07 16:01:09 -0700
commite1ecc34edd19b95d51fbcb1351b04b9876c974c1 (patch)
tree7b71b421e03cc27faaa86581ca8262026330505c
parent29d36e94e101c76da58421cab6828146b041b108 (diff)
downloadangular.js-e1ecc34edd19b95d51fbcb1351b04b9876c974c1.tar.bz2
fix(parser): Fix short circuit of logical AND and OR operators
Closes #433
-rw-r--r--src/parser.js38
-rw-r--r--test/ParserSpec.js22
2 files changed, 38 insertions, 22 deletions
diff --git a/src/parser.js b/src/parser.js
index 5129f2f7..f8978a0b 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -5,25 +5,25 @@ var OPERATORS = {
'true':function(self){return true;},
'false':function(self){return false;},
$undefined:noop,
- '+':function(self, a,b){return (isDefined(a)?a:0)+(isDefined(b)?b:0);},
- '-':function(self, a,b){return (isDefined(a)?a:0)-(isDefined(b)?b:0);},
- '*':function(self, a,b){return a*b;},
- '/':function(self, a,b){return a/b;},
- '%':function(self, a,b){return a%b;},
- '^':function(self, a,b){return a^b;},
+ '+':function(self, a,b){a=a(self); b=b(self); return (isDefined(a)?a:0)+(isDefined(b)?b:0);},
+ '-':function(self, a,b){a=a(self); b=b(self); return (isDefined(a)?a:0)-(isDefined(b)?b:0);},
+ '*':function(self, a,b){return a(self)*b(self);},
+ '/':function(self, a,b){return a(self)/b(self);},
+ '%':function(self, a,b){return a(self)%b(self);},
+ '^':function(self, a,b){return a(self)^b(self);},
'=':noop,
- '==':function(self, a,b){return a==b;},
- '!=':function(self, a,b){return a!=b;},
- '<':function(self, a,b){return a<b;},
- '>':function(self, a,b){return a>b;},
- '<=':function(self, a,b){return a<=b;},
- '>=':function(self, a,b){return a>=b;},
- '&&':function(self, a,b){return a&&b;},
- '||':function(self, a,b){return a||b;},
- '&':function(self, a,b){return a&b;},
+ '==':function(self, a,b){return a(self)==b(self);},
+ '!=':function(self, a,b){return a(self)!=b(self);},
+ '<':function(self, a,b){return a(self)<b(self);},
+ '>':function(self, a,b){return a(self)>b(self);},
+ '<=':function(self, a,b){return a(self)<=b(self);},
+ '>=':function(self, a,b){return a(self)>=b(self);},
+ '&&':function(self, a,b){return a(self)&&b(self);},
+ '||':function(self, a,b){return a(self)||b(self);},
+ '&':function(self, a,b){return a(self)&b(self);},
// '|':function(self, a,b){return a|b;},
- '|':function(self, a,b){return b(self, a);},
- '!':function(self, a){return !a;}
+ '|':function(self, a,b){return b(self)(self, a(self));},
+ '!':function(self, a){return !a(self);}
};
var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
@@ -308,13 +308,13 @@ function parser(text, json){
function unaryFn(fn, right) {
return function(self) {
- return fn(self, right(self));
+ return fn(self, right);
};
}
function binaryFn(left, fn, right) {
return function(self) {
- return fn(self, left(self), right(self));
+ return fn(self, left, right);
};
}
diff --git a/test/ParserSpec.js b/test/ParserSpec.js
index 4c3cb64b..a5e1901c 100644
--- a/test/ParserSpec.js
+++ b/test/ParserSpec.js
@@ -391,7 +391,7 @@ describe('parser', function() {
expect(scope.a).not.toBeDefined();
});
- it('should allow assignment after array dereference', function(){
+ it('should allow assignment after array dereference', function() {
scope = angular.scope();
scope.obj = [{}];
scope.$eval('obj[0].name=1');
@@ -399,14 +399,30 @@ describe('parser', function() {
expect(scope.obj[0].name).toEqual(1);
});
- describe('formatter', function(){
+ it('should short-circuit AND operator', function() {
+ var scope = angular.scope();
+ scope.run = function() {
+ throw "IT SHOULD NOT HAVE RUN";
+ };
+ expect(scope.$eval('false && run()')).toBe(false);
+ });
+
+ it('should short-circuit OR operator', function() {
+ var scope = angular.scope();
+ scope.run = function() {
+ throw "IT SHOULD NOT HAVE RUN";
+ };
+ expect(scope.$eval('true || run()')).toBe(true);
+ });
+
+ describe('formatter', function() {
it('should return no argument function', function() {
var noop = parser('noop').formatter()();
expect(noop.format(null, 'abc')).toEqual('abc');
expect(noop.parse(null, '123')).toEqual('123');
});
- it('should delegate arguments', function(){
+ it('should delegate arguments', function() {
angularFormatter.myArgs = {
parse: function(a, b){ return [a, b]; },
format: function(a, b){ return [a, b]; }