-
Notifications
You must be signed in to change notification settings - Fork 31
#3 Implement additional LDClient tests. #36
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
Conversation
…implement-ldclient-tests
…update processors.
…r levels, but we need to check the event emitter.
|
This pull request has been linked to Shortcut Story #162616: Implement LDClient unit tests.. |
| "ts-jest": "^27.1.4", | ||
| "typescript": "^4.6.3" | ||
| "typescript": "^4.6.3", | ||
| "launchdarkly-js-test-helpers": "^2.2.0" |
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.
The node level tests can benefit from this helper. For now I have excluded it from common, and server-common, because those tests should execute outside node without many polyfills or dependencies if we need them to. We may be able to more widely use them later.
| @@ -0,0 +1,151 @@ | |||
| import { integrations, interfaces, LDBigSegmentsOptions, LDLogger } from '@launchdarkly/js-server-sdk-common'; | |||
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.
There are some node level big segments test for the event emitter implementation. The main testing is done in the common sdk.
| @@ -0,0 +1,164 @@ | |||
| import { integrations } from '@launchdarkly/js-server-sdk-common'; | |||
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.
Most of the file data source testing is at the common level, but here we make sure it works with the actual node filesystem APIs.
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.
If it's just the I/O implementation that's distinctive here, I feel like you might be able to make the tests a bit simpler by omitting things like the segment. I mean, the fact that there's a flag referencing a segment is a detail of the data that's in the file, which should be orthogonal to how we read the file or detected changes to the file.
| @@ -0,0 +1,93 @@ | |||
| import { integrations } from '@launchdarkly/js-server-sdk-common'; | |||
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.
Primarily for the event emitter connection.
| @@ -1,5 +1,5 @@ | |||
| import * as os from 'os'; | |||
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.
Moved to follow directory structure.
| @@ -1,6 +1,6 @@ | |||
| import * as http from 'http'; | |||
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.
Moved to follow directory structure.
eli-darkly
left a comment
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.
Looks good - I left a couple of comments about optional changes to consider.
| @@ -0,0 +1,164 @@ | |||
| import { integrations } from '@launchdarkly/js-server-sdk-common'; | |||
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.
If it's just the I/O implementation that's distinctive here, I feel like you might be able to make the tests a bit simpler by omitting things like the segment. I mean, the fact that there's a flag referencing a segment is a detail of the data that's in the file, which should be orthogonal to how we read the file or detected changes to the file.
| () => { }, | ||
| () => { }, | ||
| // Always listen to events. | ||
| () => true, |
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.
Something that's occurred to me during this reviews in general is that the large number of LDClientImpl constructor parameters makes it a bit hard to see which one is which. Might you consider creating a type whose only purpose is to make some of these into named properties? Like, the first three parameters are mandatory and generally self-explanatory at the call site, but these other callbacks not so much. If the usage were something like this—
new LDClientImpl(
sdkKey,
platform,
config,
{
hasEventListeners: () => true
});—it'd be easier to see what's happening, and possibly harder to make a mistake by putting parameters in the wrong order. In this example I've assumed that there is some default behavior for the unspecified ones, which might not make sense in a non-test context since (I think) all of the SDK implementations are likely to need to provide all of those callbacks, but even if they're all mandatory & therefore can't make the test code less verbose, I feel like there might be some benefit.
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.
I've implemented this change.
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 does remove some verbosity in tests, because I added a makeCallbacks(withEvents:boolean) helper that most tests can use.
| targets: [], | ||
| rules: [ | ||
| { | ||
| clauses: [{ attribute: 'key', op: 'in', values: [defaultUser.key] }], |
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 a thought for future test writing: something I've done in other SDKs, and wish I had gotten around to in Node, is to rely more heavily on helper functions for generating boilerplate pieces of flag configuration like this. For instance, if the idea is to make a clause that will definitely match this user, I would change this to something like clauses: [clauseThatMatchesUser(defaultUser)] and define clauseThatMatchesUser to be equivalent to this. Even though this kind of logic isn't rocket science and isn't incredibly verbose, I find that it's easier for me to understand and validate the test logic at a glance when there are fewer extraneous details and I can see the intention immediately from the names of things, rather than having to infer it from my knowledge of how such a clause would be evaluated.
This PR adds top level tests for the
LDClientImplas well asLDClientNode.Some tests have a certain amount of duplication between the two to ensure that the platform level tests are covered.
The tests are largely ports of the tests from the node SDK.