-
Notifications
You must be signed in to change notification settings - Fork 940
Allow for lazy registration of app components #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
718c99c
1413770
f26cfc5
3a38558
47d618a
9baf65f
99820ef
3e211b3
c75fb59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
var assert = require('chai').assert; | ||
// Partial inclusion is a browser-only feature | ||
var firebase = require('../../../dist/package/app'); | ||
var helper = require('./test-helper.js'); | ||
|
||
describe("Lazy Firebase App (" + helper.getPackagerName() + ")", function() { | ||
it("firebase namespace", function() { | ||
assert.isDefined(firebase); | ||
}); | ||
|
||
it("SDK_VERSION", function() { | ||
assert.isDefined(firebase.SDK_VERSION); | ||
}); | ||
|
||
it('Should allow for lazy component init', function() { | ||
assert.isUndefined(firebase.database); | ||
firebase.initializeApp({}); | ||
require('../../../dist/package/database'); | ||
assert.isDefined(firebase.database); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,6 +166,121 @@ describe("Firebase App Class", () => { | |
assert.equal(registrations, 2); | ||
}); | ||
|
||
it("Can lazy load a service", () => { | ||
let registrations = 0; | ||
|
||
const app1 = firebase.initializeApp({}); | ||
assert.isUndefined((app1 as any).lazyService); | ||
|
||
firebase.INTERNAL.registerService('lazyService', (app: FirebaseApp) => { | ||
registrations += 1; | ||
return new TestService(app); | ||
}); | ||
|
||
assert.isDefined((app1 as any).lazyService); | ||
|
||
// Initial service registration happens on first invocation | ||
assert.equal(registrations, 0); | ||
|
||
// Verify service has been registered | ||
(firebase as any).lazyService(); | ||
assert.equal(registrations, 1); | ||
|
||
// Service should only be created once | ||
(firebase as any).lazyService(); | ||
assert.equal(registrations, 1); | ||
|
||
// Service should only be created once... regardless of how you invoke the function | ||
(firebase as any).lazyService(app1); | ||
assert.equal(registrations, 1); | ||
|
||
// Service should already be defined for the second app | ||
const app2 = firebase.initializeApp({}, 'second'); | ||
assert.isDefined((app1 as any).lazyService); | ||
|
||
// Service still should not have registered for the second app | ||
assert.equal(registrations, 1); | ||
|
||
// Service should initialize once called | ||
(app2 as any).lazyService(); | ||
assert.equal(registrations, 2); | ||
}); | ||
|
||
it("Can lazy register App Hook", (done) => { | ||
let events = ['create', 'delete']; | ||
let hookEvents = 0; | ||
const app = firebase.initializeApp({}); | ||
firebase.INTERNAL.registerService( | ||
'lazyServiceWithHook', | ||
(app: FirebaseApp) => { | ||
return new TestService(app); | ||
}, | ||
undefined, | ||
(event: string, app: FirebaseApp) => { | ||
assert.equal(event, events[hookEvents]); | ||
hookEvents += 1; | ||
if (hookEvents === events.length) { | ||
done(); | ||
} | ||
}); | ||
// Ensure the hook is called synchronously | ||
assert.equal(hookEvents, 1); | ||
app.delete(); | ||
}); | ||
|
||
it('Can register multiple instances of some services', () => { | ||
// Register Multi Instance Service | ||
firebase.INTERNAL.registerService( | ||
'multiInstance', | ||
(...args) => { | ||
const [app,,instanceIdentifier] = args; | ||
return new TestService(app, instanceIdentifier); | ||
}, | ||
null, | ||
null, | ||
true | ||
); | ||
firebase.initializeApp({}); | ||
|
||
// Capture a given service ref | ||
const service = (firebase.app() as any).multiInstance(); | ||
assert.strictEqual(service, (firebase.app() as any).multiInstance()); | ||
|
||
// Capture a custom instance service ref | ||
const serviceIdentifier = 'custom instance identifier'; | ||
const service2 = (firebase.app() as any).multiInstance(serviceIdentifier); | ||
assert.strictEqual(service2, (firebase.app() as any).multiInstance(serviceIdentifier)); | ||
|
||
// Ensure that the two services **are not equal** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't check that the two difference services are getting their identifier passed to the underlying service constructor. function factory(app: FirebaseApp, unused: any, opt_url?: string): Service {
return new Service(app, new XhrIoPool(), opt_url);
}
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha, thanks! |
||
assert.notStrictEqual(service.instanceIdentifier, service2.instanceIdentifier, '`instanceIdentifier` is not being set correctly'); | ||
assert.notStrictEqual(service, service2); | ||
assert.notStrictEqual((firebase.app() as any).multiInstance(), (firebase.app() as any).multiInstance(serviceIdentifier)); | ||
}); | ||
|
||
it(`Should return the same instance of a service if a service doesn't support multi instance`, () => { | ||
// Register Multi Instance Service | ||
firebase.INTERNAL.registerService( | ||
'singleInstance', | ||
(...args) => { | ||
const [app,,instanceIdentifier] = args; | ||
return new TestService(app, instanceIdentifier) | ||
}, | ||
null, | ||
null, | ||
false // <-- multi instance flag | ||
); | ||
firebase.initializeApp({}); | ||
|
||
// Capture a given service ref | ||
const serviceIdentifier = 'custom instance identifier'; | ||
const service = (firebase.app() as any).singleInstance(); | ||
const service2 = (firebase.app() as any).singleInstance(serviceIdentifier); | ||
|
||
// Ensure that the two services **are equal** | ||
assert.strictEqual(service.instanceIdentifier, service2.instanceIdentifier, '`instanceIdentifier` is not being set correctly'); | ||
assert.strictEqual(service, service2); | ||
}); | ||
|
||
describe("Check for bad app names", () => { | ||
let tests = ["", 123, false, null]; | ||
for (let data of tests) { | ||
|
@@ -179,9 +294,7 @@ describe("Firebase App Class", () => { | |
}); | ||
|
||
class TestService implements FirebaseService { | ||
constructor(private app_: FirebaseApp) { | ||
// empty | ||
} | ||
constructor(private app_: FirebaseApp, public instanceIdentifier?: string) {} | ||
|
||
// TODO(koss): Shouldn't this just be an added method on | ||
// the service instance? | ||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's late, maybe I'm misreading:
So this will patch in the service factory:
app.storage(instanceString);
Will this pass instanceString to
createService(app, extendApp, instanceString)
?This statement, as quoted from above, doesn't pass the instance string.
If you update the test below where I commented to confirm this, then you are good to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch on this. I have refactored to ensure that we are passing through the
instanceIdentifier
I must have missed it in adding code back.In addition I have added an additional assertion to two of the tests below to ensure that we don't break this going forward.