import { assign } from '@ember/polyfills';
import { moduleFor, AutobootApplicationTestCase } from 'internal-test-helpers';
import ApplicationInstance from '@ember/application/instance';
import Application from '@ember/application';
moduleFor(
'Application instance initializers',
class extends AutobootApplicationTestCase {
get fixture() {
return `
ONE
TWO
`;
}
get applicationOptions() {
return assign(super.applicationOptions, {
rootElement: '#one',
});
}
createSecondApplication(options, MyApplication = Application) {
let myOptions = assign(
this.applicationOptions,
{
rootElement: '#two',
},
options
);
let secondApp = (this.secondApp = MyApplication.create(myOptions));
return secondApp;
}
teardown() {
super.teardown();
if (this.secondApp) {
this.runTask(() => this.secondApp.destroy());
}
}
[`@test initializers require proper 'name' and 'initialize' properties`]() {
let MyApplication = Application.extend();
expectAssertion(() => {
MyApplication.instanceInitializer({ name: 'initializer' });
});
expectAssertion(() => {
MyApplication.instanceInitializer({ initialize() {} });
});
this.runTask(() => this.createApplication({}, MyApplication));
}
[`@test initializers are passed an app instance`](assert) {
let MyApplication = Application.extend();
MyApplication.instanceInitializer({
name: 'initializer',
initialize(instance) {
assert.ok(
instance instanceof ApplicationInstance,
'initialize is passed an application instance'
);
},
});
this.runTask(() => this.createApplication({}, MyApplication));
}
[`@test initializers can be registered in a specified order`](assert) {
let order = [];
let MyApplication = Application.extend();
MyApplication.instanceInitializer({
name: 'fourth',
after: 'third',
initialize() {
order.push('fourth');
},
});
MyApplication.instanceInitializer({
name: 'second',
after: 'first',
before: 'third',
initialize() {
order.push('second');
},
});
MyApplication.instanceInitializer({
name: 'fifth',
after: 'fourth',
before: 'sixth',
initialize() {
order.push('fifth');
},
});
MyApplication.instanceInitializer({
name: 'first',
before: 'second',
initialize() {
order.push('first');
},
});
MyApplication.instanceInitializer({
name: 'third',
initialize() {
order.push('third');
},
});
MyApplication.instanceInitializer({
name: 'sixth',
initialize() {
order.push('sixth');
},
});
this.runTask(() => this.createApplication({}, MyApplication));
assert.deepEqual(order, ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']);
}
[`@test initializers can be registered in a specified order as an array`](assert) {
let order = [];
let MyApplication = Application.extend();
MyApplication.instanceInitializer({
name: 'third',
initialize() {
order.push('third');
},
});
MyApplication.instanceInitializer({
name: 'second',
after: 'first',
before: ['third', 'fourth'],
initialize() {
order.push('second');
},
});
MyApplication.instanceInitializer({
name: 'fourth',
after: ['second', 'third'],
initialize() {
order.push('fourth');
},
});
MyApplication.instanceInitializer({
name: 'fifth',
after: 'fourth',
before: 'sixth',
initialize() {
order.push('fifth');
},
});
MyApplication.instanceInitializer({
name: 'first',
before: ['second'],
initialize() {
order.push('first');
},
});
MyApplication.instanceInitializer({
name: 'sixth',
initialize() {
order.push('sixth');
},
});
this.runTask(() => this.createApplication({}, MyApplication));
assert.deepEqual(order, ['first', 'second', 'third', 'fourth', 'fifth', 'sixth']);
}
[`@test initializers can have multiple dependencies`](assert) {
let order = [];
let MyApplication = Application.extend();
let a = {
name: 'a',
before: 'b',
initialize() {
order.push('a');
},
};
let b = {
name: 'b',
initialize() {
order.push('b');
},
};
let c = {
name: 'c',
after: 'b',
initialize() {
order.push('c');
},
};
let afterB = {
name: 'after b',
after: 'b',
initialize() {
order.push('after b');
},
};
let afterC = {
name: 'after c',
after: 'c',
initialize() {
order.push('after c');
},
};
MyApplication.instanceInitializer(b);
MyApplication.instanceInitializer(a);
MyApplication.instanceInitializer(afterC);
MyApplication.instanceInitializer(afterB);
MyApplication.instanceInitializer(c);
this.runTask(() => this.createApplication({}, MyApplication));
assert.ok(order.indexOf(a.name) < order.indexOf(b.name), 'a < b');
assert.ok(order.indexOf(b.name) < order.indexOf(c.name), 'b < c');
assert.ok(order.indexOf(b.name) < order.indexOf(afterB.name), 'b < afterB');
assert.ok(order.indexOf(c.name) < order.indexOf(afterC.name), 'c < afterC');
}
[`@test initializers set on Application subclasses should not be shared between apps`](assert) {
let firstInitializerRunCount = 0;
let secondInitializerRunCount = 0;
let FirstApp = Application.extend();
FirstApp.instanceInitializer({
name: 'first',
initialize() {
firstInitializerRunCount++;
},
});
let SecondApp = Application.extend();
SecondApp.instanceInitializer({
name: 'second',
initialize() {
secondInitializerRunCount++;
},
});
this.runTask(() => this.createApplication({}, FirstApp));
assert.equal(firstInitializerRunCount, 1, 'first initializer only was run');
assert.equal(secondInitializerRunCount, 0, 'first initializer only was run');
this.runTask(() => this.createSecondApplication({}, SecondApp));
assert.equal(firstInitializerRunCount, 1, 'second initializer only was run');
assert.equal(secondInitializerRunCount, 1, 'second initializer only was run');
}
[`@test initializers are concatenated`](assert) {
let firstInitializerRunCount = 0;
let secondInitializerRunCount = 0;
let FirstApp = Application.extend();
FirstApp.instanceInitializer({
name: 'first',
initialize() {
firstInitializerRunCount++;
},
});
let SecondApp = FirstApp.extend();
SecondApp.instanceInitializer({
name: 'second',
initialize() {
secondInitializerRunCount++;
},
});
this.runTask(() => this.createApplication({}, FirstApp));
assert.equal(
firstInitializerRunCount,
1,
'first initializer only was run when base class created'
);
assert.equal(
secondInitializerRunCount,
0,
'first initializer only was run when base class created'
);
firstInitializerRunCount = 0;
this.runTask(() => this.createSecondApplication({}, SecondApp));
assert.equal(firstInitializerRunCount, 1, 'first initializer was run when subclass created');
assert.equal(
secondInitializerRunCount,
1,
'second initializers was run when subclass created'
);
}
[`@test initializers are per-app`](assert) {
assert.expect(2);
let FirstApp = Application.extend();
FirstApp.instanceInitializer({
name: 'abc',
initialize() {},
});
expectAssertion(function() {
FirstApp.instanceInitializer({
name: 'abc',
initialize() {},
});
});
this.runTask(() => this.createApplication({}, FirstApp));
let SecondApp = Application.extend();
SecondApp.instanceInitializer({
name: 'abc',
initialize() {},
});
this.runTask(() => this.createSecondApplication({}, SecondApp));
assert.ok(true, 'Two apps can have initializers named the same.');
}
[`@test initializers are run before ready hook`](assert) {
assert.expect(2);
let MyApplication = Application.extend({
ready() {
assert.ok(true, 'ready is called');
readyWasCalled = false;
},
});
let readyWasCalled = false;
MyApplication.instanceInitializer({
name: 'initializer',
initialize() {
assert.ok(!readyWasCalled, 'ready is not yet called');
},
});
this.runTask(() => this.createApplication({}, MyApplication));
}
[`@test initializers are executed in their own context`](assert) {
assert.expect(1);
let MyApplication = Application.extend();
MyApplication.instanceInitializer({
name: 'coolInitializer',
myProperty: 'cool',
initialize() {
assert.equal(this.myProperty, 'cool', 'should have access to its own context');
},
});
this.runTask(() => this.createApplication({}, MyApplication));
}
[`@test initializers get an instance on app reset`](assert) {
assert.expect(2);
let MyApplication = Application.extend();
MyApplication.instanceInitializer({
name: 'giveMeAnInstance',
initialize(instance) {
assert.ok(!!instance, 'Initializer got an instance');
},
});
this.runTask(() => this.createApplication({}, MyApplication));
this.runTask(() => this.application.reset());
}
}
);