Skip to content

Commit

Permalink
Merge pull request #270 from flightjs/new_attrs_with_constructor_mixin
Browse files Browse the repository at this point in the history
make new attribute impl work with Constructor.mixin
  • Loading branch information
sayrer committed Jun 25, 2014
2 parents f413413 + 9955c8b commit 292783e
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ define(
var newPrototype = Object.create(Component.prototype);
newPrototype.mixedIn = [].concat(Component.prototype.mixedIn);
newPrototype.defaults = utils.merge(Component.prototype.defaults);
newPrototype.attrDef = Component.prototype.attrDef;
compose.mixin(newPrototype, arguments);
newComponent.prototype = newPrototype;
newComponent.prototype.constructor = newComponent;
Expand Down
4 changes: 2 additions & 2 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ define(
merge: function(/*obj1, obj2,....deepCopy*/) {
// unpacking arguments by hand benchmarked faster
var l = arguments.length,
i = 0,
args = new Array(l + 1);
for (; i < l; i++) args[i + 1] = arguments[i];

if (l === 0) {
return {};
}

for (var i=0; i < l; i++) args[i + 1] = arguments[i];

//start with empty object so a copy is created
args[0] = {};

Expand Down
119 changes: 118 additions & 1 deletion test/spec/constructor_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ define(['lib/component'], function (defineComponent) {
expect(TestComponent.toString()).toBe('testComponent, withGoodDefaults');
});

describe('Component.mixin', function () {
describe('Component.mixin with this.defaultAttrs', function () {

var testString1, testString2, testString3 = "";
var TestComponent, AugmentedComponent1, AugmentedComponent2;
Expand Down Expand Up @@ -172,6 +172,123 @@ define(['lib/component'], function (defineComponent) {

});

describe('Component.mixin with this.attributes', function () {

var testString1, testString2, testString3 = "";
var TestComponent, AugmentedComponent1, AugmentedComponent2;

function baseMixin() {
this.attributes({core: 35});
this.fn1 = function() {
testString1 += "testString1"; return testString1
};
this.fn2 = function() {
testString2 += "testString2"; return testString2
};
}

function augmentingMixin1() {
this.attributes({attr1: {thing: 4}});
this.before('fn1', function() {
testString1 += "augmented "
});
this.fn3 = function() {
testString3 += "testString3"; return testString3
};
}

function augmentingMixin2() {
this.attributes({attr1: {thing: 5}});
this.before('fn1', function() {
testString1 += "augmented "
});
this.fn3 = function() {
testString3 += "testString3"; return testString3
};
}

function initData() {
testString1 = "";
testString2 = "";
testString3 = "";
}

beforeEach(function () {
initData();
TestComponent = defineComponent(testComponent, baseMixin);
});

afterEach(function () {
TestComponent.teardownAll();
AugmentedComponent1 && AugmentedComponent1.teardownAll();
AugmentedComponent2 && AugmentedComponent2.teardownAll();
});

it('is a function', function () {
expect(typeof TestComponent.mixin).toBe('function');
});

it('augments a base component', function () {
var instance1 = (new TestComponent).initialize(document.body);
expect(instance1.fn1()).toBe('testString1');
expect(instance1.fn2()).toBe('testString2');
expect(instance1.fn3).not.toBeDefined();

initData();

AugmentedComponent1 = TestComponent.mixin(augmentingMixin1);

var instance2 = (new AugmentedComponent1).initialize(document.body);
expect(instance1.fn1()).toBe('testString1');
expect(instance1.fn2()).toBe('testString2');
expect(instance1.fn3).not.toBeDefined();

initData();

expect(instance2.fn1()).toBe('augmented testString1');
expect(instance2.fn2()).toBe('testString2');
expect(instance2.fn3()).toBe('testString3');
});

it('cannot re-add an original mixin to an augmented component', function () {
AugmentedComponent1 = TestComponent.mixin(augmentingMixin1, baseMixin);
expect(AugmentedComponent1.prototype.mixedIn.length).toBe(TestComponent.prototype.mixedIn.length + 1);
expect(AugmentedComponent1.prototype.mixedIn.filter(function(e) {return e === baseMixin}).length).toBe(1);
});

it('can be repeatedly called even when augmenting mixins share properties', function () {
AugmentedComponent1 = TestComponent.mixin(augmentingMixin1, baseMixin);
AugmentedComponent2 = TestComponent.mixin(augmentingMixin2, baseMixin);
expect(AugmentedComponent1.prototype.mixedIn.length).toBe(TestComponent.prototype.mixedIn.length + 1);
expect(AugmentedComponent2.prototype.mixedIn.length).toBe(TestComponent.prototype.mixedIn.length + 1);
expect(AugmentedComponent1.prototype.mixedIn.filter(function(e) {return e === baseMixin}).length).toBe(1);
expect(AugmentedComponent2.prototype.mixedIn.filter(function(e) {return e === baseMixin}).length).toBe(1);
expect(typeof AugmentedComponent1.prototype.fn3).toBe("function");
expect(typeof AugmentedComponent2.prototype.fn3).toBe("function");
expect(AugmentedComponent1.prototype.attrDef.prototype.attr1).toEqual({thing: 4});
expect(AugmentedComponent1.prototype.attrDef.prototype.constructor.prototype.core).toEqual(35);
expect(AugmentedComponent2.prototype.attrDef.prototype.attr1).toEqual({thing: 5});
expect(AugmentedComponent2.prototype.attrDef.prototype.constructor.prototype.core).toEqual(35);
expect(AugmentedComponent1.prototype.fn3 === AugmentedComponent2.prototype.fn3).toBe(false);
expect(AugmentedComponent1.prototype.attrDef.prototype.attr1 === AugmentedComponent2.prototype.attrDef.prototype.attr1).toBe(false);
});

it('(the AugmentedComponent) can be further augmented', function () {
AugmentedComponent1 = TestComponent.mixin(augmentingMixin1, baseMixin);
var anotherMixin = function() {};
var MoreAugmentedComponent = AugmentedComponent1.mixin(anotherMixin);
expect(AugmentedComponent1.prototype.mixedIn.length).toBe(TestComponent.prototype.mixedIn.length + 1);
expect(MoreAugmentedComponent.prototype.mixedIn.length).toBe(AugmentedComponent1.prototype.mixedIn.length + 1);
expect(MoreAugmentedComponent.prototype.mixedIn.filter(function(e) {return e === baseMixin}).length).toBe(1);
});

it('(the AugmentedComponent) can describe itself', function () {
AugmentedComponent1 = TestComponent.mixin(augmentingMixin1, baseMixin);
expect(AugmentedComponent1.toString()).toBe('testComponent, baseMixin, augmentingMixin1');
});

});

describe('teardownAll', function () {

it('should teardown all instances', function () {
Expand Down

0 comments on commit 292783e

Please sign in to comment.