Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Fixes an issue with parse/eval #2509

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
106 changes: 106 additions & 0 deletions test/ng/parseSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,112 @@ 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;
};
expect(scope.$eval('element[fn()].name = "lucas"')).toBe('lucas');
expect(scope.element[0].name).toBe('lucas');
expect(count).toBe(1);
});


describe('promises', function() {
var deferred, promise, q;

Expand Down