fix(parser): Fix short circuit of logical AND and OR operators

Closes #433
This commit is contained in:
Dhruv Manek 2011-09-30 16:55:01 -07:00 committed by Igor Minar
parent 29d36e94e1
commit e1ecc34edd
2 changed files with 38 additions and 22 deletions

View file

@ -5,25 +5,25 @@ var OPERATORS = {
'true':function(self){return true;}, 'true':function(self){return true;},
'false':function(self){return false;}, 'false':function(self){return false;},
$undefined:noop, $undefined:noop,
'+':function(self, a,b){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 (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*b;}, '*':function(self, a,b){return a(self)*b(self);},
'/':function(self, a,b){return a/b;}, '/':function(self, a,b){return a(self)/b(self);},
'%':function(self, a,b){return a%b;}, '%':function(self, a,b){return a(self)%b(self);},
'^':function(self, a,b){return a^b;}, '^':function(self, a,b){return a(self)^b(self);},
'=':noop, '=':noop,
'==':function(self, a,b){return a==b;}, '==':function(self, a,b){return a(self)==b(self);},
'!=':function(self, a,b){return a!=b;}, '!=':function(self, a,b){return a(self)!=b(self);},
'<':function(self, a,b){return a<b;}, '<':function(self, a,b){return a(self)<b(self);},
'>':function(self, a,b){return a>b;}, '>':function(self, a,b){return a(self)>b(self);},
'<=':function(self, a,b){return a<=b;}, '<=':function(self, a,b){return a(self)<=b(self);},
'>=':function(self, a,b){return a>=b;}, '>=':function(self, a,b){return a(self)>=b(self);},
'&&':function(self, a,b){return a&&b;}, '&&':function(self, a,b){return a(self)&&b(self);},
'||':function(self, a,b){return a||b;}, '||':function(self, a,b){return a(self)||b(self);},
'&':function(self, a,b){return a&b;}, '&':function(self, a,b){return a(self)&b(self);},
// '|':function(self, a,b){return a|b;}, // '|':function(self, a,b){return a|b;},
'|':function(self, a,b){return b(self, a);}, '|':function(self, a,b){return b(self)(self, a(self));},
'!':function(self, a){return !a;} '!':function(self, a){return !a(self);}
}; };
var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'}; var ESCAPE = {"n":"\n", "f":"\f", "r":"\r", "t":"\t", "v":"\v", "'":"'", '"':'"'};
@ -308,13 +308,13 @@ function parser(text, json){
function unaryFn(fn, right) { function unaryFn(fn, right) {
return function(self) { return function(self) {
return fn(self, right(self)); return fn(self, right);
}; };
} }
function binaryFn(left, fn, right) { function binaryFn(left, fn, right) {
return function(self) { return function(self) {
return fn(self, left(self), right(self)); return fn(self, left, right);
}; };
} }

View file

@ -391,7 +391,7 @@ describe('parser', function() {
expect(scope.a).not.toBeDefined(); 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 = angular.scope();
scope.obj = [{}]; scope.obj = [{}];
scope.$eval('obj[0].name=1'); scope.$eval('obj[0].name=1');
@ -399,14 +399,30 @@ describe('parser', function() {
expect(scope.obj[0].name).toEqual(1); 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() { it('should return no argument function', function() {
var noop = parser('noop').formatter()(); var noop = parser('noop').formatter()();
expect(noop.format(null, 'abc')).toEqual('abc'); expect(noop.format(null, 'abc')).toEqual('abc');
expect(noop.parse(null, '123')).toEqual('123'); expect(noop.parse(null, '123')).toEqual('123');
}); });
it('should delegate arguments', function(){ it('should delegate arguments', function() {
angularFormatter.myArgs = { angularFormatter.myArgs = {
parse: function(a, b){ return [a, b]; }, parse: function(a, b){ return [a, b]; },
format: function(a, b){ return [a, b]; } format: function(a, b){ return [a, b]; }