Make options object prototype-inherited

Fixes #2294
This commit is contained in:
John Firebaugh 2013-12-15 13:30:22 -08:00
parent f619e3b242
commit ad9d0f8c7f
4 changed files with 70 additions and 10 deletions

View File

@ -99,12 +99,22 @@ describe("Class", function () {
}); });
var a = new KlassWithOptions2(); var a = new KlassWithOptions2();
expect(a.options.foo1).to.eql(1);
expect(a.options.foo2).to.eql(3);
expect(a.options.foo3).to.eql(4);
});
expect(a.options).to.eql({ it("gives new classes a distinct options object", function () {
foo1: 1, var K1 = L.Class.extend({options: {}});
foo2: 3, var K2 = K1.extend({});
foo3: 4 expect(K2.prototype.options).not.to.equal(K1.prototype.options);
}); });
it("inherits options prototypally", function () {
var K1 = L.Class.extend({options: {}});
var K2 = K1.extend({options: {}});
K1.prototype.options.foo = 'bar';
expect(K2.prototype.options.foo).to.eql('bar');
}); });
it("adds constructor hooks correctly", function () { it("adds constructor hooks correctly", function () {

View File

@ -185,7 +185,47 @@ describe('Util', function () {
}); });
}); });
// TODO setOptions describe('#setOptions', function () {
it('sets specified options on object', function () {
var o = {};
L.Util.setOptions(o, {foo: 'bar'});
expect(o.options.foo).to.eql('bar');
});
it('returns options', function () {
var o = {};
var r = L.Util.setOptions(o, {foo: 'bar'});
expect(r).to.equal(o.options);
});
it('accepts undefined', function () {
var o = {};
L.Util.setOptions(o, undefined);
expect(o.options).to.eql({});
});
it('creates a distinct options object', function () {
var opts = {},
o = L.Util.create({options: opts});
L.Util.setOptions(o, {});
expect(o.options).not.to.equal(opts);
});
it("doesn't create a distinct options object if object already has own options", function () {
var opts = {},
o = {options: opts};
L.Util.setOptions(o, {});
expect(o.options).to.equal(opts);
});
it('inherits options prototypally', function () {
var opts = {},
o = L.Util.create({options: opts});
L.Util.setOptions(o, {});
opts.foo = 'bar';
expect(o.options.foo).to.eql('bar');
});
});
describe('#template', function () { describe('#template', function () {
it('evaluates templates with a given data object', function () { it('evaluates templates with a given data object', function () {

View File

@ -50,8 +50,8 @@ L.Class.extend = function (props) {
} }
// merge options // merge options
if (props.options && proto.options) { if (proto.options) {
props.options = L.extend({}, proto.options, props.options); props.options = L.Util.extend(L.Util.create(proto.options), props.options);
} }
// mix given properties into the prototype // mix given properties into the prototype

View File

@ -18,6 +18,14 @@ L.Util = {
return dest; return dest;
}, },
create: Object.create || (function () {
function F() {}
return function (proto) {
F.prototype = proto;
return new F();
};
})(),
bind: function (fn, obj) { bind: function (fn, obj) {
var slice = Array.prototype.slice; var slice = Array.prototype.slice;
@ -107,8 +115,10 @@ L.Util = {
}, },
setOptions: function (obj, options) { setOptions: function (obj, options) {
obj.options = options ? L.extend({}, obj.options, options) : obj.options || {}; if (!obj.hasOwnProperty('options')) {
return obj.options; obj.options = obj.options ? L.Util.create(obj.options) : {};
}
return L.extend(obj.options, options);
}, },
getParamString: function (obj, existingUrl, uppercase) { getParamString: function (obj, existingUrl, uppercase) {