-
Notifications
You must be signed in to change notification settings - Fork 193
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
chore(databases-collection): refactor create db / create coll to a single create namespace plugin COMPASS-7410 #5100
Conversation
…ngle create namespace plugin
@@ -3,7 +3,7 @@ import { createContext, useContext } from 'react'; | |||
|
|||
export const InstanceContext = createContext<MongoDBInstance | null>(null); | |||
|
|||
export const useMongoDBInstance = (): MongoDBInstance => { | |||
export const mongoDBInstanceLocator = (): MongoDBInstance => { |
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.
@addaleax don't know if you have a strong preference here, I thought that I'd rename it to match other methods we have and to indicate a bit better that it's not supposed to be used as a hook in React (even though it sorta is).
I think if we want to add actual hooks here (should be very valuable in some cases!), those should probably be a bit more high level, encapsulating the model subscription logic for a required field internally instead of just exposing the modal to the React view 🤔
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.
sure, no strong preferences here! happy to stick to whatever pattern we choose 🙂
packages/instance-model/index.d.ts
Outdated
@@ -100,6 +100,7 @@ declare class MongoDBInstance extends MongoDBInstanceProps { | |||
}): Promise<Collection | null>; | |||
removeAllListeners(): void; | |||
on(evt: string, fn: (...args: any) => void); | |||
off(evt: string, fn: (...args: any) => void); |
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.
lol 😄 https://github.com/mongodb-js/compass/pull/5102/files#diff-a79e9b0455facd1015dd43ba2327be7c140c049fcbb16ef624e15a67dfc38cbaR103 no strong feelings either way will align that with this PR ;)
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.
ah actually, now I remember why I did this; AppRegistry
has removeListener
but not off
. Should we also add off
to AppRegistry
then?
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.
We can do that for consistency, yes, especially now that we use it so much! With ampersand models you have off, but not removeListener, so this is why I added it here and it'd be harder for us to extend ampersand models to support removeListener compared to doing this for app registry 🙂
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.
Ahh, wait, I think I'm just silly, I'm sure I got "can't call undefined error" when trying removeListener, but it's definitely there. Will update!
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.
Renamed to align with your PR in 6691588
…ice mock helper; add new plugin tests
Added tests, should be ready for review now |
/** | ||
* Convenience method for testing: allows to override services and app | ||
* registries available in the plugin context | ||
* | ||
* @example | ||
* const PluginWithLogger = registerHadronPlugin({ ... }, { logger: loggerLocator }); | ||
* | ||
* const MockPlugin = PluginWithLogger.withMockServices({ logger: Sinon.stub() }); | ||
* | ||
* @param mocks Overrides for the services locator values and registries | ||
* passed to the plugin in runtime. When `globalAppRegistry` | ||
* override is passed, it will be also used for the | ||
* localAppRegistry override unless `localAppRegistry` is also | ||
* explicitly passed as a mock service. | ||
*/ | ||
withMockServices( | ||
mocks: Partial<Registries & Services<S>> | ||
): React.FunctionComponent<T>; |
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.
@addaleax this is this new testing helper I mentioned, I also switched drop-namespace tests to use it too (although due to how this particular plugin works, it doesn't make that much of a difference in that case)
return [s, mockServices[s] ? () => mockServices[s] : services?.[s]]; | ||
}) | ||
) as unknown as S; | ||
const MockPlugin = registerHadronPlugin(config, mockServiceLocators); |
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.
Won’t it be an issue that this re-uses the same registryName
as the original plugin and therefore shares a store (which may have already been initialized with the original services)?
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.
Hmmm, I think for that to conflict you'd need to actually render / activate both mocked and unmocked plugin in the same test, which sounds like a rare corner case, unless I'm missing some scenario here 🤔 Doesn't hurt to override config name here though, generally not that we should rely on it in any way externally, can do that!
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.
Just needs to happen in the same process as long as the global app registry is truly global, right? That doesn’t seem all that unlikely, and it’s going to be hard to diagnose because it could involve some “spooky action at a distance” from a completely unrelated test that also happens to render the plugin.
Another approach, maybe even a better one, would be figuring out how to best avoid having a truly global globalAppRegistry in tests at all. Ideally, tests should probably use a distinct one each time, not share the same on across all tests in that process…?
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.
Ah, I see what you mean. Then I think we can change the code there that passes globalAppRegistry
value to the context to be _globalAppRegistry ?? new AppRegistry()
: if you don't care about the reigstry or don't need to interact with it inside the actual test, this would be just a safe fallback, but if you want to emit events or something, then you'd want to pass your instance there. How does that sound?
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.
Yeah, I think that makes for some nice isolation between tests, and it should be easy enough to work around if it we do want the actual global instance?
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.
Totally, and it would be super explicit if you want to pass the global one, it's a singleton export from the app-registry package. Will update, thanks for the feedback!
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.
Updated globalAppRegistry
to be always scoped as discussed in 72c9c15. Also when doing that stumbled on something that I think is a bug: we did call plugin.deactivate
in appRegistry.deactivate
, but didn't de-register plugins, changed that too to always clean-up plugins from registry as at the moment we call deactivate there, we expect this whole thing to be disposeable basically
Last follow-up to #5085