diff --git a/src/core/a-entity.js b/src/core/a-entity.js index e63bd691f3e..62ce484f8dc 100644 --- a/src/core/a-entity.js +++ b/src/core/a-entity.js @@ -310,17 +310,7 @@ class AEntity extends ANode { // Initialize dependencies first this.initComponentDependencies(componentName); - // If component is sceneOnly check the entity is the scene element - if (!this.isScene && COMPONENTS[componentName].sceneOnly) { - throw new Error('Component `' + componentName + '` can only be applied to '); - } - - // If component name has an id we check component type multiplicity. - if (componentId && !COMPONENTS[componentName].multiple) { - throw new Error('Trying to initialize multiple ' + - 'components of type `' + componentName + - '`. There can only be one component of this type per entity.'); - } + // Initialize component component = new COMPONENTS[componentName].Component(this, data, componentId); if (this.isPlaying) { component.play(); } diff --git a/src/core/component.js b/src/core/component.js index 2b337ce93a7..d1ac4e558a3 100644 --- a/src/core/component.js +++ b/src/core/component.js @@ -36,6 +36,19 @@ var emptyInitialOldData = Object.freeze({}); */ var Component = module.exports.Component = function (el, attrValue, id) { var self = this; + + // If component is sceneOnly check the entity is the scene element + if (this.sceneOnly && !el.isScene) { + throw new Error('Component `' + this.name + '` can only be applied to '); + } + + // If component name has an id we check component type multiplicity. + if (id && !this.multiple) { + throw new Error('Trying to initialize multiple ' + + 'components of type `' + this.name + + '`. There can only be one component of this type per entity.'); + } + this.el = el; this.id = id; this.attrName = this.name + (id ? '__' + id : ''); diff --git a/tests/core/component.test.js b/tests/core/component.test.js index 35ed2d14090..d61ff286d86 100644 --- a/tests/core/component.test.js +++ b/tests/core/component.test.js @@ -642,6 +642,65 @@ suite('Component', function () { }); }); + suite('sceneOnly components', function () { + var el; + var TestComponent; + setup(function () { + el = entityFactory(); + delete components.test; + TestComponent = registerComponent('test', { sceneOnly: true }); + }); + + test('allows instantiating sceneOnly component on scene element', function () { + el.sceneEl.setAttribute('test', ''); + assert.ok(el.sceneEl.components['test']); + }); + + test('throws error when instantiating sceneOnly component on entities', function () { + try { + el.setAttribute('test', ''); + assert.fail(); + } catch (e) { + assert.equal(e.message, 'Component `test` can only be applied to '); + } + assert.notOk(el.components['test']); + }); + }); + + suite('multiple components', function () { + var el; + setup(function () { + el = entityFactory(); + delete components.test; + }); + + test('allows multiple instances on element with ids when component has multiple flag', function () { + var TestComponent = registerComponent('test', { multiple: true }); + var first = new TestComponent(el, 'data', 'first'); + var second = new TestComponent(el, 'data', 'second'); + assert.notOk(el.components['test']); + assert.equal(el.components['test__first'], first); + assert.equal(el.components['test__second'], second); + }); + + test('allows instance without id even when component has multiple flag', function () { + var TestComponent = registerComponent('test', { multiple: true }); + var component = new TestComponent(el, 'data', ''); + assert.equal(el.components['test'], component); + }); + + test('throws error when instantiating with id when component does not have multiple flag', function () { + var TestComponent = registerComponent('test', { multiple: false }); + try { + var component = new TestComponent(el, 'data', 'some-id'); + assert.fail(); + } catch (e) { + assert.equal(e.message, 'Trying to initialize multiple components of type `test`. ' + + 'There can only be one component of this type per entity.'); + } + }); + }); + suite('third-party components', function () { var el; setup(function (done) {