jeff1evesque / machine-learning

Web-interface + rest API for classification and regression (https://jeff1evesque.github.io/machine-learning.docs)
Other
256 stars 85 forks source link

Implement reactjs + javascript unit tests #3087

Closed jeff1evesque closed 6 years ago

jeff1evesque commented 6 years ago

We need to write some initial reactjs + javascript unit tests, and integrate it into our travis ci builds.

Note: this issue will leverage the results found from #3084.

betancourtl commented 6 years ago

You might be able to export only your routes as a functional component and then test that par by using the memory router.

jeff1evesque commented 6 years ago

08ab937: tried your suggestion (may need some finesse):

root@browserify:/var/machine-learning/src/jsx# npm run test

> reactjs@1.0.0 test /var/machine-learning/src/jsx
> NODE_ENV=test jest --config jest.config.js

 FAIL  __tests__/layout/page.test.jsx (24.421s)
  PageLayout Component
    ✕ should render home route (62ms)
    ✕ should render login route (29ms)
    ✕ should render logout route (2ms)
    ✕ should render register route (1ms)
    ✕ should render analysis route (6ms)

  ● PageLayout Component › should render home route

    Uncaught [Invariant Violation: Could not find "store" in either the context or props of "Connect(HeaderMenu)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(HeaderMenu)".]

      at reportException (node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
      at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
      at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
      at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
      at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
      at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:138:16)
      at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:187:29)
      at replayUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:11318:7)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:11885:11) thrown

  ● PageLayout Component › should render login route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/login"]}><PageLayout /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      34 |             </MemoryRouter>
      35 |         );
    > 36 |         expect(wrapper.find(LoginLayout)).toHaveLength(1);
      37 |     });
      38 |
      39 |     it('should render logout route', () => {

      at Object.<anonymous> (__tests__/layout/page.test.jsx:36:43)

  ● PageLayout Component › should render logout route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/logout"]}><PageLayout /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      43 |             </MemoryRouter>
      44 |         );
    > 45 |         expect(wrapper.find(LoginLayout)).toHaveLength(1);
      46 |     });
      47 |
      48 |     it('should render register route', () => {

      at Object.<anonymous> (__tests__/layout/page.test.jsx:45:43)

  ● PageLayout Component › should render register route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/register"]}><PageLayout /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      52 |             </MemoryRouter>
      53 |         );
    > 54 |         expect(wrapper.find(RegisterLayout)).toHaveLength(1);
      55 |     });
      56 |
      57 |     it('should render analysis route', () => {

      at Object.<anonymous> (__tests__/layout/page.test.jsx:54:46)

  ● PageLayout Component › should render analysis route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/register"]}><PageLayout /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      61 |             </MemoryRouter>
      62 |         );
    > 63 |         expect(wrapper.find(AnalysisLayoutState)).toHaveLength(1);
      64 |     });
      65 | });
      66 |

      at Object.<anonymous> (__tests__/layout/page.test.jsx:63:51)

 FAIL  __tests__/layout/analysis.test.jsx
  ● Test suite failed to run

    /var/machine-learning/src/jsx/__tests__/layout/analysis.test.jsx: Unexpected token (34:8)
        32 |
        33 |     it('should render correct routes', () => {
      > 34 |         const wrapper = shallow(<AnalysisLayout />);
           |         ^
        35 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
        36 |             const routeProps = route.props();
        37 |             pathMap[routeProps.path] = routeProps.component;

 PASS  __tests__/content/login.test.jsx
  Login Component
    ✓ should render without throwing an error (13ms)
    ✓ should render without throwing an error (8ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (7ms)

 PASS  __tests__/content/register.test.jsx
  Register Component
    ✓ should render without throwing an error (11ms)
    ✓ should render without throwing an error (3ms)
    ✓ should render without throwing an error (6ms)
    ✓ should render without throwing an error (1ms)
    ✓ should render without throwing an error (6ms)

----------------------------------|----------|----------|----------|----------|-------------------|
File                              |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------------------------------|----------|----------|----------|----------|-------------------|
All files                         |     9.05 |     3.21 |     5.73 |     9.03 |                   |
 jsx                              |       75 |      100 |       50 |      100 |                   |
  setup.js                        |       75 |      100 |       50 |      100 |                   |
 jsx/import/animation             |        0 |        0 |        0 |        0 |                   |
  animate.jsx                     |        0 |        0 |        0 |        0 |... 47,148,149,160 |
 jsx/import/content               |    24.83 |    15.12 |       40 |    24.83 |                   |
  home-page.jsx                   |        0 |      100 |        0 |        0 |          27,28,32 |
  login.jsx                       |    27.78 |    16.13 |    55.56 |    27.78 |... 46,156,169,183 |
  register.jsx                    |    23.91 |    14.55 |    33.33 |    23.91 |... 99,209,219,231 |
 jsx/import/formatter             |        0 |      100 |        0 |        0 |                   |
  transpose.js                    |        0 |      100 |        0 |        0 |    47,48,51,52,57 |
 jsx/import/general               |    19.05 |        0 |        0 |    19.51 |                   |
  ajax-caller.js                  |        0 |        0 |        0 |        0 |... 46,49,53,57,63 |
  breakpoints.js                  |      100 |      100 |      100 |      100 |                   |
  colors.js                       |      100 |      100 |      100 |      100 |                   |
  range-slider.jsx                |        0 |        0 |        0 |        0 |... 62,63,64,65,67 |
  spinner.jsx                     |       50 |      100 |        0 |       50 |                14 |
  submit-button.jsx               |        0 |        0 |        0 |        0 |    23,24,25,26,28 |
 jsx/import/input-data            |        0 |        0 |        0 |        0 |                   |
  supply-dataset-file.jsx         |        0 |        0 |        0 |        0 |... 8,90,95,96,113 |
  supply-dataset-url.jsx          |        0 |        0 |        0 |        0 |... 6,88,93,94,112 |
  supply-predictors.jsx           |        0 |        0 |        0 |        0 |... 11,118,119,121 |
 jsx/import/layout                |     12.5 |     10.1 |    21.05 |     12.5 |                   |
  analysis.jsx                    |        0 |        0 |        0 |        0 |... 51,352,353,359 |
  login.jsx                       |       50 |      100 |        0 |       50 |                13 |
  page.jsx                        |       75 |    58.82 |      100 |       75 |          39,55,56 |
  register.jsx                    |       50 |      100 |        0 |       50 |                13 |
 jsx/import/model                 |        0 |        0 |        0 |        0 |                   |
  model-type.jsx                  |        0 |        0 |        0 |        0 |... 27,28,29,31,37 |
 jsx/import/navigation            |     1.82 |        0 |        0 |     1.82 |                   |
  header-menu.jsx                 |        0 |        0 |        0 |        0 |... 35,143,150,151 |
  nav-bar.jsx                     |       50 |      100 |        0 |       50 |                12 |
  user-menu.jsx                   |        0 |        0 |        0 |        0 |... 28,229,231,248 |
 jsx/import/navigation/menu-items |     3.33 |        0 |        0 |     3.33 |                   |
  current-result.jsx              |       50 |      100 |        0 |       50 |                15 |
  home.jsx                        |       50 |      100 |        0 |       50 |                17 |
  login.jsx                       |        0 |        0 |        0 |        0 |... 20,123,132,133 |
  register.jsx                    |        0 |        0 |        0 |        0 |    25,30,40,44,45 |
  results.jsx                     |        0 |        0 |        0 |        0 |... 92,102,106,107 |
 jsx/import/redux/action          |    15.38 |        0 |       20 |    15.38 |                   |
  current-result.jsx              |        0 |      100 |        0 |        0 |                 7 |
  login.jsx                       |        0 |      100 |        0 |        0 |                 7 |
  logout.jsx                      |        0 |      100 |        0 |        0 |                 9 |
  page.jsx                        |       20 |        0 |    28.57 |       20 |... 42,56,57,62,63 |
 jsx/import/redux/container       |       38 |        0 |        0 |       38 |                   |
  analysis-layout.jsx             |    13.64 |        0 |        0 |    13.64 |... 43,46,47,53,70 |
  current-result.jsx              |       30 |        0 |        0 |       30 |... 22,29,30,34,44 |
  data-append.jsx                 |    66.67 |      100 |        0 |    66.67 |                24 |
  data-new.jsx                    |    66.67 |      100 |        0 |    66.67 |                19 |
  header-menu.jsx                 |    66.67 |      100 |        0 |    66.67 |                18 |
  home-page.jsx                   |    66.67 |      100 |        0 |    66.67 |                18 |
  login-link.jsx                  |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
  login.jsx                       |     37.5 |        0 |        0 |     37.5 |    21,22,24,28,37 |
  model-generate.jsx              |    66.67 |      100 |        0 |    66.67 |                24 |
  model-predict.jsx               |    66.67 |      100 |        0 |    66.67 |                25 |
  range-slider.jsx                |    66.67 |      100 |        0 |    66.67 |                18 |
  register-link.jsx               |    33.33 |        0 |        0 |    33.33 |       18,19,21,25 |
  register.jsx                    |     37.5 |        0 |        0 |     37.5 |    20,21,23,27,36 |
  results.jsx                     |    66.67 |      100 |        0 |    66.67 |                18 |
  review-results-link.jsx         |    33.33 |        0 |        0 |    33.33 |       17,22,23,27 |
  user-menu.jsx                   |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
 jsx/import/result                |        0 |        0 |        0 |        0 |                   |
  current-result.jsx              |        0 |        0 |        0 |        0 |... 46,349,404,411 |
  results.jsx                     |        0 |        0 |        0 |        0 |... 15,132,141,146 |
 jsx/import/session-type          |        0 |        0 |        0 |        0 |                   |
  data-append.jsx                 |        0 |        0 |        0 |        0 |... 10,211,213,243 |
  data-new.jsx                    |        0 |        0 |        0 |        0 |... 65,166,172,174 |
  model-generate.jsx              |        0 |        0 |        0 |        0 |... 45,248,252,280 |
  model-predict.jsx               |        0 |        0 |        0 |        0 |... 65,171,173,195 |
 jsx/import/svg                   |        0 |        0 |        0 |        0 |                   |
  svg-books.jsx                   |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
  svg-home.jsx                    |        0 |        0 |        0 |        0 |... 32,36,40,44,48 |
  svg-pencil-note.jsx             |        0 |      100 |        0 |        0 |... 21,22,26,30,34 |
  svg-user.jsx                    |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
 jsx/import/validator             |        0 |        0 |        0 |        0 |                   |
  valid-email.js                  |        0 |      100 |        0 |        0 |            6,7,11 |
  valid-file.js                   |        0 |        0 |        0 |        0 |       6,7,8,10,15 |
  valid-float.js                  |        0 |        0 |        0 |        0 |... 16,17,19,22,27 |
  valid-password.js               |        0 |      100 |        0 |        0 |          10,11,15 |
  valid-string.js                 |        0 |        0 |        0 |        0 |          6,7,9,14 |
  valid-url.js                    |        0 |      100 |        0 |        0 |            6,7,11 |
----------------------------------|----------|----------|----------|----------|-------------------|
Test Suites: 2 failed, 2 passed, 4 total
Tests:       5 failed, 9 passed, 14 total
Snapshots:   0 total
Time:        29.95s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test: `NODE_ENV=test jest --config jest.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the reactjs@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-05-13T01_11_15_348Z-debug.log
betancourtl commented 6 years ago

Looks like PageLayout is connected to redux which makes testing a bit more complex.

betancourtl commented 6 years ago

The reason the test is failing is because it expects the <Provider store={yourStoreObj} /> component to be wrapping the <PageLayout /> component

betancourtl commented 6 years ago

Here is some information on testing connected components. https://redux.js.org/recipes/writing-tests#connected-components

betancourtl commented 6 years ago

You can try testing the unconnected PageLayout component.

import { connect } from 'react-redux'
​
 class PageLayout extends Component { /* ... */ }
​
 // You are testing this
// Connected component 
 export default connect(mapStateToProps)(PageLayout)

 // You could test this
// Unconnected component
// You could try testing this so that you do not depend on redux
// and you might need to mock some functions and props.
export {
  PageLayout,  
}
betancourtl commented 6 years ago

A problem I see with testing <PageLayout /> is that it depends on many props, It also has other components in it which might cause the tests to fail. If you only want to test the routing you could put the routes from <PageLayout /> inside a functional component. You would import the new<Routes/> component into PageLayout.

Then in your test instead of testing PageLayout you could test the <Routes /> component.

This is what your routes component could look like

const Routes = props => {
  return (
    <>
      <Route
        component={HomePageState}
        exact
        path='/'
      />
      <Route
        component={LoginLayout}
        exact
        path='/login'
      />
      <Route
        component={LoginLayout}
        exact
        path='/logout'
      />
      <Route
        component={RegisterLayout}
        exact
        path='/register'
      />
      <Route
        component={AnalysisLayoutState}
        path='/session'
      />
    </>
  );
};
betancourtl commented 6 years ago

BTW im not exactly sure if this would work but thats how I would try testing the routing. This way It rules out other factors like redux, other components, props etc.

jeff1evesque commented 6 years ago

Ah, bummer. Still getting the same errors with the above commits:

root@browserify:/var/machine-learning/src/jsx# npm run test

> reactjs@1.0.0 test /var/machine-learning/src/jsx
> NODE_ENV=test jest --config jest.config.js

 FAIL  __tests__/layout/page.test.jsx (11.161s)
  PageLayout Component
    ✕ should render home route (23ms)
    ✕ should render login route (15ms)
    ✕ should render logout route (2ms)
    ✕ should render register route (1ms)
    ✕ should render analysis route (1ms)

  ● PageLayout Component › should render home route

    Uncaught [Invariant Violation: Could not find "store" in either the context or props of "Connect(HomePage)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(HomePage)".]

      at reportException (node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
      at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
      at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
      at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
      at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
      at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:138:16)
      at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:187:29)
      at replayUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:11318:7)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:11885:11) thrown

  ● PageLayout Component › should render login route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/login"]}><MainRoute /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      34 |             </MemoryRouter>
      35 |         );
    > 36 |         expect(wrapper.find(LoginLayout)).toHaveLength(1);
      37 |     });
      38 |
      39 |     it('should render logout route', () => {

      at Object.<anonymous> (__tests__/layout/page.test.jsx:36:43)

  ● PageLayout Component › should render logout route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/logout"]}><MainRoute /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      43 |             </MemoryRouter>
      44 |         );
    > 45 |         expect(wrapper.find(LoginLayout)).toHaveLength(1);
      46 |     });
      47 |
      48 |     it('should render register route', () => {

      at Object.<anonymous> (__tests__/layout/page.test.jsx:45:43)

  ● PageLayout Component › should render register route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/register"]}><MainRoute /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      52 |             </MemoryRouter>
      53 |         );
    > 54 |         expect(wrapper.find(RegisterLayout)).toHaveLength(1);
      55 |     });
      56 |
      57 |     it('should render analysis route', () => {

      at Object.<anonymous> (__tests__/layout/page.test.jsx:54:46)

  ● PageLayout Component › should render analysis route

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {"length": 0, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): {"length": 1, Symbol(enzyme.__unrendered__): <MemoryRouter initialEntries={["/register"]}><MainRoute /></MemoryRouter>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__node__): null, Symbol(enzyme.__nodes__): [null], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true}}}}
    received.length:
      0

      61 |             </MemoryRouter>
      62 |         );
    > 63 |         expect(wrapper.find(AnalysisLayoutState)).toHaveLength(1);
      64 |     });
      65 | });
      66 |

      at Object.<anonymous> (__tests__/layout/page.test.jsx:63:51)

 FAIL  __tests__/layout/analysis.test.jsx
  ● Test suite failed to run

    /var/machine-learning/src/jsx/__tests__/layout/analysis.test.jsx: Unexpected token (34:8)
        32 |
        33 |     it('should render correct routes', () => {
      > 34 |         const wrapper = shallow(<AnalysisLayout />);
           |         ^
        35 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
        36 |             const routeProps = route.props();
        37 |             pathMap[routeProps.path] = routeProps.component;

 PASS  __tests__/content/login.test.jsx
  Login Component
    ✓ should render without throwing an error (6ms)
    ✓ should render without throwing an error (6ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (1ms)

 PASS  __tests__/content/register.test.jsx
  Register Component
    ✓ should render without throwing an error (3ms)
    ✓ should render without throwing an error (3ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (1ms)
    ✓ should render without throwing an error (1ms)

----------------------------------|----------|----------|----------|----------|-------------------|
File                              |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------------------------------|----------|----------|----------|----------|-------------------|
All files                         |     8.42 |     1.86 |     4.63 |     8.39 |                   |
 jsx                              |       75 |      100 |       50 |      100 |                   |
  setup.js                        |       75 |      100 |       50 |      100 |                   |
 jsx/import/animation             |        0 |        0 |        0 |        0 |                   |
  animate.jsx                     |        0 |        0 |        0 |        0 |... 47,148,149,160 |
 jsx/import/content               |    24.83 |    15.12 |       40 |    24.83 |                   |
  home-page.jsx                   |        0 |      100 |        0 |        0 |          27,28,32 |
  login.jsx                       |    27.78 |    16.13 |    55.56 |    27.78 |... 46,156,169,183 |
  register.jsx                    |    23.91 |    14.55 |    33.33 |    23.91 |... 99,209,219,231 |
 jsx/import/formatter             |        0 |      100 |        0 |        0 |                   |
  transpose.js                    |        0 |      100 |        0 |        0 |    47,48,51,52,57 |
 jsx/import/general               |    19.05 |        0 |        0 |    19.51 |                   |
  ajax-caller.js                  |        0 |        0 |        0 |        0 |... 46,49,53,57,63 |
  breakpoints.js                  |      100 |      100 |      100 |      100 |                   |
  colors.js                       |      100 |      100 |      100 |      100 |                   |
  range-slider.jsx                |        0 |        0 |        0 |        0 |... 62,63,64,65,67 |
  spinner.jsx                     |       50 |      100 |        0 |       50 |                14 |
  submit-button.jsx               |        0 |        0 |        0 |        0 |    23,24,25,26,28 |
 jsx/import/input-data            |        0 |        0 |        0 |        0 |                   |
  supply-dataset-file.jsx         |        0 |        0 |        0 |        0 |... 8,90,95,96,113 |
  supply-dataset-url.jsx          |        0 |        0 |        0 |        0 |... 6,88,93,94,112 |
  supply-predictors.jsx           |        0 |        0 |        0 |        0 |... 11,118,119,121 |
 jsx/import/layout                |     2.63 |        0 |        0 |     2.63 |                   |
  analysis.jsx                    |        0 |        0 |        0 |        0 |... 51,352,353,359 |
  login.jsx                       |       50 |      100 |        0 |       50 |                13 |
  register.jsx                    |       50 |      100 |        0 |       50 |                13 |
 jsx/import/model                 |        0 |        0 |        0 |        0 |                   |
  model-type.jsx                  |        0 |        0 |        0 |        0 |... 27,28,29,31,37 |
 jsx/import/navigation            |     1.82 |        0 |        0 |     1.82 |                   |
  header-menu.jsx                 |        0 |        0 |        0 |        0 |... 35,143,150,151 |
  nav-bar.jsx                     |       50 |      100 |        0 |       50 |                12 |
  user-menu.jsx                   |        0 |        0 |        0 |        0 |... 28,229,231,248 |
 jsx/import/navigation/menu-items |     3.33 |        0 |        0 |     3.33 |                   |
  current-result.jsx              |       50 |      100 |        0 |       50 |                15 |
  home.jsx                        |       50 |      100 |        0 |       50 |                17 |
  login.jsx                       |        0 |        0 |        0 |        0 |... 20,123,132,133 |
  register.jsx                    |        0 |        0 |        0 |        0 |    25,30,40,44,45 |
  results.jsx                     |        0 |        0 |        0 |        0 |... 92,102,106,107 |
 jsx/import/redux/action          |    15.38 |        0 |       20 |    15.38 |                   |
  current-result.jsx              |        0 |      100 |        0 |        0 |                 7 |
  login.jsx                       |        0 |      100 |        0 |        0 |                 7 |
  logout.jsx                      |        0 |      100 |        0 |        0 |                 9 |
  page.jsx                        |       20 |        0 |    28.57 |       20 |... 42,56,57,62,63 |
 jsx/import/redux/container       |       38 |        0 |        0 |       38 |                   |
  analysis-layout.jsx             |    13.64 |        0 |        0 |    13.64 |... 43,46,47,53,70 |
  current-result.jsx              |       30 |        0 |        0 |       30 |... 22,29,30,34,44 |
  data-append.jsx                 |    66.67 |      100 |        0 |    66.67 |                24 |
  data-new.jsx                    |    66.67 |      100 |        0 |    66.67 |                19 |
  header-menu.jsx                 |    66.67 |      100 |        0 |    66.67 |                18 |
  home-page.jsx                   |    66.67 |      100 |        0 |    66.67 |                18 |
  login-link.jsx                  |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
  login.jsx                       |     37.5 |        0 |        0 |     37.5 |    21,22,24,28,37 |
  model-generate.jsx              |    66.67 |      100 |        0 |    66.67 |                24 |
  model-predict.jsx               |    66.67 |      100 |        0 |    66.67 |                25 |
  range-slider.jsx                |    66.67 |      100 |        0 |    66.67 |                18 |
  register-link.jsx               |    33.33 |        0 |        0 |    33.33 |       18,19,21,25 |
  register.jsx                    |     37.5 |        0 |        0 |     37.5 |    20,21,23,27,36 |
  results.jsx                     |    66.67 |      100 |        0 |    66.67 |                18 |
  review-results-link.jsx         |    33.33 |        0 |        0 |    33.33 |       17,22,23,27 |
  user-menu.jsx                   |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
 jsx/import/result                |        0 |        0 |        0 |        0 |                   |
  current-result.jsx              |        0 |        0 |        0 |        0 |... 46,349,404,411 |
  results.jsx                     |        0 |        0 |        0 |        0 |... 15,132,141,146 |
 jsx/import/route                 |      100 |      100 |      100 |      100 |                   |
  main-route.jsx                  |      100 |      100 |      100 |      100 |                   |
 jsx/import/session-type          |        0 |        0 |        0 |        0 |                   |
  data-append.jsx                 |        0 |        0 |        0 |        0 |... 10,211,213,243 |
  data-new.jsx                    |        0 |        0 |        0 |        0 |... 65,166,172,174 |
  model-generate.jsx              |        0 |        0 |        0 |        0 |... 45,248,252,280 |
  model-predict.jsx               |        0 |        0 |        0 |        0 |... 65,171,173,195 |
 jsx/import/svg                   |        0 |        0 |        0 |        0 |                   |
  svg-books.jsx                   |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
  svg-home.jsx                    |        0 |        0 |        0 |        0 |... 32,36,40,44,48 |
  svg-pencil-note.jsx             |        0 |      100 |        0 |        0 |... 21,22,26,30,34 |
  svg-user.jsx                    |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
 jsx/import/validator             |        0 |        0 |        0 |        0 |                   |
  valid-email.js                  |        0 |      100 |        0 |        0 |            6,7,11 |
  valid-file.js                   |        0 |        0 |        0 |        0 |       6,7,8,10,15 |
  valid-float.js                  |        0 |        0 |        0 |        0 |... 16,17,19,22,27 |
  valid-password.js               |        0 |      100 |        0 |        0 |          10,11,15 |
  valid-string.js                 |        0 |        0 |        0 |        0 |          6,7,9,14 |
  valid-url.js                    |        0 |      100 |        0 |        0 |            6,7,11 |
----------------------------------|----------|----------|----------|----------|-------------------|
Test Suites: 2 failed, 2 passed, 4 total
Tests:       5 failed, 9 passed, 14 total
Snapshots:   0 total
Time:        13.63s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test: `NODE_ENV=test jest --config jest.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the reactjs@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-05-13T13_08_22_942Z-debug.log

Note: I'm going to move all the route to their own designated components, to allow better segregation, for better reusability, and even for future unit tests.

betancourtl commented 6 years ago

This is good though, now you don't have to worry about the PageLayout dependencies. You only need to worry about passing the correct props to the components being rendered.

Try wrapping the MemoryRouter with a Provider Component.

    it('should render login route', () => {
        const wrapper = mount(
            <Provider store={ReduxStateUsedByLoginComponent}>
              <MemoryRouter initialEntries={[ '/login' ]}>
                  <MainRoute/>
              </MemoryRouter>
            </Provider>
        );
        expect(wrapper.find(LoginLayout)).toHaveLength(1);
    });
jeff1evesque commented 6 years ago

Is {ReduxStateUsedByLoginComponent} a json structure, of all the redux properties? What if the Login component also uses props, or it's nested child component(s) uses props?

betancourtl commented 6 years ago

render the component like in the example above and by ReduxStateUsedByLoginComponent just pass an empty object to start.

Whenever the test fails start passing the props that the test wants. I'm guessing the props will all be from redux store because the routes do not seem to be passing any props.

Also in order to avoid children components rendering (which might make your test fail) use shallow render

jeff1evesque commented 6 years ago

React won't accept an empty object:

root@browserify:/var/machine-learning/src/jsx# npm run test

> reactjs@1.0.0 test /var/machine-learning/src/jsx
> NODE_ENV=test jest --config jest.config.js

 FAIL  __tests__/layout/page.test.jsx
  ● Test suite failed to run

    /var/machine-learning/src/jsx/__tests__/layout/page.test.jsx: JSX attributes must only be assigned a non-empty expression (28:28)
        26 |     it('should render home route', () => {
        27 |         const wrapper = mount(
      > 28 |             <Provider store={}>
           |                             ^
        29 |                 <MemoryRouter initialEntries={[ '/' ]}>
        30 |                     <MainRoute/>
        31 |                 </MemoryRouter>

Am I supposed to pass in the implemented redux action in the ReduxStateUsedByLoginComponent? For example, pass in the setLoginState, in place of ReduxStateUsedByLoginComponent?

betancourtl commented 6 years ago

<Provider store={{}}>

jeff1evesque commented 6 years ago

a051c05 : without the committed changes, while applying <Provider store={{}}>:

root@trusty64:/vagrant# docker run --hostname browserify --name browserify -d jeff1evesque/ml-browserify:0.7529e99e791915c73628154ca2de13b7a8202fa1d43aa8c22c7888c50013359f0
root@trusty64:/vagrant# docker exec -it browserify /bin/bash                                                root@browserify:/var/machine-learning/src/jsx# npm run test

> reactjs@1.0.0 test /var/machine-learning/src/jsx
> NODE_ENV=test jest --config jest.config.js

 FAIL  __tests__/layout/page.test.jsx
  ● Test suite failed to run

    ReferenceError: sessionStorage is not defined

      at Object.<anonymous> (import/redux/store.jsx:128:119)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:19:14)

 FAIL  __tests__/layout/analysis.test.jsx
  ● Test suite failed to run

    /var/machine-learning/src/jsx/__tests__/layout/analysis.test.jsx: Unexpected token (34:8)
        32 |
        33 |     it('should render correct routes', () => {
      > 34 |         const wrapper = shallow(<AnalysisLayout />);
           |         ^
        35 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
        36 |             const routeProps = route.props();
        37 |             pathMap[routeProps.path] = routeProps.component;

 PASS  __tests__/content/login.test.jsx
  Login Component
    ✓ should render without throwing an error (33ms)
    ✓ should render without throwing an error (22ms)
    ✓ should render without throwing an error (4ms)
    ✓ should render without throwing an error (3ms)

 PASS  __tests__/content/register.test.jsx
  Register Component
    ✓ should render without throwing an error (17ms)
    ✓ should render without throwing an error (13ms)
    ✓ should render without throwing an error (8ms)
    ✓ should render without throwing an error (9ms)
    ✓ should render without throwing an error (6ms)

-------------------------|----------|----------|----------|----------|-------------------|
File                     |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------------|----------|----------|----------|----------|-------------------|
All files                |    22.58 |    12.75 |       25 |    22.95 |                   |
 jsx                     |       50 |      100 |        0 |      100 |                   |
  setup.js               |       50 |      100 |        0 |      100 |                   |
 jsx/import/content      |    25.34 |    15.12 |    44.44 |    25.34 |                   |
  login.jsx              |    27.78 |    16.13 |    55.56 |    27.78 |... 46,156,169,183 |
  register.jsx           |    23.91 |    14.55 |    33.33 |    23.91 |... 99,209,219,231 |
 jsx/import/general      |     6.67 |        0 |        0 |     7.14 |                   |
  ajax-caller.js         |        0 |        0 |        0 |        0 |... 46,49,53,57,63 |
  spinner.jsx            |       50 |      100 |        0 |       50 |                14 |
 jsx/import/redux/action |    18.18 |        0 |       25 |    18.18 |                   |
  login.jsx              |        0 |      100 |        0 |        0 |                 7 |
  page.jsx               |       20 |        0 |    28.57 |       20 |... 42,56,57,62,63 |
 jsx/import/validator    |        0 |        0 |        0 |        0 |                   |
  valid-email.js         |        0 |      100 |        0 |        0 |            6,7,11 |
  valid-password.js      |        0 |      100 |        0 |        0 |          10,11,15 |
  valid-string.js        |        0 |        0 |        0 |        0 |          6,7,9,14 |
-------------------------|----------|----------|----------|----------|-------------------|
Test Suites: 2 failed, 2 passed, 4 total
Tests:       9 passed, 9 total
Snapshots:   0 total
Time:        14.38s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test: `NODE_ENV=test jest --config jest.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the reactjs@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-05-14T04_14_37_137Z-debug.log

After the committed change:

root@browserify:/var/machine-learning/src/jsx# npm run test

> reactjs@1.0.0 test /var/machine-learning/src/jsx
> NODE_ENV=test jest --config jest.config.js

 FAIL  __tests__/layout/page.test.jsx (25.633s)
  PageLayout Component
    ✕ should render home route (156ms)
    ✕ should render login route (15ms)
    ✕ should render logout route (9ms)
    ✕ should render register route (26ms)
    ✕ should render analysis route (14ms)

  ● PageLayout Component › should render home route

    TypeError: store.getState is not a function

      21 | describe('PageLayout Component', () => {
      22 |     it('should render home route', () => {
    > 23 |         const wrapper = mount(
      24 |             <Provider store={{}}>
      25 |                 <MemoryRouter initialEntries={[ '/' ]}>
      26 |                     <MainRoute/>

      at Object.runComponentSelector [as run] (node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
      at Connect.initSelector (node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
      at new Connect (node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
      at constructClassInstance (node_modules/react-dom/cjs/react-dom.development.js:6801:20)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:8336:9)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:8982:16)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:11814:16)
      at workLoop (node_modules/react-dom/cjs/react-dom.development.js:11843:26)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:11874:9)
      at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:12449:24)
      at performWork (node_modules/react-dom/cjs/react-dom.development.js:12370:9)
      at performSyncWork (node_modules/react-dom/cjs/react-dom.development.js:12347:5)
      at requestWork (node_modules/react-dom/cjs/react-dom.development.js:12247:7)
      at scheduleWorkImpl (node_modules/react-dom/cjs/react-dom.development.js:12122:13)
      at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:12082:12)
      at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:12710:5)
      at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:12738:12)
      at Object.updateContainer (node_modules/react-dom/cjs/react-dom.development.js:12765:14)
      at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:16069:15)
      at node_modules/react-dom/cjs/react-dom.development.js:16488:14
      at Object.unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:12557:12)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:16484:17)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:16543:12)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:98:16)
      at mount (node_modules/enzyme/build/mount.js:19:10)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:23:25)

  ● PageLayout Component › should render login route

    TypeError: store.getState is not a function

      32 |
      33 |     it('should render login route', () => {
    > 34 |         const wrapper = mount(
      35 |             <Provider store={{}}>
      36 |                 <MemoryRouter initialEntries={[ '/login' ]}>
      37 |                     <MainRoute/>

      at Object.runComponentSelector [as run] (node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
      at Connect.initSelector (node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
      at new Connect (node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
      at constructClassInstance (node_modules/react-dom/cjs/react-dom.development.js:6801:20)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:8336:9)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:8982:16)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:11814:16)
      at workLoop (node_modules/react-dom/cjs/react-dom.development.js:11843:26)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:11874:9)
      at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:12449:24)
      at performWork (node_modules/react-dom/cjs/react-dom.development.js:12370:9)
      at performSyncWork (node_modules/react-dom/cjs/react-dom.development.js:12347:5)
      at requestWork (node_modules/react-dom/cjs/react-dom.development.js:12247:7)
      at scheduleWorkImpl (node_modules/react-dom/cjs/react-dom.development.js:12122:13)
      at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:12082:12)
      at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:12710:5)
      at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:12738:12)
      at Object.updateContainer (node_modules/react-dom/cjs/react-dom.development.js:12765:14)
      at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:16069:15)
      at node_modules/react-dom/cjs/react-dom.development.js:16488:14
      at Object.unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:12557:12)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:16484:17)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:16543:12)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:98:16)
      at mount (node_modules/enzyme/build/mount.js:19:10)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:34:25)

  ● PageLayout Component › should render logout route

    TypeError: store.getState is not a function

      43 |
      44 |     it('should render logout route', () => {
    > 45 |         const wrapper = mount(
      46 |             <Provider store={{}}>
      47 |                 <MemoryRouter initialEntries={[ '/logout' ]}>
      48 |                     <MainRoute/>

      at Object.runComponentSelector [as run] (node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
      at Connect.initSelector (node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
      at new Connect (node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
      at constructClassInstance (node_modules/react-dom/cjs/react-dom.development.js:6801:20)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:8336:9)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:8982:16)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:11814:16)
      at workLoop (node_modules/react-dom/cjs/react-dom.development.js:11843:26)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:11874:9)
      at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:12449:24)
      at performWork (node_modules/react-dom/cjs/react-dom.development.js:12370:9)
      at performSyncWork (node_modules/react-dom/cjs/react-dom.development.js:12347:5)
      at requestWork (node_modules/react-dom/cjs/react-dom.development.js:12247:7)
      at scheduleWorkImpl (node_modules/react-dom/cjs/react-dom.development.js:12122:13)
      at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:12082:12)
      at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:12710:5)
      at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:12738:12)
      at Object.updateContainer (node_modules/react-dom/cjs/react-dom.development.js:12765:14)
      at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:16069:15)
      at node_modules/react-dom/cjs/react-dom.development.js:16488:14
      at Object.unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:12557:12)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:16484:17)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:16543:12)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:98:16)
      at mount (node_modules/enzyme/build/mount.js:19:10)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:45:25)

  ● PageLayout Component › should render register route

    TypeError: store.getState is not a function

      54 |
      55 |     it('should render register route', () => {
    > 56 |         const wrapper = mount(
      57 |             <Provider store={{}}>
      58 |                 <MemoryRouter initialEntries={[ '/register' ]}>
      59 |                     <MainRoute/>

      at Object.runComponentSelector [as run] (node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
      at Connect.initSelector (node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
      at new Connect (node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
      at constructClassInstance (node_modules/react-dom/cjs/react-dom.development.js:6801:20)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:8336:9)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:8982:16)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:11814:16)
      at workLoop (node_modules/react-dom/cjs/react-dom.development.js:11843:26)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:11874:9)
      at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:12449:24)
      at performWork (node_modules/react-dom/cjs/react-dom.development.js:12370:9)
      at performSyncWork (node_modules/react-dom/cjs/react-dom.development.js:12347:5)
      at requestWork (node_modules/react-dom/cjs/react-dom.development.js:12247:7)
      at scheduleWorkImpl (node_modules/react-dom/cjs/react-dom.development.js:12122:13)
      at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:12082:12)
      at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:12710:5)
      at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:12738:12)
      at Object.updateContainer (node_modules/react-dom/cjs/react-dom.development.js:12765:14)
      at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:16069:15)
      at node_modules/react-dom/cjs/react-dom.development.js:16488:14
      at Object.unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:12557:12)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:16484:17)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:16543:12)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:98:16)
      at mount (node_modules/enzyme/build/mount.js:19:10)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:56:25)

  ● PageLayout Component › should render analysis route

    TypeError: store.getState is not a function

      65 |
      66 |     it('should render analysis route', () => {
    > 67 |         const wrapper = mount(
      68 |             <Provider store={{}}>
      69 |                 <MemoryRouter initialEntries={[ '/register' ]}>
      70 |                     <MainRoute/>

      at Object.runComponentSelector [as run] (node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
      at Connect.initSelector (node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
      at new Connect (node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
      at constructClassInstance (node_modules/react-dom/cjs/react-dom.development.js:6801:20)
      at updateClassComponent (node_modules/react-dom/cjs/react-dom.development.js:8336:9)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:8982:16)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:11814:16)
      at workLoop (node_modules/react-dom/cjs/react-dom.development.js:11843:26)
      at renderRoot (node_modules/react-dom/cjs/react-dom.development.js:11874:9)
      at performWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:12449:24)
      at performWork (node_modules/react-dom/cjs/react-dom.development.js:12370:9)
      at performSyncWork (node_modules/react-dom/cjs/react-dom.development.js:12347:5)
      at requestWork (node_modules/react-dom/cjs/react-dom.development.js:12247:7)
      at scheduleWorkImpl (node_modules/react-dom/cjs/react-dom.development.js:12122:13)
      at scheduleWork (node_modules/react-dom/cjs/react-dom.development.js:12082:12)
      at scheduleRootUpdate (node_modules/react-dom/cjs/react-dom.development.js:12710:5)
      at updateContainerAtExpirationTime (node_modules/react-dom/cjs/react-dom.development.js:12738:12)
      at Object.updateContainer (node_modules/react-dom/cjs/react-dom.development.js:12765:14)
      at ReactRoot.Object.<anonymous>.ReactRoot.render (node_modules/react-dom/cjs/react-dom.development.js:16069:15)
      at node_modules/react-dom/cjs/react-dom.development.js:16488:14
      at Object.unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:12557:12)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:16484:17)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:16543:12)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
      at new ReactWrapper (node_modules/enzyme/build/ReactWrapper.js:98:16)
      at mount (node_modules/enzyme/build/mount.js:19:10)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:67:25)

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: Failed prop type: The prop `store.subscribe` is marked as required in `Provider`, but its value is `undefined`.
        in Provider

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: Failed child context type: The child context `store.subscribe` is marked as required in `Provider`, but its value is `undefined`.
        in Provider (created by WrapperComponent)
        in WrapperComponent

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: Failed context type: The context `store.subscribe` is marked as required in `Connect(HomePage)`, but its value is `undefined`.
        in Connect(HomePage) (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Uncaught [TypeError: store.getState is not a function]
        at reportException (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11) TypeError: store.getState is not a function
        at Object.runComponentSelector [as run] (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
        at Connect.initSelector (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
        at new Connect (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
        at constructClassInstance (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:6801:20)
        at updateClassComponent (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8336:9)
        at beginWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8982:16)
        at performUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11814:16)
        at workLoop (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11843:26)
        at HTMLUnknownElement.callCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:100:14)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11)
        at performWorkOnRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12449:24)
        at performWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12370:9)
        at performSyncWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12347:5)
        at requestWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12247:7)
        at scheduleWorkImpl (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12122:13)
        at scheduleWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12082:12)
        at scheduleRootUpdate (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12710:5)
        at updateContainerAtExpirationTime (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12738:12)
        at Object.updateContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12765:14)
        at ReactRoot.Object.<anonymous>.ReactRoot.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16069:15)
        at /var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16488:14
        at Object.unbatchedUpdates (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12557:12)
        at legacyRenderSubtreeIntoContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16484:17)
        at Object.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16543:12)
        at Object.render (/var/machine-learning/src/jsx/node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
        at new ReactWrapper (/var/machine-learning/src/jsx/node_modules/enzyme/build/ReactWrapper.js:98:16)
        at mount (/var/machine-learning/src/jsx/node_modules/enzyme/build/mount.js:19:10)
        at Object.<anonymous> (/var/machine-learning/src/jsx/__tests__/layout/page.test.jsx:58:41)
        at Object.asyncFn (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/jasmine_async.js:82:37)
        at resolve (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
        at new Promise (<anonymous>)
        at mapper (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
        at promise.then (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
        at <anonymous>

  console.error node_modules/react-dom/cjs/react-dom.development.js:9643
    The above error occurred in the <Connect(HomePage)> component:
        in Connect(HomePage) (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: Failed context type: The context `store.subscribe` is marked as required in `Connect(LoginForm)`, but its value is `undefined`.
        in Connect(LoginForm) (created by LoginLayout)
        in div (created by LoginLayout)
        in LoginLayout (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Uncaught [TypeError: store.getState is not a function]
        at reportException (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11) TypeError: store.getState is not a function
        at Object.runComponentSelector [as run] (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
        at Connect.initSelector (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
        at new Connect (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
        at constructClassInstance (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:6801:20)
        at updateClassComponent (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8336:9)
        at beginWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8982:16)
        at performUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11814:16)
        at workLoop (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11843:26)
        at HTMLUnknownElement.callCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:100:14)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11)
        at performWorkOnRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12449:24)
        at performWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12370:9)
        at performSyncWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12347:5)
        at requestWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12247:7)
        at scheduleWorkImpl (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12122:13)
        at scheduleWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12082:12)
        at scheduleRootUpdate (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12710:5)
        at updateContainerAtExpirationTime (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12738:12)
        at Object.updateContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12765:14)
        at ReactRoot.Object.<anonymous>.ReactRoot.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16069:15)
        at /var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16488:14
        at Object.unbatchedUpdates (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12557:12)
        at legacyRenderSubtreeIntoContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16484:17)
        at Object.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16543:12)
        at Object.render (/var/machine-learning/src/jsx/node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
        at new ReactWrapper (/var/machine-learning/src/jsx/node_modules/enzyme/build/ReactWrapper.js:98:16)
        at mount (/var/machine-learning/src/jsx/node_modules/enzyme/build/mount.js:19:10)
        at Object.<anonymous> (/var/machine-learning/src/jsx/__tests__/layout/page.test.jsx:71:41)
        at Object.asyncFn (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/jasmine_async.js:82:37)
        at resolve (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
        at new Promise (<anonymous>)
        at mapper (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
        at promise.then (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
        at <anonymous>

  console.error node_modules/react-dom/cjs/react-dom.development.js:9643
    The above error occurred in the <Connect(LoginForm)> component:
        in Connect(LoginForm) (created by LoginLayout)
        in div (created by LoginLayout)
        in LoginLayout (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Uncaught [TypeError: store.getState is not a function]
        at reportException (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11) TypeError: store.getState is not a function
        at Object.runComponentSelector [as run] (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
        at Connect.initSelector (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
        at new Connect (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
        at constructClassInstance (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:6801:20)
        at updateClassComponent (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8336:9)
        at beginWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8982:16)
        at performUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11814:16)
        at workLoop (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11843:26)
        at HTMLUnknownElement.callCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:100:14)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11)
        at performWorkOnRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12449:24)
        at performWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12370:9)
        at performSyncWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12347:5)
        at requestWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12247:7)
        at scheduleWorkImpl (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12122:13)
        at scheduleWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12082:12)
        at scheduleRootUpdate (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12710:5)
        at updateContainerAtExpirationTime (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12738:12)
        at Object.updateContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12765:14)
        at ReactRoot.Object.<anonymous>.ReactRoot.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16069:15)
        at /var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16488:14
        at Object.unbatchedUpdates (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12557:12)
        at legacyRenderSubtreeIntoContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16484:17)
        at Object.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16543:12)
        at Object.render (/var/machine-learning/src/jsx/node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
        at new ReactWrapper (/var/machine-learning/src/jsx/node_modules/enzyme/build/ReactWrapper.js:98:16)
        at mount (/var/machine-learning/src/jsx/node_modules/enzyme/build/mount.js:19:10)
        at Object.<anonymous> (/var/machine-learning/src/jsx/__tests__/layout/page.test.jsx:84:41)
        at Object.asyncFn (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/jasmine_async.js:82:37)
        at resolve (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
        at new Promise (<anonymous>)
        at mapper (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
        at promise.then (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
        at <anonymous>

  console.error node_modules/react-dom/cjs/react-dom.development.js:9643
    The above error occurred in the <Connect(LoginForm)> component:
        in Connect(LoginForm) (created by LoginLayout)
        in div (created by LoginLayout)
        in LoginLayout (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

  console.error node_modules/fbjs/lib/warning.js:33
    Warning: Failed context type: The context `store.subscribe` is marked as required in `Connect(RegisterForm)`, but its value is `undefined`.
        in Connect(RegisterForm) (created by RegisterLayout)
        in div (created by RegisterLayout)
        in RegisterLayout (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Uncaught [TypeError: store.getState is not a function]
        at reportException (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11) TypeError: store.getState is not a function
        at Object.runComponentSelector [as run] (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
        at Connect.initSelector (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
        at new Connect (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
        at constructClassInstance (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:6801:20)
        at updateClassComponent (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8336:9)
        at beginWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8982:16)
        at performUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11814:16)
        at workLoop (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11843:26)
        at HTMLUnknownElement.callCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:100:14)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11)
        at performWorkOnRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12449:24)
        at performWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12370:9)
        at performSyncWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12347:5)
        at requestWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12247:7)
        at scheduleWorkImpl (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12122:13)
        at scheduleWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12082:12)
        at scheduleRootUpdate (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12710:5)
        at updateContainerAtExpirationTime (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12738:12)
        at Object.updateContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12765:14)
        at ReactRoot.Object.<anonymous>.ReactRoot.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16069:15)
        at /var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16488:14
        at Object.unbatchedUpdates (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12557:12)
        at legacyRenderSubtreeIntoContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16484:17)
        at Object.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16543:12)
        at Object.render (/var/machine-learning/src/jsx/node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
        at new ReactWrapper (/var/machine-learning/src/jsx/node_modules/enzyme/build/ReactWrapper.js:98:16)
        at mount (/var/machine-learning/src/jsx/node_modules/enzyme/build/mount.js:19:10)
        at Object.<anonymous> (/var/machine-learning/src/jsx/__tests__/layout/page.test.jsx:97:41)
        at Object.asyncFn (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/jasmine_async.js:82:37)
        at resolve (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
        at new Promise (<anonymous>)
        at mapper (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
        at promise.then (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
        at <anonymous>

  console.error node_modules/react-dom/cjs/react-dom.development.js:9643
    The above error occurred in the <Connect(RegisterForm)> component:
        in Connect(RegisterForm) (created by RegisterLayout)
        in div (created by RegisterLayout)
        in RegisterLayout (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

  console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Uncaught [TypeError: store.getState is not a function]
        at reportException (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11) TypeError: store.getState is not a function
        at Object.runComponentSelector [as run] (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:43:46)
        at Connect.initSelector (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:195:23)
        at new Connect (/var/machine-learning/src/jsx/node_modules/react-redux/lib/components/connectAdvanced.js:136:15)
        at constructClassInstance (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:6801:20)
        at updateClassComponent (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8336:9)
        at beginWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:8982:16)
        at performUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11814:16)
        at workLoop (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11843:26)
        at HTMLUnknownElement.callCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:100:14)
        at invokeEventListeners (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
        at HTMLUnknownElementImpl._dispatch (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
        at HTMLUnknownElementImpl.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
        at HTMLUnknownElement.dispatchEvent (/var/machine-learning/src/jsx/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
        at Object.invokeGuardedCallbackDev (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:138:16)
        at invokeGuardedCallback (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:187:29)
        at replayUnitOfWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11318:7)
        at renderRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:11885:11)
        at performWorkOnRoot (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12449:24)
        at performWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12370:9)
        at performSyncWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12347:5)
        at requestWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12247:7)
        at scheduleWorkImpl (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12122:13)
        at scheduleWork (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12082:12)
        at scheduleRootUpdate (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12710:5)
        at updateContainerAtExpirationTime (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12738:12)
        at Object.updateContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12765:14)
        at ReactRoot.Object.<anonymous>.ReactRoot.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16069:15)
        at /var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16488:14
        at Object.unbatchedUpdates (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:12557:12)
        at legacyRenderSubtreeIntoContainer (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16484:17)
        at Object.render (/var/machine-learning/src/jsx/node_modules/react-dom/cjs/react-dom.development.js:16543:12)
        at Object.render (/var/machine-learning/src/jsx/node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:218:50)
        at new ReactWrapper (/var/machine-learning/src/jsx/node_modules/enzyme/build/ReactWrapper.js:98:16)
        at mount (/var/machine-learning/src/jsx/node_modules/enzyme/build/mount.js:19:10)
        at Object.<anonymous> (/var/machine-learning/src/jsx/__tests__/layout/page.test.jsx:110:41)
        at Object.asyncFn (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/jasmine_async.js:82:37)
        at resolve (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
        at new Promise (<anonymous>)
        at mapper (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
        at promise.then (/var/machine-learning/src/jsx/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
        at <anonymous>

  console.error node_modules/react-dom/cjs/react-dom.development.js:9643
    The above error occurred in the <Connect(RegisterForm)> component:
        in Connect(RegisterForm) (created by RegisterLayout)
        in div (created by RegisterLayout)
        in RegisterLayout (created by Route)
        in Route (created by MainRoute)
        in div (created by MainRoute)
        in MainRoute
        in Router (created by MemoryRouter)
        in MemoryRouter
        in Provider (created by WrapperComponent)
        in WrapperComponent

    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

 FAIL  __tests__/layout/analysis.test.jsx
  ● Test suite failed to run

    /var/machine-learning/src/jsx/__tests__/layout/analysis.test.jsx: Unexpected token (34:8)
        32 |
        33 |     it('should render correct routes', () => {
      > 34 |         const wrapper = shallow(<AnalysisLayout />);
           |         ^
        35 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
        36 |             const routeProps = route.props();
        37 |             pathMap[routeProps.path] = routeProps.component;

 PASS  __tests__/content/login.test.jsx
  Login Component
    ✓ should render without throwing an error (13ms)
    ✓ should render without throwing an error (14ms)
    ✓ should render without throwing an error (10ms)
    ✓ should render without throwing an error (1ms)

 PASS  __tests__/content/register.test.jsx
  Register Component
    ✓ should render without throwing an error (7ms)
    ✓ should render without throwing an error (7ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (7ms)
    ✓ should render without throwing an error (1ms)

--------------------------|----------|----------|----------|----------|-------------------|
File                      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------------|----------|----------|----------|----------|-------------------|
All files                 |     8.35 |     1.86 |     5.02 |     8.39 |                   |
 animation                |        0 |        0 |        0 |        0 |                   |
  animate.jsx             |        0 |        0 |        0 |        0 |... 47,148,149,160 |
 content                  |    24.83 |    15.12 |       40 |    24.83 |                   |
  home-page.jsx           |        0 |      100 |        0 |        0 |          27,28,32 |
  login.jsx               |    27.78 |    16.13 |    55.56 |    27.78 |... 46,156,169,183 |
  register.jsx            |    23.91 |    14.55 |    33.33 |    23.91 |... 99,209,219,231 |
 formatter                |        0 |      100 |        0 |        0 |                   |
  transpose.js            |        0 |      100 |        0 |        0 |    47,48,51,52,57 |
 general                  |    19.05 |        0 |        0 |    19.51 |                   |
  ajax-caller.js          |        0 |        0 |        0 |        0 |... 46,49,53,57,63 |
  breakpoints.js          |      100 |      100 |      100 |      100 |                   |
  colors.js               |      100 |      100 |      100 |      100 |                   |
  range-slider.jsx        |        0 |        0 |        0 |        0 |... 62,63,64,65,67 |
  spinner.jsx             |       50 |      100 |        0 |       50 |                14 |
  submit-button.jsx       |        0 |        0 |        0 |        0 |    23,24,25,26,28 |
 input-data               |        0 |        0 |        0 |        0 |                   |
  supply-dataset-file.jsx |        0 |        0 |        0 |        0 |... 8,90,95,96,113 |
  supply-dataset-url.jsx  |        0 |        0 |        0 |        0 |... 6,88,93,94,112 |
  supply-predictors.jsx   |        0 |        0 |        0 |        0 |... 11,118,119,121 |
 layout                   |     5.26 |        0 |    13.33 |     5.26 |                   |
  analysis.jsx            |        0 |        0 |        0 |        0 |... 19,320,321,327 |
  login.jsx               |      100 |      100 |      100 |      100 |                   |
  register.jsx            |      100 |      100 |      100 |      100 |                   |
 model                    |        0 |        0 |        0 |        0 |                   |
  model-type.jsx          |        0 |        0 |        0 |        0 |... 27,28,29,31,37 |
 navigation               |     1.82 |        0 |        0 |     1.82 |                   |
  header-menu.jsx         |        0 |        0 |        0 |        0 |... 35,143,150,151 |
  nav-bar.jsx             |       50 |      100 |        0 |       50 |                12 |
  user-menu.jsx           |        0 |        0 |        0 |        0 |... 28,229,231,248 |
 navigation/menu-items    |     3.33 |        0 |        0 |     3.33 |                   |
  current-result.jsx      |       50 |      100 |        0 |       50 |                15 |
  home.jsx                |       50 |      100 |        0 |       50 |                17 |
  login.jsx               |        0 |        0 |        0 |        0 |... 20,123,132,133 |
  register.jsx            |        0 |        0 |        0 |        0 |    25,30,40,44,45 |
  results.jsx             |        0 |        0 |        0 |        0 |... 92,102,106,107 |
 redux/action             |    15.38 |        0 |       20 |    15.38 |                   |
  current-result.jsx      |        0 |      100 |        0 |        0 |                 7 |
  login.jsx               |        0 |      100 |        0 |        0 |                 7 |
  logout.jsx              |        0 |      100 |        0 |        0 |                 9 |
  page.jsx                |       20 |        0 |    28.57 |       20 |... 42,56,57,62,63 |
 redux/container          |       38 |        0 |        0 |       38 |                   |
  analysis-layout.jsx     |    13.64 |        0 |        0 |    13.64 |... 43,46,47,53,70 |
  current-result.jsx      |       30 |        0 |        0 |       30 |... 22,29,30,34,44 |
  data-append.jsx         |    66.67 |      100 |        0 |    66.67 |                24 |
  data-new.jsx            |    66.67 |      100 |        0 |    66.67 |                19 |
  header-menu.jsx         |    66.67 |      100 |        0 |    66.67 |                18 |
  home-page.jsx           |    66.67 |      100 |        0 |    66.67 |                18 |
  login-link.jsx          |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
  login.jsx               |     37.5 |        0 |        0 |     37.5 |    21,22,24,28,37 |
  model-generate.jsx      |    66.67 |      100 |        0 |    66.67 |                24 |
  model-predict.jsx       |    66.67 |      100 |        0 |    66.67 |                25 |
  range-slider.jsx        |    66.67 |      100 |        0 |    66.67 |                18 |
  register-link.jsx       |    33.33 |        0 |        0 |    33.33 |       18,19,21,25 |
  register.jsx            |     37.5 |        0 |        0 |     37.5 |    20,21,23,27,36 |
  results.jsx             |    66.67 |      100 |        0 |    66.67 |                18 |
  review-results-link.jsx |    33.33 |        0 |        0 |    33.33 |       17,22,23,27 |
  user-menu.jsx           |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
 result                   |        0 |        0 |        0 |        0 |                   |
  current-result.jsx      |        0 |        0 |        0 |        0 |... 46,349,404,411 |
  results.jsx             |        0 |        0 |        0 |        0 |... 15,132,141,146 |
 route                    |    33.33 |      100 |    33.33 |    33.33 |                   |
  main-route.jsx          |      100 |      100 |      100 |      100 |                   |
  result-route.jsx        |        0 |      100 |        0 |        0 |                19 |
  session-route.jsx       |        0 |      100 |        0 |        0 |                21 |
 session-type             |        0 |        0 |        0 |        0 |                   |
  data-append.jsx         |        0 |        0 |        0 |        0 |... 10,211,213,243 |
  data-new.jsx            |        0 |        0 |        0 |        0 |... 65,166,172,174 |
  model-generate.jsx      |        0 |        0 |        0 |        0 |... 45,248,252,280 |
  model-predict.jsx       |        0 |        0 |        0 |        0 |... 65,171,173,195 |
 svg                      |        0 |        0 |        0 |        0 |                   |
  svg-books.jsx           |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
  svg-home.jsx            |        0 |        0 |        0 |        0 |... 32,36,40,44,48 |
  svg-pencil-note.jsx     |        0 |      100 |        0 |        0 |... 21,22,26,30,34 |
  svg-user.jsx            |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
 validator                |        0 |        0 |        0 |        0 |                   |
  valid-email.js          |        0 |      100 |        0 |        0 |            6,7,11 |
  valid-file.js           |        0 |        0 |        0 |        0 |       6,7,8,10,15 |
  valid-float.js          |        0 |        0 |        0 |        0 |... 16,17,19,22,27 |
  valid-password.js       |        0 |      100 |        0 |        0 |          10,11,15 |
  valid-string.js         |        0 |        0 |        0 |        0 |          6,7,9,14 |
  valid-url.js            |        0 |      100 |        0 |        0 |            6,7,11 |
--------------------------|----------|----------|----------|----------|-------------------|
Test Suites: 2 failed, 2 passed, 4 total
Tests:       5 failed, 9 passed, 14 total
Snapshots:   0 total
Time:        31.713s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test: `NODE_ENV=test jest --config jest.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the reactjs@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-05-14T04_34_21_537Z-debug.log
jeff1evesque commented 6 years ago

Instead of using jest.fn, the fully explicit store can be supplied to the <Provider store={store}/> component. This may mean that we run the web-interface with console.log('store' + $store); in our store.jsx, to determine the corresponding store values, when particular components are rendered.

rickhanlonii commented 6 years ago

@jeff1evesque have you seen redux-mock-store?

jeff1evesque commented 6 years ago

@rickhanlonii, do you recommend redux-mock-store over passing the explicit store object to the <Provider/> component? I was leaning towards using an explicit store object. But, this requires me to know exactly what properties are required by the store, which may be challenging since many properties aren't defined by default. Instead they get added to the store via redux.

ljharb commented 6 years ago

so add them via redux in your tests

jeff1evesque commented 6 years ago

The test results have improved:

root@browserify:/var/machine-learning/src/jsx# npm run test

> reactjs@1.0.0 test /var/machine-learning/src/jsx
> NODE_ENV=test jest --config jest.config.js

 FAIL  __tests__/layout/analysis.test.jsx
  ● Test suite failed to run

    /var/machine-learning/src/jsx/__tests__/layout/analysis.test.jsx: Unexpected token (46:8)
        44 |
        45 |     it('should render data-new route', () => {
      > 46 |         const wrapper = mount(
           |         ^
        47 |             <Provider store={store}>
        48 |                 <MemoryRouter initialEntries={[ '/session/data-new' ]}>
        49 |                     <SessionRoute/>

 PASS  __tests__/layout/page.test.jsx (20.047s)
  PageLayout Component
    ✓ should render home route (298ms)
    ✓ should render login route (53ms)
    ✓ should render logout route (16ms)
    ✓ should render register route (25ms)
    ✓ should render analysis route (80ms)

 PASS  __tests__/content/login.test.jsx
  Login Component
    ✓ should render without throwing an error (18ms)
    ✓ should render without throwing an error (26ms)
    ✓ should render without throwing an error (1ms)
    ✓ should render without throwing an error (1ms)

 PASS  __tests__/content/register.test.jsx
  Register Component
    ✓ should render without throwing an error (7ms)
    ✓ should render without throwing an error (3ms)
    ✓ should render without throwing an error (1ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (9ms)

--------------------------|----------|----------|----------|----------|-------------------|
File                      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------------|----------|----------|----------|----------|-------------------|
All files                 |    19.43 |    12.82 |    21.29 |    19.53 |                   |
 animation                |    79.17 |       55 |    64.29 |    79.17 |                   |
  animate.jsx             |    79.17 |       55 |    64.29 |    79.17 |... 34,135,136,139 |
 content                  |    26.85 |    17.44 |       50 |    26.85 |                   |
  home-page.jsx           |      100 |      100 |      100 |      100 |                   |
  login.jsx               |    27.78 |    22.58 |    55.56 |    27.78 |... 46,156,169,183 |
  register.jsx            |    23.91 |    14.55 |    33.33 |    23.91 |... 99,209,219,231 |
 formatter                |        0 |      100 |        0 |        0 |                   |
  transpose.js            |        0 |      100 |        0 |        0 |    47,48,51,52,57 |
 general                  |    35.71 |    15.38 |    27.27 |    36.59 |                   |
  ajax-caller.js          |    53.85 |       50 |       60 |    58.33 |    16,44,46,49,53 |
  breakpoints.js          |      100 |      100 |      100 |      100 |                   |
  colors.js               |      100 |      100 |      100 |      100 |                   |
  range-slider.jsx        |        0 |        0 |        0 |        0 |... 62,63,64,65,67 |
  spinner.jsx             |       50 |      100 |        0 |       50 |                14 |
  submit-button.jsx       |        0 |        0 |        0 |        0 |    23,24,25,26,28 |
 input-data               |        0 |        0 |        0 |        0 |                   |
  supply-dataset-file.jsx |        0 |        0 |        0 |        0 |... 8,90,95,96,113 |
  supply-dataset-url.jsx  |        0 |        0 |        0 |        0 |... 6,88,93,94,112 |
  supply-predictors.jsx   |        0 |        0 |        0 |        0 |... 11,118,119,121 |
 layout                   |    34.21 |    18.29 |    73.33 |    34.21 |                   |
  analysis.jsx            |    30.56 |    18.29 |    69.23 |    30.56 |... 33,234,254,281 |
  login.jsx               |      100 |      100 |      100 |      100 |                   |
  register.jsx            |      100 |      100 |      100 |      100 |                   |
 model                    |        0 |        0 |        0 |        0 |                   |
  model-type.jsx          |        0 |        0 |        0 |        0 |... 27,28,29,31,37 |
 navigation               |     3.64 |        0 |     6.25 |     3.64 |                   |
  header-menu.jsx         |        0 |        0 |        0 |        0 |... 35,143,150,151 |
  nav-bar.jsx             |      100 |      100 |      100 |      100 |                   |
  user-menu.jsx           |        0 |        0 |        0 |        0 |... 28,229,231,248 |
 navigation/menu-items    |    23.33 |    15.09 |    33.33 |    23.33 |                   |
  current-result.jsx      |       50 |      100 |        0 |       50 |                15 |
  home.jsx                |       50 |      100 |        0 |       50 |                17 |
  login.jsx               |        0 |        0 |        0 |        0 |... 20,123,132,133 |
  register.jsx            |        0 |        0 |        0 |        0 |    25,30,40,44,45 |
  results.jsx             |    52.17 |    44.44 |    83.33 |    52.17 |... 63,64,67,68,92 |
 redux                    |      100 |      100 |      100 |      100 |                   |
  store.jsx               |      100 |      100 |      100 |      100 |                   |
 redux/action             |    15.38 |        0 |       20 |    15.38 |                   |
  current-result.jsx      |        0 |      100 |        0 |        0 |                 7 |
  login.jsx               |        0 |      100 |        0 |        0 |                 7 |
  logout.jsx              |        0 |      100 |        0 |        0 |                 9 |
  page.jsx                |       20 |        0 |    28.57 |       20 |... 42,56,57,62,63 |
 redux/container          |       60 |    31.58 |    36.36 |       60 |                   |
  analysis-layout.jsx     |    63.64 |    33.33 |      100 |    63.64 |... 38,42,43,46,47 |
  current-result.jsx      |       30 |        0 |        0 |       30 |... 22,29,30,34,44 |
  data-append.jsx         |    66.67 |      100 |        0 |    66.67 |                24 |
  data-new.jsx            |    66.67 |      100 |        0 |    66.67 |                19 |
  header-menu.jsx         |    66.67 |      100 |        0 |    66.67 |                18 |
  home-page.jsx           |      100 |      100 |      100 |      100 |                   |
  login-link.jsx          |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
  login.jsx               |     87.5 |       80 |      100 |     87.5 |                22 |
  model-generate.jsx      |    66.67 |      100 |        0 |    66.67 |                24 |
  model-predict.jsx       |    66.67 |      100 |        0 |    66.67 |                25 |
  range-slider.jsx        |    66.67 |      100 |        0 |    66.67 |                18 |
  register-link.jsx       |    33.33 |        0 |        0 |    33.33 |       18,19,21,25 |
  register.jsx            |     87.5 |       80 |      100 |     87.5 |                21 |
  results.jsx             |    66.67 |      100 |        0 |    66.67 |                18 |
  review-results-link.jsx |    66.67 |    57.14 |      100 |    66.67 |             22,23 |
  user-menu.jsx           |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
 redux/reducer            |    54.76 |       55 |      100 |    54.76 |                   |
  data.jsx                |     37.5 |    36.36 |      100 |     37.5 |    17,18,20,22,29 |
  layout.jsx              |     87.5 |    90.91 |      100 |     87.5 |                38 |
  login.jsx               |     62.5 |    55.56 |      100 |     62.5 |          16,23,25 |
  page.jsx                |    44.44 |    33.33 |      100 |    44.44 |... 43,52,54,69,77 |
 result                   |        0 |        0 |        0 |        0 |                   |
  current-result.jsx      |        0 |        0 |        0 |        0 |... 46,349,404,411 |
  results.jsx             |        0 |        0 |        0 |        0 |... 15,132,141,146 |
 route                    |      100 |      100 |      100 |      100 |                   |
  main-route.jsx          |      100 |      100 |      100 |      100 |                   |
  result-route.jsx        |      100 |      100 |      100 |      100 |                   |
  session-route.jsx       |      100 |      100 |      100 |      100 |                   |
 session-type             |        0 |        0 |        0 |        0 |                   |
  data-append.jsx         |        0 |        0 |        0 |        0 |... 10,211,213,243 |
  data-new.jsx            |        0 |        0 |        0 |        0 |... 65,166,172,174 |
  model-generate.jsx      |        0 |        0 |        0 |        0 |... 45,248,252,280 |
  model-predict.jsx       |        0 |        0 |        0 |        0 |... 65,171,173,195 |
 svg                      |        0 |        0 |        0 |        0 |                   |
  svg-books.jsx           |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
  svg-home.jsx            |        0 |        0 |        0 |        0 |... 32,36,40,44,48 |
  svg-pencil-note.jsx     |        0 |      100 |        0 |        0 |... 21,22,26,30,34 |
  svg-user.jsx            |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
 validator                |        0 |        0 |        0 |        0 |                   |
  valid-email.js          |        0 |      100 |        0 |        0 |            6,7,11 |
  valid-file.js           |        0 |        0 |        0 |        0 |       6,7,8,10,15 |
  valid-float.js          |        0 |        0 |        0 |        0 |... 16,17,19,22,27 |
  valid-password.js       |        0 |      100 |        0 |        0 |          10,11,15 |
  valid-string.js         |        0 |        0 |        0 |        0 |          6,7,9,14 |
  valid-url.js            |        0 |      100 |        0 |        0 |            6,7,11 |
--------------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 failed, 3 passed, 4 total
Tests:       14 passed, 14 total
Snapshots:   0 total
Time:        28.456s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test: `NODE_ENV=test jest --config jest.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the reactjs@1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-05-18T02_07_16_291Z-debug.log

For now, I'll stick with this approach. I'll cleanup the mistakes in analysis.test.jsx, then attempt to pipe the results together with the pytest results, in the travis ci.

betancourtl commented 6 years ago

Awesome, almost done.

jeff1evesque commented 6 years ago

All tests succeeded:

root@browserify:/var/machine-learning/src/jsx# npm run test

> reactjs@1.0.0 test /var/machine-learning/src/jsx
> NODE_ENV=test jest --config jest.config.js

 PASS  __tests__/layout/analysis.test.jsx (11.716s)
  AnalysisLayout Component
    ✓ should render without throwing an error (19ms)
    ✓ should render data-new route (113ms)
    ✓ should render data-append route (72ms)
    ✓ should render model-generate route (25ms)
    ✓ should render model-predict route (7ms)
    ✓ should render current-result route (16ms)
    ✓ should render results route (11ms)

 PASS  __tests__/layout/page.test.jsx
  PageLayout Component
    ✓ should render home route (157ms)
    ✓ should render login route (18ms)
    ✓ should render logout route (18ms)
    ✓ should render register route (21ms)
    ✓ should render analysis route (88ms)

 PASS  __tests__/content/register.test.jsx
  Register Component
    ✓ should render without throwing an error (4ms)
    ✓ should render without throwing an error (8ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (2ms)

 PASS  __tests__/content/login.test.jsx
  Login Component
    ✓ should render without throwing an error (3ms)
    ✓ should render without throwing an error (3ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (3ms)

--------------------------|----------|----------|----------|----------|-------------------|
File                      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------------|----------|----------|----------|----------|-------------------|
All files                 |    33.33 |    21.32 |    37.64 |    33.51 |                   |
 animation                |    79.17 |       55 |    64.29 |    79.17 |                   |
  animate.jsx             |    79.17 |       55 |    64.29 |    79.17 |... 34,135,136,139 |
 content                  |    26.85 |    17.44 |       50 |    26.85 |                   |
  home-page.jsx           |      100 |      100 |      100 |      100 |                   |
  login.jsx               |    27.78 |    22.58 |    55.56 |    27.78 |... 46,156,169,183 |
  register.jsx            |    23.91 |    14.55 |    33.33 |    23.91 |... 99,209,219,231 |
 formatter                |        0 |      100 |        0 |        0 |                   |
  transpose.js            |        0 |      100 |        0 |        0 |    47,48,51,52,57 |
 general                  |    35.71 |    15.38 |    27.27 |    36.59 |                   |
  ajax-caller.js          |    53.85 |       50 |       60 |    58.33 |    16,44,46,49,53 |
  breakpoints.js          |      100 |      100 |      100 |      100 |                   |
  colors.js               |      100 |      100 |      100 |      100 |                   |
  range-slider.jsx        |        0 |        0 |        0 |        0 |... 62,63,64,65,67 |
  spinner.jsx             |       50 |      100 |        0 |       50 |                14 |
  submit-button.jsx       |        0 |        0 |        0 |        0 |    23,24,25,26,28 |
 input-data               |        0 |        0 |        0 |        0 |                   |
  supply-dataset-file.jsx |        0 |        0 |        0 |        0 |... 8,90,95,96,113 |
  supply-dataset-url.jsx  |        0 |        0 |        0 |        0 |... 6,88,93,94,112 |
  supply-predictors.jsx   |        0 |        0 |        0 |        0 |... 11,118,119,121 |
 layout                   |    34.21 |    19.51 |    73.33 |    34.21 |                   |
  analysis.jsx            |    30.56 |    19.51 |    69.23 |    30.56 |... 33,234,254,281 |
  login.jsx               |      100 |      100 |      100 |      100 |                   |
  register.jsx            |      100 |      100 |      100 |      100 |                   |
 model                    |       50 |        0 |    66.67 |       50 |                   |
  model-type.jsx          |       50 |        0 |    66.67 |       50 |       27,28,29,31 |
 navigation               |     3.64 |        0 |     6.25 |     3.64 |                   |
  header-menu.jsx         |        0 |        0 |        0 |        0 |... 35,143,150,151 |
  nav-bar.jsx             |      100 |      100 |      100 |      100 |                   |
  user-menu.jsx           |        0 |        0 |        0 |        0 |... 28,229,231,248 |
 navigation/menu-items    |    23.33 |    15.09 |    33.33 |    23.33 |                   |
  current-result.jsx      |       50 |      100 |        0 |       50 |                15 |
  home.jsx                |       50 |      100 |        0 |       50 |                17 |
  login.jsx               |        0 |        0 |        0 |        0 |... 20,123,132,133 |
  register.jsx            |        0 |        0 |        0 |        0 |    25,30,40,44,45 |
  results.jsx             |    52.17 |    44.44 |    83.33 |    52.17 |... 63,64,67,68,92 |
 redux                    |      100 |      100 |      100 |      100 |                   |
  store.jsx               |      100 |      100 |      100 |      100 |                   |
 redux/action             |    23.08 |        0 |       30 |    23.08 |                   |
  current-result.jsx      |        0 |      100 |        0 |        0 |                 7 |
  login.jsx               |        0 |      100 |        0 |        0 |                 7 |
  logout.jsx              |        0 |      100 |        0 |        0 |                 9 |
  page.jsx                |       30 |        0 |    42.86 |       30 |... 26,56,57,62,63 |
 redux/container          |       70 |     38.6 |    68.18 |       70 |                   |
  analysis-layout.jsx     |    63.64 |    33.33 |      100 |    63.64 |... 38,42,43,46,47 |
  current-result.jsx      |       80 |    57.14 |      100 |       80 |             29,30 |
  data-append.jsx         |      100 |      100 |      100 |      100 |                   |
  data-new.jsx            |      100 |      100 |      100 |      100 |                   |
  header-menu.jsx         |    66.67 |      100 |        0 |    66.67 |                18 |
  home-page.jsx           |      100 |      100 |      100 |      100 |                   |
  login-link.jsx          |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
  login.jsx               |     87.5 |       80 |      100 |     87.5 |                22 |
  model-generate.jsx      |      100 |      100 |      100 |      100 |                   |
  model-predict.jsx       |      100 |      100 |      100 |      100 |                   |
  range-slider.jsx        |    66.67 |      100 |        0 |    66.67 |                18 |
  register-link.jsx       |    33.33 |        0 |        0 |    33.33 |       18,19,21,25 |
  register.jsx            |     87.5 |       80 |      100 |     87.5 |                21 |
  results.jsx             |      100 |      100 |      100 |      100 |                   |
  review-results-link.jsx |    66.67 |    57.14 |      100 |    66.67 |             22,23 |
  user-menu.jsx           |     37.5 |        0 |        0 |     37.5 |    19,20,22,26,35 |
 redux/reducer            |    59.52 |     57.5 |      100 |    59.52 |                   |
  data.jsx                |     37.5 |    36.36 |      100 |     37.5 |    17,18,20,22,29 |
  layout.jsx              |     87.5 |    90.91 |      100 |     87.5 |                38 |
  login.jsx               |     62.5 |    55.56 |      100 |     62.5 |          16,23,25 |
  page.jsx                |    55.56 |    44.44 |      100 |    55.56 |... 32,41,43,69,77 |
 result                   |    31.54 |    32.32 |    43.48 |    31.54 |                   |
  current-result.jsx      |    22.11 |    34.15 |    31.25 |    22.11 |... 80,343,346,349 |
  results.jsx             |    57.14 |    23.53 |    71.43 |    57.14 |... 99,114,115,132 |
 route                    |      100 |      100 |      100 |      100 |                   |
  main-route.jsx          |      100 |      100 |      100 |      100 |                   |
  result-route.jsx        |      100 |      100 |      100 |      100 |                   |
  session-route.jsx       |      100 |      100 |      100 |      100 |                   |
 session-type             |    38.46 |    14.38 |    43.75 |    38.46 |                   |
  data-append.jsx         |    43.94 |     18.6 |    46.15 |    43.94 |... 93,196,197,243 |
  data-new.jsx            |    39.62 |     8.33 |       40 |    39.62 |... 32,136,137,153 |
  model-generate.jsx      |    30.38 |    10.64 |    35.71 |    30.38 |... 18,224,230,280 |
  model-predict.jsx       |    41.94 |    22.22 |    54.55 |    41.94 |... 49,154,165,195 |
 svg                      |        0 |        0 |        0 |        0 |                   |
  svg-books.jsx           |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
  svg-home.jsx            |        0 |        0 |        0 |        0 |... 32,36,40,44,48 |
  svg-pencil-note.jsx     |        0 |      100 |        0 |        0 |... 21,22,26,30,34 |
  svg-user.jsx            |        0 |      100 |        0 |        0 |... 20,21,25,29,33 |
 validator                |    10.71 |    21.43 |    16.67 |    10.71 |                   |
  valid-email.js          |        0 |      100 |        0 |        0 |            6,7,11 |
  valid-file.js           |        0 |        0 |        0 |        0 |       6,7,8,10,15 |
  valid-float.js          |        0 |        0 |        0 |        0 |... 16,17,19,22,27 |
  valid-password.js       |        0 |      100 |        0 |        0 |          10,11,15 |
  valid-string.js         |       75 |       75 |      100 |       75 |                 9 |
  valid-url.js            |        0 |      100 |        0 |        0 |            6,7,11 |
--------------------------|----------|----------|----------|----------|-------------------|
Test Suites: 4 passed, 4 total
Tests:       21 passed, 21 total
Snapshots:   0 total
Time:        20.649s
Ran all test suites.

Now, I need to merge the coverage results from jest + pytest, and combine them into to the coveralls implementation of the travis ci, as indicated within the README.md. Also, I need to automate the jest unit tests within each travis ci build. Lastly, I need to update the jest.rst traceback, to take into account the updated test messages.