-
Notifications
You must be signed in to change notification settings - Fork 403
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
TimelineMarkers snapshot test #353
TimelineMarkers snapshot test #353
Conversation
@@ -102,12 +102,12 @@ | |||
"browserify": "^13.0.1", | |||
"chai": "^3.5.0", | |||
"css-loader": "^0.26.0", | |||
"devtools-license-check": "^0.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.
This and other changes are npm install
noise
@@ -25,6 +25,7 @@ export default class TimelineCanvas extends Component { | |||
_requestedAnimationFrame: boolean; | |||
_devicePixelRatio: 1; | |||
_ctx: CanvasRenderingContext2D; | |||
_canvas: ?HTMLCanvasElement; |
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 had to change the ref
implementation to satisfy react-test-renderer
Codecov Report
@@ Coverage Diff @@
## master #353 +/- ##
==========================================
+ Coverage 31.64% 36.02% +4.38%
==========================================
Files 124 123 -1
Lines 5947 5940 -7
Branches 1233 1231 -2
==========================================
+ Hits 1882 2140 +258
+ Misses 3484 3252 -232
+ Partials 581 548 -33
Continue to review full report at Codecov.
|
@@ -17,7 +17,9 @@ import type { | |||
import type { UpdateProfileSelection } from '../actions/profile-view'; | |||
import type { ProfileSelection } from '../actions/types'; | |||
|
|||
const { DOM_DELTA_PAGE, DOM_DELTA_LINE } = new WheelEvent('mouse'); | |||
const { DOM_DELTA_PAGE, DOM_DELTA_LINE } = (typeof window === 'object' && window.WheelEvent) |
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.
Hmm... this was the easiest way to handle this for the test to run, otherwise I'll need to put this information into the component.
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.
or you can add the WheelEvent component in window
? (or file a bug at https://github.com/tmpvar/jsdom ? or even better, do a PR there ;) )
Please at least file a bug there
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 problem is that this runs anytime the document is imported, often before I get a chance to be able to inject something into the window, and I have to catch it for every single test that happens to touch this file.
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.
oh I see ! so we can't add it ourselves but still jsdom should have it :)
window.devicePixelRatio = 1; | ||
const ctx = mockCanvasContext(); | ||
|
||
/** |
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.
createNodeMock
is definitely the most brittle part of the test. Not super happy about mocking things out like this, but it lets us use ref
s.
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 we can do better by mocking (with sinon or jest) stuff in HTMLCanvasElement. But that will do for 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.
ah, I see, it's because of facebook/react#7740 :/
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.
Yes, that's the reasoning for switching it up.
@mstange This is starting to block other component testing, do you think you could take a look at it? |
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
ref='canvas' | ||
ref={canvas => { | ||
this._canvas = canvas; | ||
}} |
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.
Do you know if the fact that you're passing a lambda here is going to cause unnecessary re-renders? In other places we've used this._takeCanvasRef
to store the function.
Though it's just really one element, so it probably won't matter.
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.
what's the advantage of using this instead of this.refs.canvas
?
Ok I read the string refs are now deprecated.
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 going to fix that before merging. We've been bitten too much in the past with similar types of issues.
}); | ||
|
||
afterEach(() => { | ||
delete global.Image; | ||
delete window.Image; |
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.
this will likely bite us later -- but please proceed, I'll have a look later.
expect(drawCalls).toMatchSnapshot(); | ||
|
||
delete window.requestAnimationFrame; | ||
delete window.devicePixelRatio; |
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.
pretty sure this will bite us later :/ I'll have a look at how to make this better
import { storeWithProfile } from '../fixtures/stores'; | ||
import { getProfileWithMarkers } from '../store/fixtures/profiles'; | ||
|
||
jest.useFakeTimers(); |
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 don't really like that we call that here at the top level, I'd rather call it in beforeEach
so that we can call useRealTimers
in an afterEach
.
That said I don't really understand why we use fake timers -- don't you need real timers to mock requestAnimationFrame
?
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 timers are only fake for the scope of that file, and don't affect other ones. I think I'd prefer not to clutter up the test with extra beforeEach and afterEach declarations.
he requestAnimationFrame mock uses the setTimeout
which is faked by jest. I added a few comments in the file explaining the timers and how they are running requestAnimationFrames to clarify.
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 timers are only fake for the scope of that file,
Oh OK. Jest is different to mocha in this regard. Good!
about my comment about the fake timers, I missed the call to jest.runAllTimers();
, so all is good :)
ref='container'> | ||
ref={container => { | ||
this._container = container; | ||
}}> |
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 don't you like using because this is deprecatedthis.refs
?
51d0674
to
73d9b9b
Compare
934169b
to
e58b49f
Compare
This is my first attempt at a snapshot test for a component. My thoughts here are that snapshots should be a good first line of defense for catching component regressions. Snapshot tests would only be sanity checks for when things change. They should be fairly lightweight in the implementation, and easy to regenerate. As the components change over time you can see that the snapshots fail, inspect the output, re-generate the snapshot, and then move on with your life. I think these are good candidates for higher level connected components that have some complexity. This tests the integration of several components.
For more a unit-test level of individual components, I think enzyme would be a better fit. You can command the component at a more granular level, and check individual properties. I think the moment that we start trying to do things with the test, we should consider switching over to an enzyme test and be more strict with testing the desired output.
I would say at this point, let's create some enzyme tests of some components, and compare how this looks to a snapshot test. I think a good approach would be to go ahead and merge in these experiments, but with the option to strip them out, or refactor them.