You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Client side searching: array.filter( ${string_template}.toUpperCase().indexOf(this.state.searchTerm.toUpperCase()) >= 0 ) => map output what's left
Snapshot Testing w/ Jest
Library from Facebook
Migrating from Jasmine -- Jest2 uses Jasmine2 in the back-end
Jest2 is better than Jest1
snapshot testing...
/* search.spec.js -- jest knows where to find .spec.js */
/* search.js is in the same directory as search.spec.js */
import React from 'react'
import Search from './Search'
import renderer from 'react-test-renderer'
test('Search snapshot test', ()? }
const component = renderer.create(<Search />)
const tree = component.toJSON()
expect(tree).toMatchsnapshot()
})
Configuring and Running Jest
$ jest => Test suite failed, unexpected token import
We need to tell bable that, when in a testing context, please compile my modules (preset in .babelrc)
NODE_ENV=test jest --no-cache
keep snapshots in repo so everyone runs same tests
Shallow rendering with enzyme
If there's a bug in an included module, you don't want to break the test for the module at hand.
Enzyme lets you use a shallow render
Facebook uses enzyme, but it's not officially part of react
import { shallow } from 'enzyme'
import { shallowToJson } from 'enzyne-to-json'
test('Search snapshot test', () => {
const component = shallow(<Search />)
const tree = shallowToJson(component)
expect(tree).toMatchSnapshot()
})
Note you can snapshot test anything that you can dump to a json structure
We should go back and write a test for ShowCard
Testing the number of ShowCards
import preload from '../public/data.json'
test('Search should render a ShowCard for each show', () => {
const component = shallow(<Search />)
expect(component.find(ShowCard).length).toEqual(preload.shows.length)
})
Testing the Search Field
test('Search should render correct amount of shows based on search', () => {
const searchWord = 'house'
const component = shallow(<Search />)
component.find('input').simulate('change', {target: {value:searchWord}})
const showCount = preload.shows.filter((show) => `${show.title} ${show.description}`.toUpperCase().indexOf(this.state.searchTerm.toUpperCase()) >= 0).length
expect(component.find(ShowCard).length).toEqual(showCount)
})
Test coverage with Istanbul
npm run test -- --coverage
Already built into Jest
open coverage/lcov-report/index.html
URL Parameters
Day 2! Now we get to have more fun than just tooling
Pushing the sharded data upto a parent container to avoid querying it twice
/* Details.js */
import React from 'react'
const Details = () => () => {
return ( <h1></h1> ) // a stateless functional component -- basically, just a render method
}
//=========================================
/* ClientApp.js */
// NOTE: Now we need to pass parameters to search...
import React from 'react'
import { render } from 'react-dom'
import { Browserrouter, Match } from 'react-router'
import Landing from './Landing'
import Search from './Search'
import Details from './Details
import preload from '../public/data.json'
import '../public/normalize.css'
import '../public/style.css'
const App = React.createClass({
render ()
return (
<BrowserRouter>
<div className='app'>
<Match exactly pattern='/' component={Landing} />
<Match
pattern='/search'
component={(props) => <Search shows={preload.shows} {...props} />} /* <-- this here */
/>
<Match pattern='/details:id' component={Details} />
</div>
</BrowserRouter>
)
}
})
render(<App />, document.getElementById('app')}
Updating the Search Component
We're really taking advantage of "black magic" shortcuts
Anywhere you're using JSX you have to also use React -- JSX gets transpiled to React
replace preload.shows with this.props.shows and removed preload from imports in Search.js
React Router is passing props into our componenent
<Match
pattern='/search'
component={(props) => <Search shows={preload.shows} {...props} />} /* <-- this here */
/>
Note the function in component={(props) => <Search shows={preload.shows} {...props} />}
Here, we're getting props from BrowserRouter and using spreading {...props} to maintain them as props on the compoment
This lets us keep things like the id from the route (i.e. on Details page) along with the new shows prop w/ preload
Now we get "shows" passed into Search.js as a prop, so that's why we replace preload.shows' with 'this.props.shows' and removed preloadfromimports` in Search.js
Nothing changes here on the front-end, but shows are now coming in as a parameter from the router
We should add propTypes to our Search..
const { arrayOf, shape, string } = React.PropTypes
const Search = React.createClass({
propTypes: {
shows: arrayOf(shape({ /* Be descriptive because we know what the objects are and they're all this format */
title: string,
description: string
}))
},
getInitialState() {
...