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.

jeff1evesque commented 6 years ago

We'll begin by creating snapshot tests. This means snapshot tests will be saved within test/jest/test/. After finishing writing the snapshot tests, when we run npm test, or jest, our snapshots will be created under test/__snapshots__/xxx, where xxx would be the corresponding snapshot filename. These snapshots should be committed into this issue. Additionally, we'll need to integrate the jest results, with our current code coverage implementation. So, the corresponding jest coverage results, will need to be merged with our existing pytest coverage.

jeff1evesque commented 6 years ago

Now, we can begin to write our snapshot tests, into the designated directory, and fix any docker related syntax, as well as making necessary adjustments to capture, and copy the corresponding coverage results. Assuming that the docker syntax is correct (both in unit-tests, as well as the respective dockerfiles), we'll need to find out how to merge the pytest results, with the jest coverage.

jeff1evesque commented 6 years ago

da6a87e: we install jest globally, so it'll be in the PATH, and can easily be used via our dockerfile.

jeff1evesque commented 6 years ago

We've decided to write unit tests, instead of snapshot tests, since that was the original intent of this issue. Snapshot testing is a relatively new concept to this repository, and may be integrated at a later time.

jeff1evesque commented 6 years ago

The following is an important statement to keep in mind:

By default, Jest will recursively pick up all files that have a .spec.js or .test.js extension in the entire project. If this does not fit your needs, it's possible to change the testRegex in the config section in the package.json file.

Jest recommends creating a tests directory right next to the code being tested, but feel free to structure your tests as you see fit. Just beware that Jest would create a snapshots directory next to test files that performs snapshot testing.

jeff1evesque commented 6 years ago

Running our jest unit tests produces the following errors:

root@trusty64:/vagrant/test/jest# jest --config jest.config.js
 FAIL  __tests__/content/login.test.jsx
  ● Test suite failed to run

    SyntaxError: Unexpected token {

      at _load_jsdom (../../../usr/lib/node_modules/jest-cli/node_modules/jest-environment-jsdom/build/index.js:17:41)

 FAIL  __tests__/content/register.test.jsx
  ● Test suite failed to run

    SyntaxError: Unexpected token {

      at _load_jsdom (../../../usr/lib/node_modules/jest-cli/node_modules/jest-environment-jsdom/build/index.js:17:41)

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

    SyntaxError: Unexpected token {

      at _load_jsdom (../../../usr/lib/node_modules/jest-cli/node_modules/jest-environment-jsdom/build/index.js:17:41)

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

    SyntaxError: Unexpected token {

      at _load_jsdom (../../../usr/lib/node_modules/jest-cli/node_modules/jest-environment-jsdom/build/index.js:17:41)

----------|----------|----------|----------|----------|----------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
----------|----------|----------|----------|----------|----------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                |
----------|----------|----------|----------|----------|----------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        0.589s
Ran all test suites.
jeff1evesque commented 6 years ago

Now, we are receiving the following error, when running the jest unit tests:

root@trusty64:/vagrant/test/jest# jest --config jest.config.js
 FAIL  __tests__/layout/analysis.test.jsx
  ● Test suite failed to run

    /vagrant/test/jest/__tests__/layout/analysis.test.jsx:6
    import React from 'react';
    ^^^^^^
    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../../usr/lib/node_modules/jest-cli/node_modules/jest-runtime/build/script_transformer.js:318:17)

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

    /vagrant/test/jest/__tests__/layout/page.test.jsx:6
    import React from 'react';
    ^^^^^^
    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../../usr/lib/node_modules/jest-cli/node_modules/jest-runtime/build/script_transformer.js:318:17)

 FAIL  __tests__/content/register.test.jsx
  ● Test suite failed to run

    /vagrant/test/jest/__tests__/content/register.test.jsx:6
    import React from 'react';
    ^^^^^^
    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../../usr/lib/node_modules/jest-cli/node_modules/jest-runtime/build/script_transformer.js:318:17)

 FAIL  __tests__/content/login.test.jsx
  ● Test suite failed to run

    /vagrant/test/jest/__tests__/content/login.test.jsx:6
    import React from 'react';
    ^^^^^^
    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../../usr/lib/node_modules/jest-cli/node_modules/jest-runtime/build/script_transformer.js:318:17)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        16.03s
Ran all test suites.
jeff1evesque commented 6 years ago

Now, we are receiving the following error, when running the jest unit tests:

root@trusty64:/vagrant/test/jest# jest --config jest.config.js
 FAIL  __tests__/content/register.test.jsx
  ● Test suite failed to run

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../../usr/lib/node_modules/jest-cli/node_modules/jest-resolve/build/index.js:194:17)

 FAIL  __tests__/content/login.test.jsx
  ● Test suite failed to run

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../../usr/lib/node_modules/jest-cli/node_modules/jest-resolve/build/index.js:194:17)

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

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../../usr/lib/node_modules/jest-cli/node_modules/jest-resolve/build/index.js:194:17)

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

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../../usr/lib/node_modules/jest-cli/node_modules/jest-resolve/build/index.js:194:17)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        1.992s
Ran all test suites.
jeff1evesque commented 6 years ago

Now, we are receiving the following error, when running the jest unit tests:

root@trusty64:/vagrant/test/jest# jest --config jest.config.js
 FAIL  __tests__/content/register.test.jsx
  ● Test suite failed to run

    /vagrant/test/jest/__tests__/content/register.test.jsx: Unexpected token (12:23)
        10 | describe('Register Component', () => {
        11 |     it('should render without throwing an error', () => {
      > 12 |         expect(shallow(<RegisterForm />).exists(<form ref='registerForm'></form>)).toBe(true)
           |                        ^
        13 |     });
        14 |
        15 |     it('should render a username input', () => {

 FAIL  __tests__/content/login.test.jsx
  ● Test suite failed to run

    /vagrant/test/jest/__tests__/content/login.test.jsx: Unexpected token (12:23)
        10 | describe('Login Component', () => {
        11 |     it('should render without throwing an error', () => {
      > 12 |         expect(shallow(<LoginForm />).exists(<form ref='loginForm'></form>)).toBe(true)
           |                        ^
        13 |     });
        14 |
        15 |     it('should render an email input', () => {

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

    /vagrant/test/jest/__tests__/layout/analysis.test.jsx: Unexpected token (19:23)
        17 | describe('AnalysisLayout Component', () => {
        18 |     it('should render without throwing an error', () => {
      > 19 |         expect(shallow(<AnalysisLayout />).exists(<form ref='analysisForm'></form>)).toBe(true)
           |                        ^
        20 |     });
        21 |
        22 |     it('should render correct routes', () => {

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

    /vagrant/test/jest/__tests__/layout/page.test.jsx: Unexpected token (18:32)
        16 | describe('PageLayout Component', () => {
        17 |     it('should render correct routes', () => {
      > 18 |         const wrapper = shallow(<PageLayout />);
           |                                 ^
        19 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
        20 |             const routeProps = route.props();
        21 |             pathMap[routeProps.path] = routeProps.component;

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |  Unknown |  Unknown |  Unknown |  Unknown |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        3.782s
Ran all test suites.
jeff1evesque commented 6 years ago

We are having some difficulties, since the jest packages rely on symlinking various binaries. However, we cannot implement symlinks within the mounted /vagrant directory within the vagrant virtual machine. As, a workaround, we installed jest related packages globally, via npm install -g [PACKAGE]. This partially works, until the globally installed packages need to reference various already installed packages within the /vagrant/src/node_modules directory. So, we need to think of a better way to implement jest unit testing, or we need to reconsider an adjusted development environment.

jeff1evesque commented 6 years ago

We'll replace our current vagrant puppet environment with docker containers, with respect to the strategy outlined in #2935. Once completed, we'll be able to remove the puppet vagrant environment, and proceed with this issue, with an updated development infrastructure, which should be less constrained on symlinking mounted directories.

jeff1evesque commented 6 years ago

Since not all instances of our webserver-xxx containers will need the jest-cli package installed, we'll conditionally install this npm package, via the ENTRYPOINT. Specifically, we'll pass an argument to the corresponding bash script, if we want to install jest-cli.

jeff1evesque commented 6 years ago

57ae6ea: in our case, each npm installed package, will likely relate to the frontend use. Therefore, it is more appropriate, to remove the generalization of the nodejs installation from the system, to the webserver custom puppet module. This will better segregate the installation of packages, across multiple containers.

jeff1evesque commented 6 years ago

477079b: actually, npm packages will generally relate to the process of compiling, minifying, linting, or unit testing. Specifically, these processes will not reside in our non-development environments. Therefore, it is fair to relocate the installation of jest-cli in our package.json.

jeff1evesque commented 6 years ago

We are receiving similar errors, as indicated earlier, in our browserify container:

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

> reactjs@1.0.0 test:jest /var/machine-learning/src
> jest --config /var/machine-learning/test/jest/jest.config.js

 FAIL  ../test/jest/__tests__/content/login.test.jsx
  ● Test suite failed to run

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../src/node_modules/jest-resolve/build/index.js:169:17)

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

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../src/node_modules/jest-resolve/build/index.js:169:17)

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

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../src/node_modules/jest-resolve/build/index.js:169:17)

 FAIL  ../test/jest/__tests__/content/register.test.jsx
  ● Test suite failed to run

    Cannot find module 'expect' from 'jest_expect.js'

      at Resolver.resolveModule (../../src/node_modules/jest-resolve/build/index.js:169:17)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |        0 |        0 |        0 |        0 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        1.94s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test:jest: `jest --config /var/machine-learning/test/jest/jest.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the reactjs@1.0.0 test:jest 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-06T21_00_37_304Z-debug.log

Note: we should indicate in our documentation, that our jest unit tests, need to be executed via the npm run test:jest command, from our browserify container.

jeff1evesque commented 6 years ago

We are now receiving SyntaxError: Unexpected token import:

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

> reactjs@1.0.0 test:jest /var/machine-learning/src
> jest --config /var/machine-learning/test/jest/jest.config.js

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

    /var/machine-learning/test/jest/__tests__/layout/analysis.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

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

    /var/machine-learning/test/jest/__tests__/layout/page.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

 FAIL  ../test/jest/__tests__/content/register.test.jsx
  ● Test suite failed to run

    /var/machine-learning/test/jest/__tests__/content/register.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

 FAIL  ../test/jest/__tests__/content/login.test.jsx
  ● Test suite failed to run

    /var/machine-learning/test/jest/__tests__/content/login.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |        0 |        0 |        0 |        0 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        1.387s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test:jest: `jest --config /var/machine-learning/test/jest/jest.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the reactjs@1.0.0 test:jest 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-06T23_46_28_300Z-debug.log
betancourtl commented 6 years ago

Do tests need to be run through babel before being executed?

jeff1evesque commented 6 years ago

I've configured another script in the package.json, which uses babelify, and a few presets. That's working as expected. So, I'm wondering if jest needs to be notified to use the same babelify, and corresponding presets? Or, if we should simply run browserify beforehand, to ensure jsx gets transpiled and compiled to js, before we run jest. I tried adding a .babelrc in the same directory where the package.json resides, with no luck:

{
  "env": {
    "test": {
      "presets": ["env", "stage-2", "react"]
    }
  }
}

This is the directory structure, which the browserify container reorders content:

The following is the jest.config.js configurations:

module.exports = {
  'collectCoverage': true,
  'coverageDirectory': '/var/machine-learning',
  'moduleDirectories': ['/var/machine-learning/src/node_modules'],
  'verbose': true
}
jeff1evesque commented 6 years ago

When using the above .babelrc, I adjusted the scripts in the package.json:

[...OMITTED-CONTENT...]
  "scripts": {
    "build:browserify": "browserify -t [ babelify --presets env,stage-2,react ] /var/machine-learning/src/jsx/content.jsx > /var/machine-learning/interface/static/js/content.js",
    "prebuild:dos2unix": "find /var/machine-learning/src/jsx -type f -print0 | xargs -0 dos2unix",
    "watch:jsx": "onchange '/var/machine-learning/src/jsx/**/*.jsx' '/var/machine-learning/src/jsx/**/*.js' -- npm run build:browserify",
    "test": "NODE_ENV=test jest --config /var/machine-learning/test/jest/jest.config.js"
  },
[...OMITTED-CONTENT...]
ljharb commented 6 years ago

The presets should only be in babelrc; that’s what jest and babel both use. You shouldn’t need browserify to run tests.

jeff1evesque commented 6 years ago

How should I define the .babelrc? Is there anything currently in the package.json that I should change?

jeff1evesque commented 6 years ago

I tried earlier the following .babelrc:

{
  "env": {
    "test": {
      "presets": ["env", "stage-2", "react"]
    }
  }
}

But, does my script in the package.json need to reference the test environment (is the env needed):

"test": "jest --config /var/machine-learning/test/jest/jest.config.js"

Also, do I need a jest directive in the package.json?

ljharb commented 6 years ago

no, the environment is set with the NODE_ENV environment variable.

You need a jest config somewhere - if you're passing in a path to jest.config.js, then you don't need it in package.json, and vice versa.

jeff1evesque commented 6 years ago

59a907a: @ljharb, I made the changes you suggested. But, upon running npm run test:

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

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

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

    /var/machine-learning/test/jest/__tests__/layout/analysis.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

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

    /var/machine-learning/test/jest/__tests__/layout/page.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

 FAIL  ../test/jest/__tests__/content/register.test.jsx
  ● Test suite failed to run

    /var/machine-learning/test/jest/__tests__/content/register.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

 FAIL  ../test/jest/__tests__/content/login.test.jsx
  ● Test suite failed to run

    /var/machine-learning/test/jest/__tests__/content/login.test.jsx:6
    import React from 'react';
    ^^^^^^

    SyntaxError: Unexpected token import

      at ScriptTransformer._transformAndBuildScript (../../src/node_modules/jest-runtime/build/script_transformer.js:316:17)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |        0 |        0 |        0 |        0 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        1.623s
Ran all test suites.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! reactjs@1.0.0 test: `NODE_ENV=test jest --config /var/machine-learning/test/jest/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-09T20_49_34_439Z-debug.log

I double checked all the configurations are where they are supposed to be:

root@browserify:/var/machine-learning/src# ls -l /var/machine-learning/test/jest
total 20
drwxrwxrwx 4 root root 4096 May  5 22:20 __tests__
-rwxrwxrwx 1 root root  410 May  6 21:00 clover.xml
-rwxrwxrwx 1 root root    3 May  6 21:00 coverage-final.json
-rwxrwxrwx 1 root root  411 May  8 23:45 jest.config.js
drwxrwxrwx 2 root root 4096 May  6 20:55 lcov-report
-rwxrwxrwx 1 root root    0 May  6 21:00 lcov.info
root@browserify:/var/machine-learning/src# ls -lAZ
total 316
-rwxrwxrwx   1 root root ?     91 May  9 19:05 .babelrc
-rwx--x---   1 root root ?     82 May  9 20:42 entrypoint
drwxr-xr-x   1 root root ?   4096 May  9 20:40 jsx
drwxr-xr-x 693 root root ?  20480 May  9 20:41 node_modules
-rw-r--r--   1 root root ? 286037 May  9 20:41 package-lock.json
-rwxrwxrwx   1 root root ?   1557 May  9 20:41 package.json
ljharb commented 6 years ago

This presumes your .babelrc is correct, and that you have babel-jest installed.

If it's still not working at that point, I'd file an issue on jest.

rickhanlonii commented 6 years ago

@jeff1evesque happy to help on this - can you give me some instructions on how to run?

It looks like this is designed to be run inside a container? If I were to guess, the .babelrc file is not mounted in the correct location for babel-jest to find it. Also, is there is reason you're using jest-cli instead of jest in your package.json?

jeff1evesque commented 6 years ago

@rickhanlonii, i'd like to first say thank you for your assistance. Secondly, you're exactly correct. The overall jest implementation is designed to be run in a container, where files are copied from the git clone on the host, into the browserify container. I would like to blame my inexperience for using jest-cli instead of jest, in my package.json. I'm not sure currently what the difference are between the two.

The following are the commands to run the jest script within the browserify container:

## clone repository
git clone https://github.com/jeff1evesque/machine-learning
cd machine-learning
## checkout hash: https://github.com/jeff1evesque/machine-learning/issues/3087#ref-commit-59a907a
git checkout 59a907a 
## build container: automate container with package.json dependencies
docker build -f dockerfile/browserify.dockerfile -t jeff1evesque/ml-browserify:0.7 .
docker run --hostname browserify --name browserify -d jeff1evesque/ml-browserify:0.7
docker exec -it browserify /bin/bash
## run jest
root@browserify:/var/machine-learning/src# npm run test

Note: I'm not 100% sure if the git checkout 59a907a is correct, or if the hash needs to be fully explicit.

rickhanlonii commented 6 years ago

Ok great, I'm able to reproduce but wasn't able to track down the issue. Will let you know what I find, but @jeff1evesque is it possible to co-locate your tests/jest config within the same dir?

There's a bit of redirection here:

- test/
  - jest/
    - __tests__/
    - jest.config.js
- src/
  - jsx/
    - node_modules (contains jest and babel)
    - .babelrc (how should we know to use this?)
    - package.json (points to ../../test/jest/jest.config.js)

a better structure may be:

- src/
  - jsx/
    - node_modules
    - tests/ (this could be just in __tests__ along side the source files)
    - .babelrc
    - jest.config.js
    - package.json
jeff1evesque commented 6 years ago

@rickhanlonii, coupled with general changes, along with your suggested directory structure:

root@browserify:/var/machine-learning/src/jsx# ls -lAZ
total 364
-rwxrwxrwx 1 root root ?     84 May 10 23:22 .babelrc
-rwxrwxrwx 1 root root ?   1013 May 10 23:22 README.md
-rwxrwxrwx 1 root root ?   1291 May 10 23:22 content.jsx
-rwx--x--- 1 root root ?     82 May 10 23:21 entrypoint
drwxrwxrwx 1 root root ?   4096 Mar 26 04:34 import
-rwxrwxrwx 1 root root ?    195 May 10 23:22 jest.config.js
drwxr-xr-x 1 root root ?  36864 May 10 23:20 node_modules
-rw-r--r-- 1 root root ? 296304 May 10 23:22 package-lock.json
-rwxrwxrwx 1 root root ?   1455 May 10 23:22 package.json
drwxr-xr-x 1 root root ?   4096 May 10 23:20 tests

I was able to make progress running npm run test:

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/__tests__/layout/analysis.test.jsx
  ● Test suite failed to run

    Cannot find module '../../../../src/jsx/import/layout/analysis.jsx' from 'analysis.test.jsx'

       7 | import { shallow } from 'enzyme';
       8 | import AnalysisLayout from '../../../../src/jsx/import/layout/analysis.jsx';
    >  9 | import DataNewState from '../../../../src/jsx/import/redux/container/data-new.jsx';
      10 | import DataAppendState from '../../../../src/jsx/import/redux/container/data-append.jsx';
      11 | import ModelGenerateState from '../../../../src/jsx/import/redux/container/model-generate.jsx';
      12 | import ModelPredictState from '../../../../src/jsx/import/redux/container/model-predict.jsx';

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (tests/__tests__/layout/analysis.test.jsx:9:17)

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

    Cannot find module '../../../../src/jsx/import/layout/page.jsx' from 'page.test.jsx'

       7 | import { shallow } from 'enzyme';
       8 | import PageLayout from '../../../../src/jsx/import/layout/page.jsx';
    >  9 | import HomePageState from '../../../src/jsx/import/redux/container/home-page.jsx';
      10 | import UserMenuState from '../../../src/jsx/import/redux/container/user-menu.jsx';
      11 | import HeaderMenuState from '../../../src/jsx/import/redux/container/header-menu.jsx';
      12 | import AnalysisLayoutState from '../../../src/jsx/import/redux/container/analysis-layout.jsx';

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (tests/__tests__/layout/page.test.jsx:9:13)

 FAIL  tests/__tests__/content/register.test.jsx
  ● Test suite failed to run

    Cannot find module '../../../../src/jsx/import/content/register.jsx' from 'register.test.jsx'

       7 | import { shallow } from 'enzyme';
       8 | import RegisterForm from '../../../../src/jsx/import/content/register.jsx'
    >  9 |
      10 | describe('Register Component', () => {
      11 |     it('should render without throwing an error', () => {
      12 |         expect(shallow(<RegisterForm />).exists(<form ref='registerForm'></form>)).toBe(true)

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (tests/__tests__/content/register.test.jsx:9:17)

 FAIL  tests/__tests__/content/login.test.jsx
  ● Test suite failed to run

    Cannot find module '../../../../src/jsx/import/content/login.jsx' from 'login.test.jsx'

       7 | import { shallow } from 'enzyme';
       8 | import LoginForm from '../../../../src/jsx/import/content/login.jsx'
    >  9 |
      10 | describe('Login Component', () => {
      11 |     it('should render without throwing an error', () => {
      12 |         expect(shallow(<LoginForm />).exists(<form ref='loginForm'></form>)).toBe(true)

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (tests/__tests__/content/login.test.jsx:9:14)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |        0 |        0 |        0 |        0 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 4 failed, 4 total
Tests:       0 total
Snapshots:   0 total
Time:        7.987s
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-10T23_22_14_355Z-debug.log

I'm not sure why jest cannot interpret the relative import paths. The same relative import paths are used for the main application, which renders without any related errors.

jeff1evesque commented 6 years ago

I've further restructured the directories within the browserify container:

root@browserify:/var/machine-learning/src/jsx# ls -lAZ
total 364
-rwxrwxrwx 1 root root ?     84 May 12 01:04 .babelrc
-rwxrwxrwx 1 root root ?   1013 May 12 01:04 README.md
drwxr-xr-x 1 root root ?   4096 May 12 01:02 __tests__
-rwxrwxrwx 1 root root ?   1291 May 12 01:04 content.jsx
-rwx--x--- 1 root root ?     82 May 12 01:04 entrypoint
drwxrwxrwx 1 root root ?   4096 Mar 26 04:34 import
-rwxrwxrwx 1 root root ?    207 May 12 01:04 jest.config.js
drwxr-xr-x 1 root root ?  36864 May 12 01:02 node_modules
-rw-r--r-- 1 root root ? 296307 May 12 01:04 package-lock.json
-rwxrwxrwx 1 root root ?   1455 May 12 01:04 package.json

Now, the jest unit tests fails with the following:

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
  AnalysisLayout Component
    ✕ should render without throwing an error (11ms)
    ✕ should render correct routes (1ms)

  ● AnalysisLayout Component › should render without throwing an error

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      17 | describe('AnalysisLayout Component', () => {
      18 |     it('should render without throwing an error', () => {
    > 19 |         expect(shallow(<AnalysisLayout />).exists(<form ref='analysisForm'></form>)).toBe(true)
      20 |     });
      21 |
      22 |     it('should render correct routes', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/layout/analysis.test.jsx:19:16)

  ● AnalysisLayout Component › should render correct routes

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      21 |
      22 |     it('should render correct routes', () => {
    > 23 |         const wrapper = shallow(<AnalysisLayout />);
      24 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
      25 |             const routeProps = route.props();
      26 |             pathMap[routeProps.path] = routeProps.component;

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/layout/analysis.test.jsx:23:25)

 FAIL  __tests__/content/register.test.jsx
  Register Component
    ✕ should render without throwing an error (4ms)
    ✕ should render a username input
    ✕ should render an email input (1ms)
    ✕ should render a password input
    ✕ should render a submit input (1ms)

  ● Register Component › should render without throwing an error

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      10 | describe('Register Component', () => {
      11 |     it('should render without throwing an error', () => {
    > 12 |         expect(shallow(<RegisterForm />).exists(<form ref='registerForm'></form>)).toBe(true)
      13 |     });
      14 |
      15 |     it('should render a username input', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:12:16)

  ● Register Component › should render a username input

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      14 |
      15 |     it('should render a username input', () => {
    > 16 |         expect(shallow(<RegisterForm />).find('[name="user[login]"]').length).toEqual(1)
      17 |     });
      18 |
      19 |     it('should render an email input', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:16:16)

  ● Register Component › should render an email input

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      18 |
      19 |     it('should render an email input', () => {
    > 20 |         expect(shallow(<RegisterForm />).find('[name="user[email]"]').length).toEqual(1)
      21 |     });
      22 |
      23 |     it('should render a password input', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:20:16)

  ● Register Component › should render a password input

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      22 |
      23 |     it('should render a password input', () => {
    > 24 |         expect(shallow(<RegisterForm />).find('[name="user[password]"]').length).toEqual(1)
      25 |     });
      26 |
      27 |     it('should render a submit input', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:24:16)

  ● Register Component › should render a submit input

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      26 |
      27 |     it('should render a submit input', () => {
    > 28 |         expect(shallow(<RegisterForm />).find('[type="submit"]').length).toEqual(1)
      29 |     });
      30 | });
      31 |

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:28:16)

 FAIL  __tests__/content/login.test.jsx
  Login Component
    ✕ should render without throwing an error (4ms)
    ✕ should render an email input (1ms)
    ✕ should render a password input
    ✕ should render a submit input (1ms)

  ● Login Component › should render without throwing an error

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      10 | describe('Login Component', () => {
      11 |     it('should render without throwing an error', () => {
    > 12 |         expect(shallow(<LoginForm />).exists(<form ref='loginForm'></form>)).toBe(true)
      13 |     });
      14 |
      15 |     it('should render an email input', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:12:16)

  ● Login Component › should render an email input

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      14 |
      15 |     it('should render an email input', () => {
    > 16 |         expect(shallow(<LoginForm />).find('[name="user[login]"]').length).toEqual(1)
      17 |     });
      18 |
      19 |     it('should render a password input', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:16:16)

  ● Login Component › should render a password input

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      18 |
      19 |     it('should render a password input', () => {
    > 20 |         expect(shallow(<LoginForm />).find('[name="user[password]"]').length).toEqual(1)
      21 |     });
      22 |
      23 |     it('should render a submit input', () => {

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:20:16)

  ● Login Component › should render a submit input

          Enzyme Internal Error: Enzyme expects an adapter to be configured, but found none. To
          configure an adapter, you should call `Enzyme.configure({ adapter: new Adapter() })`
          before using any of Enzyme's top level APIs, where `Adapter` is the adapter
          corresponding to the library currently being tested. For example:

          import Adapter from 'enzyme-adapter-react-15';

          To find out more about this, see http://airbnb.io/enzyme/docs/installation/index.html

      22 |
      23 |     it('should render a submit input', () => {
    > 24 |         expect(shallow(<LoginForm />).find('[type="submit"]').length).toEqual(1)
      25 |     });
      26 | });
      27 |

      at validateAdapter (node_modules/enzyme/build/validateAdapter.js:14:11)
      at getAdapter (node_modules/enzyme/build/Utils.js:76:36)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:117:44)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:24:16)

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

    Cannot find module '../../../src/jsx/import/redux/container/home-page.jsx' from 'page.test.jsx'

      11 | import HeaderMenuState from '../../../src/jsx/import/redux/container/header-menu.jsx';
      12 | import AnalysisLayoutState from '../../../src/jsx/import/redux/container/analysis-layout.jsx';
    > 13 | import LoginLayout from '../../../src/jsx/import/layout/login.jsx';
      14 | import RegisterLayout from '../../../src/jsx/import/layou/register.jsx';
      15 |
      16 | describe('PageLayout Component', () => {

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:13:17)

--------------------------|----------|----------|----------|----------|-------------------|
File                      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------------|----------|----------|----------|----------|-------------------|
All files                 |     2.99 |        0 |        0 |     3.01 |                   |
 content                  |        0 |        0 |        0 |        0 |                   |
  login.jsx               |        0 |        0 |        0 |        0 |... 73,177,183,186 |
  register.jsx            |        0 |        0 |        0 |        0 |... 27,231,233,236 |
 formatter                |        0 |      100 |        0 |        0 |                   |
  transpose.js            |        0 |      100 |        0 |        0 |    47,48,51,52,57 |
 general                  |    17.07 |        0 |        0 |     17.5 |                   |
  ajax-caller.js          |        0 |        0 |        0 |        0 |... 46,49,53,57,63 |
  breakpoints.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                   |        0 |        0 |        0 |        0 |                   |
  analysis.jsx            |        0 |        0 |        0 |        0 |... 51,352,353,359 |
 model                    |        0 |        0 |        0 |        0 |                   |
  model-type.jsx          |        0 |        0 |        0 |        0 |... 27,28,29,31,37 |
 navigation               |       50 |      100 |        0 |       50 |                   |
  nav-bar.jsx             |       50 |      100 |        0 |       50 |                12 |
 navigation/menu-items    |        4 |        0 |        0 |        4 |                   |
  current-result.jsx      |       50 |      100 |        0 |       50 |                15 |
  results.jsx             |        0 |        0 |        0 |        0 |... 92,102,106,107 |
 redux/action             |        0 |        0 |        0 |        0 |                   |
  current-result.jsx      |        0 |      100 |        0 |        0 |                 7 |
  login.jsx               |        0 |      100 |        0 |        0 |                 7 |
  page.jsx                |        0 |        0 |        0 |        0 |... 49,56,57,62,63 |
 redux/container          |       50 |        0 |        0 |       50 |                   |
  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 |
  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 |
  results.jsx             |    66.67 |      100 |        0 |    66.67 |                18 |
  review-results-link.jsx |    33.33 |        0 |        0 |    33.33 |       17,22,23,27 |
 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 |
 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 |
 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: 4 failed, 4 total
Tests:       11 failed, 11 total
Snapshots:   0 total
Time:        3.544s, estimated 14s
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-12T01_06_45_512Z-debug.log
betancourtl commented 6 years ago

Did you install the enzyme adapter?

betancourtl commented 6 years ago

I have a file like this on my personal project, which jest reads from the package.json file

test-setup.js

import Enzyme, { shallow, render, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';

Enzyme.configure({ adapter: new Adapter() });

// Make Enzyme functions available in all test files without importing
global.shallow = shallow;
global.render = render;
global.mount = mount;
global.React = React;

Here is my package.json file

{
  "name": "webdeveloperpr-blog",
  "version": "1.0.0",
  "description": "webdeveloperpr-blog",
  "main": "index.js",
  "scripts": {
    "dev": "if [[ -e .env ]]; then . .env; fi && if [[ -e .env.dev ]]; then . .env.dev; fi && nodemon ./server/index.js --watch ./server",
    "prod": "if [[ -e .env ]]; then . .env; fi && if [[ -e .env.prod ]]; then . .env.prod; fi && npm run build && node ./server/index.js",
    "build": "if [[ -e .env ]]; then . .env; fi && if [[ -e .env.prod ]]; then . .env.prod; fi && webpack -p --config ./config/webpack.prod.js",
    "test-client": "jest --watch",
    "test-server": "if [[ -e .env ]]; then . .env; fi && if [[ -e .env.test ]]; then . .env.test; fi && nodemon --exec 'mocha'",
    "docker:remove": "docker rm /webdeveloperpr-blog",
    "docker:build": "docker build -t webdeveloperpr/webdeveloperpr-blog .",
    "docker:prod": "docker run --name webdeveloperpr-blog -p 80:80 -e NODE_ENV=production webdeveloperpr/webdeveloperpr-blog",
    "docker:build:prod": "npm run docker:remove & npm run docker:build &&  npm run docker:prod",
    "knex:dev": "if [[ -e .env ]]; then . .env; fi && if [[ -e .env.dev ]]; then . .env.dev; fi && knex",
    "knex:prod": "if [[ -e .env ]]; then . .env; fi && if [[ -e .env.prod ]]; then . .env.prod; fi && knex"
  },
  "keywords": [
    "webpack",
    "webdeveloperpr-blog"
  ],
  "author": "Luis Betancourt <webdeveloperpr@gmail.com> (https://github.com/webdeveloperpr)",
  "license": "MIT",
  "dependencies": {
    "axios": "0.17.1",
    "bcrypt-nodejs": "0.0.3",
    "body-parser": "^1.18.2",
    "classnames": "2.2.5",
    "countryjs": "1.8.0",
    "draft-js": "^0.10.5",
    "draft-js-raw-content-state": "^1.2.7",
    "express": "^4.16.2",
    "google-libphonenumber": "3.0.10",
    "immutable": "^3.8.2",
    "jsonwebtoken": "8.1.1",
    "knex": "^0.14.4",
    "lodash.debounce": "^4.0.8",
    "mailgun-js": "^0.16.0",
    "mobx": "^4.1.0",
    "mobx-react": "^5.0.0",
    "mobx-react-form": "^1.34.0",
    "moment": "^2.22.1",
    "mysql": "^2.15.0",
    "prop-types": "15.6.0",
    "ramda": "^0.25.0",
    "react": "16.2.0",
    "react-bootstrap": "^0.32.1",
    "react-dom": "16.2.0",
    "react-ga": "^2.5.0",
    "react-router-dom": "^4.2.2",
    "sinon": "^4.5.0",
    "slug": "^0.9.1",
    "validatorjs": "^3.14.2"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-beta.42",
    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.42",
    "@babel/plugin-proposal-decorators": "^7.0.0-beta.42",
    "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.42",
    "@babel/preset-env": "^7.0.0-beta.42",
    "@babel/preset-react": "^7.0.0-beta.42",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "22.1.0",
    "babel-loader": "8.0.0-beta.0",
    "babel-polyfill": "6.26.0",
    "chai": "4.1.2",
    "clean-webpack-plugin": "0.1.17",
    "css-loader": "0.28.7",
    "enzyme": "3.3.0",
    "enzyme-adapter-react-16": "1.1.1",
    "eslint": "4.17.0",
    "extract-text-webpack-plugin": "3.0.2",
    "file-loader": "1.1.6",
    "html-webpack-plugin": "^3.2.0",
    "image-webpack-loader": "3.4.2",
    "jest": "22.1.4",
    "mocha": "5.0.0",
    "node-sass": "4.7.2",
    "nodemon": "1.12.1",
    "regenerator-runtime": "0.11.1",
    "sass-loader": "6.0.6",
    "style-loader": "0.19.0",
    "supertest": "3.0.0",
    "webpack": "^4.6.0",
    "webpack-dev-middleware": "1.12.2",
    "webpack-hot-middleware": "2.21.0"
  },
  "jest": {
    "setupFiles": [
      "./config/jest/test-setup.js" // test file above being loaded
    ],
    "roots": [
      "<rootDir>/client"
    ]
  }
}
betancourtl commented 6 years ago

BTW I have no idea how I ended up in this repo.

jeff1evesque commented 6 years ago

@webdeveloperpr, I'm not sure either. But, thanks for the suggestions. They seem to be improving my situation. The errors now have become more verbose, and maybe less of a jest problem?

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 (15.033s)
  AnalysisLayout Component
    ✕ should render without throwing an error (92ms)
    ✕ should render correct routes (10ms)

  ● AnalysisLayout Component › should render without throwing an error

    TypeError: this.props.dispatchLayout is not a function

      77 |         // update redux store: define overall page layout
      78 |         const action = setLayout({ layout: 'analysis' });
    > 79 |         this.props.dispatchLayout(action);
      80 |     }
      81 |
      82 |     componentWillReceiveProps(nextProps) {

      at AnalysisLayout.componentWillMount (import/layout/analysis.jsx:79:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/layout/analysis.test.jsx:22:16)

  ● AnalysisLayout Component › should render correct routes

    TypeError: this.props.dispatchLayout is not a function

      77 |         // update redux store: define overall page layout
      78 |         const action = setLayout({ layout: 'analysis' });
    > 79 |         this.props.dispatchLayout(action);
      80 |     }
      81 |
      82 |     componentWillReceiveProps(nextProps) {

      at AnalysisLayout.componentWillMount (import/layout/analysis.jsx:79:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/layout/analysis.test.jsx:26:25)

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

    Cannot find module '../../../src/jsx/import/redux/container/home-page.jsx' from 'page.test.jsx'

      17 | Enzyme.configure({ adapter: new Adapter() });
      18 |
    > 19 | describe('PageLayout Component', () => {
      20 |     it('should render correct routes', () => {
      21 |         const wrapper = shallow(<PageLayout />);
      22 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:19:17)

 FAIL  __tests__/content/register.test.jsx
  Register Component
    ✕ should render without throwing an error (41ms)
    ✕ should render a username input (1ms)
    ✕ should render an email input (1ms)
    ✕ should render a password input (8ms)
    ✕ should render a submit input (2ms)

  ● Register Component › should render without throwing an error

    TypeError: this.props.dispatchLayout is not a function

      49 |         // update redux store
      50 |         const action = setLayout({ layout: 'register' });
    > 51 |         this.props.dispatchLayout(action);
      52 |     }
      53 |
      54 |     // send form data to serverside on form submission

      at RegisterForm.componentWillMount (import/content/register.jsx:51:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:15:16)

  ● Register Component › should render a username input

    TypeError: this.props.dispatchLayout is not a function

      49 |         // update redux store
      50 |         const action = setLayout({ layout: 'register' });
    > 51 |         this.props.dispatchLayout(action);
      52 |     }
      53 |
      54 |     // send form data to serverside on form submission

      at RegisterForm.componentWillMount (import/content/register.jsx:51:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:19:16)

  ● Register Component › should render an email input

    TypeError: this.props.dispatchLayout is not a function

      49 |         // update redux store
      50 |         const action = setLayout({ layout: 'register' });
    > 51 |         this.props.dispatchLayout(action);
      52 |     }
      53 |
      54 |     // send form data to serverside on form submission

      at RegisterForm.componentWillMount (import/content/register.jsx:51:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:23:16)

  ● Register Component › should render a password input

    TypeError: this.props.dispatchLayout is not a function

      49 |         // update redux store
      50 |         const action = setLayout({ layout: 'register' });
    > 51 |         this.props.dispatchLayout(action);
      52 |     }
      53 |
      54 |     // send form data to serverside on form submission

      at RegisterForm.componentWillMount (import/content/register.jsx:51:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:27:16)

  ● Register Component › should render a submit input

    TypeError: this.props.dispatchLayout is not a function

      49 |         // update redux store
      50 |         const action = setLayout({ layout: 'register' });
    > 51 |         this.props.dispatchLayout(action);
      52 |     }
      53 |
      54 |     // send form data to serverside on form submission

      at RegisterForm.componentWillMount (import/content/register.jsx:51:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/register.test.jsx:31:16)

 FAIL  __tests__/content/login.test.jsx
  Login Component
    ✕ should render without throwing an error (41ms)
    ✕ should render an email input (8ms)
    ✕ should render a password input
    ✕ should render a submit input (1ms)

  ● Login Component › should render without throwing an error

    TypeError: this.props.dispatchLayout is not a function

      45 |     componentWillMount() {
      46 |         // update redux store
    > 47 |         this.props.dispatchLayout(setLayout({ layout: 'login' }));
      48 |     }
      49 |
      50 |     componentDidMount() {

      at LoginForm.componentWillMount (import/content/login.jsx:47:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:15:16)

  ● Login Component › should render an email input

    TypeError: this.props.dispatchLayout is not a function

      45 |     componentWillMount() {
      46 |         // update redux store
    > 47 |         this.props.dispatchLayout(setLayout({ layout: 'login' }));
      48 |     }
      49 |
      50 |     componentDidMount() {

      at LoginForm.componentWillMount (import/content/login.jsx:47:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:19:16)

  ● Login Component › should render a password input

    TypeError: this.props.dispatchLayout is not a function

      45 |     componentWillMount() {
      46 |         // update redux store
    > 47 |         this.props.dispatchLayout(setLayout({ layout: 'login' }));
      48 |     }
      49 |
      50 |     componentDidMount() {

      at LoginForm.componentWillMount (import/content/login.jsx:47:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:23:16)

  ● Login Component › should render a submit input

    TypeError: this.props.dispatchLayout is not a function

      45 |     componentWillMount() {
      46 |         // update redux store
    > 47 |         this.props.dispatchLayout(setLayout({ layout: 'login' }));
      48 |     }
      49 |
      50 |     componentDidMount() {

      at LoginForm.componentWillMount (import/content/login.jsx:47:20)
      at ReactShallowRenderer._mountClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:174:26)
      at ReactShallowRenderer.render (node_modules/react-test-renderer/cjs/react-test-renderer-shallow.development.js:135:14)
      at node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:287:35
      at withSetStateAllowed (node_modules/enzyme-adapter-utils/build/Utils.js:94:16)
      at Object.render (node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:286:68)
      at new ShallowWrapper (node_modules/enzyme/build/ShallowWrapper.js:119:22)
      at shallow (node_modules/enzyme/build/shallow.js:19:10)
      at Object.<anonymous> (__tests__/content/login.test.jsx:27:16)

--------------------------|----------|----------|----------|----------|-------------------|
File                      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------------|----------|----------|----------|----------|-------------------|
All files                 |     5.52 |        0 |     3.78 |     5.56 |                   |
 content                  |     9.59 |        0 |    22.22 |     9.59 |                   |
  login.jsx               |    11.11 |        0 |    22.22 |    11.11 |... 73,177,183,186 |
  register.jsx            |      8.7 |        0 |    22.22 |      8.7 |... 27,231,233,236 |
 formatter                |        0 |      100 |        0 |        0 |                   |
  transpose.js            |        0 |      100 |        0 |        0 |    47,48,51,52,57 |
 general                  |    17.07 |        0 |        0 |     17.5 |                   |
  ajax-caller.js          |        0 |        0 |        0 |        0 |... 46,49,53,57,63 |
  breakpoints.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                   |     9.72 |        0 |    15.38 |     9.72 |                   |
  analysis.jsx            |     9.72 |        0 |    15.38 |     9.72 |... 51,352,353,359 |
 model                    |        0 |        0 |        0 |        0 |                   |
  model-type.jsx          |        0 |        0 |        0 |        0 |... 27,28,29,31,37 |
 navigation               |       50 |      100 |        0 |       50 |                   |
  nav-bar.jsx             |       50 |      100 |        0 |       50 |                12 |
 navigation/menu-items    |        4 |        0 |        0 |        4 |                   |
  current-result.jsx      |       50 |      100 |        0 |       50 |                15 |
  results.jsx             |        0 |        0 |        0 |        0 |... 92,102,106,107 |
 redux/action             |     8.33 |        0 |    11.11 |     8.33 |                   |
  current-result.jsx      |        0 |      100 |        0 |        0 |                 7 |
  login.jsx               |        0 |      100 |        0 |        0 |                 7 |
  page.jsx                |       10 |        0 |    14.29 |       10 |... 49,56,57,62,63 |
 redux/container          |       50 |        0 |        0 |       50 |                   |
  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 |
  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 |
  results.jsx             |    66.67 |      100 |        0 |    66.67 |                18 |
  review-results-link.jsx |    33.33 |        0 |        0 |    33.33 |       17,22,23,27 |
 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 |
 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 |
 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: 4 failed, 4 total
Tests:       11 failed, 11 total
Snapshots:   0 total
Time:        25.373s
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-12T02_44_07_608Z-debug.log
betancourtl commented 6 years ago

let me see which react version you are running. There might be 2 adapters. 1 for v15 and 1 or v16

betancourtl commented 6 years ago

looks like you are on v16 which should be ok

most of the errors are related to this

 componentWillMount() {
          // update redux store
    this.props.dispatchLayout(setLayout({ layout: 'login' }));
     }

maybe the test is not passing that dispatchLayout fn?

rickhanlonii commented 6 years ago

Great to see you Jest config is working!

Those failures are legit now (for example, this.props.dispatchLayout is not a function because you're not passing any props in your tests as @webdeveloperpr said)

jeff1evesque commented 6 years ago

@webdeveloperpr, do you have some example syntax of how to pass this.props.xxx into the tests? I spent maybe 5-10 trying to google some relevant syntax, and currently empty handed.

betancourtl commented 6 years ago

yeah let me check

rickhanlonii commented 6 years ago

@jeff1evesque as an example, consider this test:

it('should render without throwing an error', () => {
    expect(shallow(<LoginForm />).exists(<form ref='loginForm'></form>)).toBe(true)
});

This is saying to shallow render a <LoginForm /> with no props. When LoginForm is rendered, it goes through the React component lifecycle, which calls the lifecycle methods. That means it will call componentWillMount and componentDidMount, which call this.props.dispatchLayout and this.props.dispatchSpinner respectively.

But, those props are not passed in, so the test fails when they're called

One way you can pass those props in, is by creating an empty mockFunction, as in:

it("should render without throwing an error", () => {
    const mockDispatchLayout = jest.fn();
    const mockDispatchSpinner = jest.fn();
    expect(
        shallow(
        <LoginForm
            dispatchLayout={mockDispatchLayout}
            dispatchSpinner={mockDispatchSpinner}
        />
        ).exists(<form ref="loginForm" />)
    ).toBe(true);

    // now you can also assert that they're called
    expect(mockDispatchLayout).toBeCalled();
    expect(mockDispatchSpinner).toBeCalled();
});
betancourtl commented 6 years ago

^ Looks good to me.

jeff1evesque commented 6 years ago

Almost done. But, can't quite nail down the syntax to test routes. For example, from analysis.test.jsx:

    it('should render correct routes', () => {
        const wrapper = shallow(<AnalysisLayout />);
        const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
            const routeProps = route.props();
            pathMap[routeProps.path] = routeProps.component;
            return pathMap;
        }, {});

        expect(pathMap['/session/data-new']).toBe(DataNewState);
        expect(pathMap['/session/data-append']).toBe(DataAppendState);
        expect(pathMap['/session/model-generate']).toBe(ModelGenerateState);
        expect(pathMap['/session/model-predict']).toBe(ModelPredictState);
        expect(pathMap['/session/current-result']).toBe(CurrentResultState);
        expect(pathMap['/session/results']).toBe(ResultsDisplayState);
    });

However, it is encouraging to see only two tests failing:

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 (33:8)
        31 |
        32 |     it('should render correct routes', () => {
      > 33 |         const wrapper = shallow(<AnalysisLayout />);
           |         ^
        34 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
        35 |             const routeProps = route.props();
        36 |             pathMap[routeProps.path] = routeProps.component;

 PASS  __tests__/content/login.test.jsx
  Login Component
    ✓ should render without throwing an error (17ms)
    ✓ should render without throwing an error (7ms)
    ✓ 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 (6ms)
    ✓ should render without throwing an error (2ms)
    ✓ should render without throwing an error (6ms)
    ✓ should render without throwing an error (1ms)
    ✓ should render without throwing an error (2ms)

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

    Cannot find module '../../../src/jsx/import/redux/container/home-page.jsx' from 'page.test.jsx'

      17 | Enzyme.configure({ adapter: new Adapter() });
      18 |
    > 19 | describe('PageLayout Component', () => {
      20 |     it('should render correct routes', () => {
      21 |         const wrapper = shallow(<PageLayout />);
      22 |         const pathMap = wrapper.find(Route).reduce((pathMap, route) => {

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:169:17)
      at Object.<anonymous> (__tests__/layout/page.test.jsx:19:17)

--------------------|----------|----------|----------|----------|-------------------|
File                |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files           |    21.98 |    12.75 |    26.32 |     22.1 |                   |
 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 |
 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 |
 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 |
 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:        28.037s
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-12T17_13_23_527Z-debug.log
ljharb commented 6 years ago

You should also make console warnings/errors fail your tests, so propType warnings can be caught.

jeff1evesque commented 6 years ago

@ljharb, do you know the syntax by chance, to catch propType warnings?

ljharb commented 6 years ago

It’s not syntax, it’s api. console.error = x => { throw x; }; console.warn = x => { throw x; } in your jest setup file should be sufficient.

jeff1evesque commented 6 years ago

Each test instance it( 'blah', () => { console.error = x => { throw x; }; console.warn = x => { throw x; } }); needs the api?

ljharb commented 6 years ago

No, if you put it in your jest setup file it will run before every test file.

jeff1evesque commented 6 years ago

First time I've heard setup file. I found an example. So basically, I define setupTestFrameworkScriptFile, and whatever is in there gets run before each test?

jeff1evesque commented 6 years ago

@webdeveloperpr, would you happen to know how to check if a particular URL renders a specific component? For example, in my page.test.jsx:

import React from 'react';
import { Route } from 'react-router-dom';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import PageLayout from '../../../../src/jsx/import/layout/page.jsx';
import HomePageState from '../../../../src/jsx/import/redux/container/home-page.jsx';
import UserMenuState from '../../../../src/jsx/import/redux/container/user-menu.jsx';
import HeaderMenuState from '../../../../src/jsx/import/redux/container/header-menu.jsx';
import AnalysisLayoutState from '../../../../src/jsx/import/redux/container/analysis-layout.jsx';
import LoginLayout from '../../../../src/jsx/import/layout/login.jsx';
import RegisterLayout from '../../../../src/jsx/import/layout/register.jsx';

Enzyme.configure({ adapter: new Adapter() });

describe('PageLayout Component', () => {
    it('should render correct routes', () => {
        const wrapper = shallow(<PageLayout />);
        const pathMap = wrapper.find(Route).reduce((pathMap, route) => {
            const routeProps = route.props();
            pathMap[routeProps.path] = routeProps.component;
            return pathMap;
        }, {});

        expect(pathMap['/']).toBe(HomePageState);
        expect(pathMap['/login']).toBe(LoginLayout);
        expect(pathMap['/logout']).toBe(LoginLayout);
        expect(pathMap['/register']).toBe(RegisterLayout);
        expect(pathMap['/session']).toBe(AnalysisLayoutState);
    });
});

But, when I run the unit tests:

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 (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 (11ms)
    ✓ should render without throwing an error (4ms)
    ✓ should render without throwing an error (4ms)

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

 FAIL  __tests__/layout/page.test.jsx (15.669s)
  PageLayout Component
    ✕ should render correct routes (33ms)

  ● PageLayout Component › should render correct routes

    expect(received).toBe(expected) // Object.is equality

    Expected value to be:
      [Function Connect]
    Received:
      undefined

    Difference:

      Comparing two different types of values. Expected function but received undefined.

      27 |         }, {});
      28 |
    > 29 |         expect(pathMap['/']).toBe(HomePageState);
      30 |         expect(pathMap['/login']).toBe(LoginLayout);
      31 |         expect(pathMap['/logout']).toBe(LoginLayout);
      32 |         expect(pathMap['/register']).toBe(RegisterLayout);

      at Object.<anonymous> (__tests__/layout/page.test.jsx:29:30)

----------------------------------|----------|----------|----------|----------|-------------------|
File                              |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------------------------------|----------|----------|----------|----------|-------------------|
All files                         |     8.25 |     1.82 |      4.2 |     8.31 |                   |
 jsx                              |       50 |      100 |        0 |      100 |                   |
  setup.js                        |       50 |      100 |        0 |      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                |     3.41 |        0 |     5.26 |     3.41 |                   |
  analysis.jsx                    |        0 |        0 |        0 |        0 |... 51,352,353,359 |
  login.jsx                       |       50 |      100 |        0 |       50 |                13 |
  page.jsx                        |     8.33 |        0 |       25 |     8.33 |... 6,58,59,62,106 |
  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:       1 failed, 9 passed, 10 total
Snapshots:   0 total
Time:        28.904s
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-12T21_53_57_213Z-debug.log

Note: thank you everyone, I should be out of all your cross hairs very soon. Once I know how to test url with it's matching react component, it's just going to be a matter of piping the jest test result to travis ci.

betancourtl commented 6 years ago

I don't think all of the Route components are rendering, I'm guessing you would have to mock a route path for each Route and test to see if the route renders.

Here they mock the route with a Memory router

https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/testing.md#starting-at-specific-routes