Skip to content

Adding onSnapshotsInSync (not public) #2100

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

Merged
merged 12 commits into from
Sep 9, 2019
Merged

Conversation

thebrianchen
Copy link

First pass at plumbing through onSnapshotsInSync.

  • I wasn't sure how to add comments to the changed onViewSnapshots and applyOnlineStateChanges mainly because I'm not sure how they do. I'd be happy to add comments to the individual methods in EventManager since it's pretty hard to follow along with just the code.
  • Please fill me in on any other test cases I should also include.
  • Inside EventManager, I'm only calling the listener once per call to applyOnlineStateChanges and onViewSnapshots. Otherwise, the inSync callback would fire for each query listener.

Copy link
Contributor

@mikelehen mikelehen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core of this looks good to me, but I have a few small suggestions, and I think Gil is right that we can implement tests for this as spec tests. I expect this will be a bit of a learning adventure for you and take some time, but I left you some pointers to hopefully help. But feel free to holler as you dig in and have questions.

@mikelehen mikelehen assigned thebrianchen and unassigned mikelehen Aug 21, 2019
Copy link
Contributor

@mikelehen mikelehen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Generally this looks quite good. I think there's some question as to the best way to represent these expectations in the spec tests. I think we have a bit of debt with regard to how we differentiate (or not) state expectations vs event-based expectations. Not sure we need to clean that up in this PR though.

});
}

it('fires after local listeners fire', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is testing anything not covered by the spec tests?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec tests can't check that the onSnapshotsInSync listener fires after the other listeners are added. Not sure if it's vital that we keep this one though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's vital. And I think this test may actually be racey on other platforms.

Because JS is single-threaded, you're guaranteed to add the snapshots-in-sync listener before the normal snapshot listeners fire (because they have to wait for data from the server). But on Android / iOS, it's conceivable that we could add one of the snapshot listeners, get data back from the server, and raise the snapshot event before the snapshots-in-sync listener is added. So you could actually get a different event ordering...

So I think we shouldn't keep this test... but I do think one integration test that goes through the public API would be a good idea. So I'd probably try to create a single very simple smoke test.

});
});

it('fires for duplicate query listeners', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you have this test because spec tests don't let you listen to the same query twice? That's fine I guess, but I think I would try to pare it down as much as possible. Offhand it looks more complicated than I'd expect.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried cutting out some unused variables.

@mikelehen mikelehen assigned thebrianchen and unassigned mikelehen Aug 26, 2019
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some feedback for the parts of the PR I looked at (mostly regarding the changes in spec test runner)

expectation.numSnapshotsInSyncEvents
);
// Reset count after checking so tests don't have to track state.
this.snapshotsInSyncEvents = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think of the stateExpectations as global client state, which accumulate over time and represents the current state of the client at all times. There is already some state in stateExpectations that breaks this assumption (like userCallbacks), so it is probably fine to continue down the path and reset the count here. If you can think of a clever way to merge this with stepExpectations, it might be worth exploring that as an option (or we could have a separate "expected events" section for queries and callbacks).

Totally optional.

I also want to point out that I like that this is not a global counter that tracks every event since the spec test started, so I suggest to keep it that way.

Copy link
Contributor

@mikelehen mikelehen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly LGTM but I have some test feedback and I think the validation error has the wrong method name.

@mikelehen mikelehen assigned thebrianchen and unassigned mikelehen Aug 27, 2019
@thebrianchen thebrianchen requested a review from mikelehen August 27, 2019 21:31
@thebrianchen
Copy link
Author

@mikelehen Is this sufficient integration testing? I'm worried that I might have cut out too much -- specifically, an end-to-end integration test that checks a snapshotsInSync event is raised after a document is set. Or is this properly covered by spec tests already?

Copy link
Contributor

@mikelehen mikelehen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit more feedback on the testing strategy, but this is getting very close I think. 😄

});
}

it('fires after local listeners fire', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's vital. And I think this test may actually be racey on other platforms.

Because JS is single-threaded, you're guaranteed to add the snapshots-in-sync listener before the normal snapshot listeners fire (because they have to wait for data from the server). But on Android / iOS, it's conceivable that we could add one of the snapshot listeners, get data back from the server, and raise the snapshot event before the snapshots-in-sync listener is added. So you could actually get a different event ordering...

So I think we shouldn't keep this test... but I do think one integration test that goes through the public API would be a good idea. So I'd probably try to create a single very simple smoke test.

expectation.numSnapshotsInSyncEvents
);
// Reset count after checking so tests don't have to track state.
this.snapshotsInSyncEvents = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm... This expect validation is a little looser than I would like. The way expectEvents() works, you must call expectEvents() directly after a step that generates events, and if a step generates an event that you didn't explicitly expect, then the test fails.

With expectSnapshotsInSyncEvent(), you have a looser contract. The test runner will basically aggregate all of the events raised since last time you called expectSnapshotsInSyncEvent() and then validate the count if/when you call expectSnapshotsInSyncEvent() again. This is less explicit and makes it unclear exactly which step(s) are generating the expected events. So I think you should change this to something in the spirit of:

      expect(this.snapshotsInSyncEvents).to.eq(
        expectation.numSnapshotsInSyncEvents || 0
      );
      this.snapshotsInSyncEvents = 0;

I think this will result in you having to explicitly declare expected events immediately after the step that generated them, and if you don't, then the test fails... you will probably need to tweak some tests as a result.

@mikelehen mikelehen assigned thebrianchen and unassigned mikelehen Aug 29, 2019
Copy link
Contributor

@mikelehen mikelehen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I think this is much better. A couple last tweaks (sorry) and it'll be good to go.

@mikelehen mikelehen assigned thebrianchen and unassigned mikelehen Aug 30, 2019
Copy link
Contributor

@mikelehen mikelehen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants