Skip to content

Commit

Permalink
fix(parse): Fix context access and double function call
Browse files Browse the repository at this point in the history
Fix a context duplication and invocation to a previous context when
doing an access modifier function on the result of a function

Closes angular#2496
  • Loading branch information
lgalfaso committed Apr 25, 2013
1 parent 2629f7f commit 0305753
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 12 deletions.
20 changes: 10 additions & 10 deletions src/ng/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,8 @@ function parser(text, json, $filter, csp){
text.substring(0, token.index) + "] can not be assigned to", token);
}
right = logicalOR();
return function(self, locals){
return left.assign(self, right(self, locals), locals);
return function(scope, locals){
return left.assign(scope, right(scope, locals), locals);
};
} else {
return left;
Expand Down Expand Up @@ -559,12 +559,12 @@ function parser(text, json, $filter, csp){
var field = expect().text;
var getter = getterFn(field, csp);
return extend(
function(self, locals) {
return getter(object(self, locals), locals);
function(scope, locals, self) {
return getter(self || object(scope, locals), locals);
},
{
assign:function(self, value, locals) {
return setter(object(self, locals), field, value);
assign:function(scope, value, locals) {
return setter(object(scope, locals), field, value);
}
}
);
Expand Down Expand Up @@ -605,14 +605,14 @@ function parser(text, json, $filter, csp){
} while (expect(','));
}
consume(')');
return function(self, locals){
return function(scope, locals){
var args = [],
context = contextGetter ? contextGetter(self, locals) : self;
context = contextGetter ? contextGetter(scope, locals) : scope;

for ( var i = 0; i < argsFn.length; i++) {
args.push(argsFn[i](self, locals));
args.push(argsFn[i](scope, locals));
}
var fnPtr = fn(self, locals) || noop;
var fnPtr = fn(scope, locals, context) || noop;
// IE stupidity!
return fnPtr.apply
? fnPtr.apply(context, args)
Expand Down
99 changes: 97 additions & 2 deletions test/ng/parseSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,108 @@ describe('parser', function() {
});


it('should call the function from the received instance and not from a new one', function() {
var n = 0;
scope.fn = function() {
var c = n++;
return { c: c, anotherFn: function() { return this.c == c; } };
};
expect(scope.$eval('fn().anotherFn()')).toBe(true);
});


it('should call the function once when it is part of the context', function() {
var count = 0;
scope.fn = function() {
count++;
return { anotherFn: function() { return "lucas"; } };
};
expect(scope.$eval('fn().anotherFn()')).toBe('lucas');
expect(count).toBe(1);
});


it('should call the function once when it is not part of the context', function() {
var count = 0;
scope.fn = function() {
count++;
return function() { return 'lucas'; };
};
expect(scope.$eval('fn()()')).toBe('lucas');
expect(count).toBe(1);
});


it('should call the function once when it is not part of the context', function() {
var count = 0;
scope.fn = function() {
count++;
return function() { return 'lucas'; };
};
expect(scope.$eval('fn()()')).toBe('lucas');
expect(count).toBe(1);
});


it('should call the function once when it is part of the context on assignments', function() {
var count = 0;
var element = {};
scope.fn = function() {
count++;
return element;
};
expect(scope.$eval('fn().name = "lucas"')).toBe('lucas');
expect(element.name).toBe('lucas');
expect(count).toBe(1);
});


it('should call the function once when it is part of the context on array lookups', function() {
var count = 0;
var element = [];
scope.fn = function() {
count++;
return element;
};
expect(scope.$eval('fn()[0] = "lucas"')).toBe('lucas');
expect(element[0]).toBe('lucas');
expect(count).toBe(1);
});


it('should call the function once when it is part of the context on array lookup function', function() {
var count = 0;
var element = [{anotherFn: function() { return 'lucas';} }];
scope.fn = function() {
count++;
return element;
};
expect(scope.$eval('fn()[0].anotherFn()')).toBe('lucas');
expect(count).toBe(1);
});


it('should call the function once when it is part of the context on array lookup function', function() {
var count = 0;
var element = {name: {anotherFn: function() { return 'lucas';} } };
scope.fn = function() {
count++;
return element;
};
expect(scope.$eval('fn().name.anotherFn()')).toBe('lucas');
expect(count).toBe(1);
});


it('should call the function once when it is part of a sub-expression', function() {
var count = 0;
scope.element = [{}];
scope.fn = function() {
count++;
return 0;
};
scope.fn.anotherFn = function() { return ''; };
expect(scope.$eval('fn().anotherFn()')).toBe('');
expect(scope.$eval('element[fn()].name = "lucas"')).toBe('lucas');
expect(scope.element[0].name).toBe('lucas');
expect(count).toBe(1);
});

Expand Down

0 comments on commit 0305753

Please sign in to comment.