-
Notifications
You must be signed in to change notification settings - Fork 585
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
Add tests for QBS GeoSpatial #6223
Conversation
* Expanded previous tests with a `useFlexibleSync` flag * Added special logic to initialize app, auth and sync data * Updated all utility test methods to be async and peform sub/unsub for qbs * Disabled duplicate tests
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 is good to see that our geospatial queries now can be used with flexible sync.
expectedLength, | ||
`Expected length ${expectedLength} for query: ${queryString} ${JSON.stringify(queryArgs)}`, | ||
); | ||
if (useFlexibleSync) { |
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.
Could it make sense to turn it into a small function? I mean, it is repeated many places.
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 do like to repeat myself in tests, but I can see that this is replicated maybe a bit too much.
if (useFlexibleSync) { | ||
await filtered.subscribe({ behavior: WaitForSync.Always }); | ||
} |
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'm thinking it may be best to add a unique name
as part of the subscription options as well, so that the removal of the subscription specifically targets this subscription. In this case, my comment would also apply to the functions expectQueryResultValues()
and expectQueryResultValuesByName()
.
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.
But with this "new" subscription mechanism it relieves the need for this. I think for testing it's okay to just unsubscribe from the original model, no?
I do agree that in actual application code, one should be using names to track their subscriptions.
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 think the reason in this case to also use a name
would be if the same realm is used at the same the by some other test and that test relies on a subscription with the same query. Then that subscription would be removed. But I'm definitely unsure if this scenario (same realm, parallel test, same query) is possible or likely in our tests.
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 cross that bridge when we come to it. I think we will start having many problems in many areas if we start adding parallelizations to our test framework (which then would need this type of optimization, including realm file paths, etc).
if (useFlexibleSync) { | ||
await filtered.subscribe({ behavior: WaitForSync.Always }); | ||
} | ||
expect(filtered.length).equal( |
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.
Usage of expect().equal()
and expect().to.equal()
are being mixed in the test. Could we pick just one of them? 🙂
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 didn't write this, but if I did, I would have chosen expect().to.equal()
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.
Ditto to.equal()
useFlexibleSync && authenticateUserBefore(); | ||
const realmConfig = (useFlexibleSync | ||
? { schema: [PointOfInterest, MyGeoPoint.schema], sync: { flexible: true } } | ||
: { schema: [PointOfInterest, MyGeoPoint.schema] }) as unknown as OpenRealmConfiguration; |
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.
Why was the as unknown as..
needed here? Even though the sync
is not taking a user
here, it looks like the type system should not have an issue with that since OpenRealmConfiguration
allows Partial<SyncConfiguration>
. So maybe that's not the issue here?
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 was getting type errors and this was my quick and dirty solution without digging into why this Partial wasn't taken by our internal hooks. However, I could take some extra time to make this clearer.
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.
Alrighty, yeah probably don't have to spend too much time on it tho 👍
center: { latitude: -25, longitude: -32.34 }, | ||
distance: 0.5, | ||
}; | ||
async function geoTest( |
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 like async
shouldn't be needed here. The Promise
return type is inferred in this function.
async function geoTest( | |
function geoTest( |
if (useFlexibleSync) { | ||
const fullConfig = { | ||
...realmConfig, | ||
sync: { ...realmConfig.sync, user: this.user }, | ||
} as unknown as Realm.ConfigurationWithSync; | ||
await this.realm.syncSession?.uploadAllLocalChanges(); | ||
objects.unsubscribe(); | ||
this.realm.close(); | ||
Realm.deleteFile(fullConfig); | ||
this.realm = await Realm.open(fullConfig); |
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.
Could you add some inline comments to why this beforeEach
needs to unsubscribe, close and delete the realm, and the reopen it, please 🙂
Also, perhaps an expect()
would be good after the last line (after reopening the realm again) to verify the state is what you expect (and helps the reader understand what should be expected). I assume e.g. you'd expect the length of this.realm.objects(PointOfInterest)
to be 0
since there are no subscriptions.
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 could also extract this into a reusable hook. I will add some comments, as this did take a fair amount of trickery to get right.
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 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.
For the tests, perhaps only using flexible sync would be enough? Rather than doing both local and synced tests. Was there a reason for adding rather than replacing?
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 agree. Refactoring now.
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.
Cool, this will definitely simplify things as well 🙂
* Flexible sync only for geospatial * Convenience function for tear down * Add error case for altitude * Refactor altitude test to box, since circle is erroneous from baas
654ca31
to
417caec
Compare
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 great 💯
@@ -231,23 +196,25 @@ const expectQueryException = ( | |||
* For example: (r, "Obj", "intCol" [[3, 4], "intCol > 2]) => querying "intCol > 2" should | |||
* return results whose elements' intCol property values are 3 and 4. | |||
*/ | |||
const expectQueryResultValues = ( | |||
const expectQueryResultValues = async ( |
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.
const expectQueryResultValues = async ( | |
const expectQueryResultValues = ( |
expectedResults, | ||
` | ||
return Promise.all( | ||
queryResultPairs.map(async ([expectedResults, queryString, ...queryArgs]) => { |
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.
queryResultPairs.map(async ([expectedResults, queryString, ...queryArgs]) => { | |
queryResultPairs.map(([expectedResults, queryString, ...queryArgs]) => { |
expectedResults, | ||
` | ||
return Promise.all( | ||
queryResultPairs.map(async ([expectedResults, queryString, ...queryArgs]) => { |
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.
queryResultPairs.map(async ([expectedResults, queryString, ...queryArgs]) => { | |
queryResultPairs.map(([expectedResults, queryString, ...queryArgs]) => { |
Co-authored-by: LJ <[email protected]>
What, How & Why?
useFlexibleSync
flagid
to_id
as it is required for QBSforeach
as the callback is completely ignored by mocha when set toasync
Possible Followup
Impossible Box
is possibly able to be reenabled, but must ask core for exceptionaltitude
in local queries throws in QBS. Perhaps they should be unified in their behavior between core and baas.☑️ ToDos
Compatibility
label is updated or copied from previous entryCOMPATIBILITY.md
package.json
s (if updating internal packages)Breaking
label has been applied or is not necessary