Tcomb-form-native: Jest tests are broken: Error: Cannot find module './datepicker' from 'index.js'

Created on 22 Mar 2016  ·  23Comments  ·  Source: gcanti/tcomb-form-native

Version

Tell us which versions you are using:

  • tcomb-form-native v0.4.0
  • react-native v0.22.2

Expected behaviour

Tests should pass as they used to!

Actual behaviour

Error: Cannot find module './datepicker' from 'index.js'

Steps to reproduce

  1. git clone [email protected]:bartonhammond/snowflake.git
  2. npm3 install
  3. npm3 test
  ✓ it if disabled and not checked, it should display square-o and text

 FAIL  src/components/__tests__/LoginForm-test.js
Runtime Error
Error: Cannot find module './datepicker' from 'index.js'
    at Loader._resolveNodeModule (/Users/barton/projects/MFV/snowflake/node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:431:11)
    at Object.<anonymous> (/Users/barton/projects/MFV/snowflake/node_modules/tcomb-form-native/lib/templates/bootstrap/index.js:5:12)
    at Object.<anonymous> (/Users/barton/projects/MFV/snowflake/node_modules/tcomb-form-native/index.js:3:15)
1 test suite failed, 74 tests passed (74 total in 11 test suites, run time 7.245s)
Docs

Most helpful comment

The following seems to work w/ JEST testing!

Here is the full package.json wrt Jest setup:

 "jest": {
    "setupEnvScriptFile": "./node_modules/react-native/jestSupport/env.js",
    "haste": {
      "defaultPlatform": "ios",
      "platforms": [
        "ios",
        "android"
      ],
      "providesModuleNodeModules": [
        "react-native"
      ]
    },
    "testPathIgnorePatterns": [
      "/node_modules/"
    ],
    "testFileExtensions": [
      "es6",
      "js"
    ],
    "moduleFileExtensions": [
      "js",
      "json",
      "es6",
      "ios.js"   <<<<<<<<<<<<<<<<<<<<<<<< this makes it work!
    ],
    "unmockedModulePathPatterns": [
      "react",
      "react-addons-test-utils",
      "react-native-router-flux",
      "promise",
      "source-map",
      "key-mirror",
      "immutable",
      "fetch",
      "redux",
      "redux-thunk",
      "fbjs"
    ],
    "collectCoverage": false,
    "verbose": true
  },

Would you like a PR w/ a note in the README?

All 23 comments

This could be related to the new HMR feature of RN 0.22. Will look into this.

Ok, this is due to the dynamic require of platform-specific code by the DatePicker component. react-packager solves the issue by automatically getting the right code for the platform, but I don't know how can we provide a fallback for the tests. @gcanti any idea?

@alvaromb

any idea?

Honestly nothing that is not hacky: for example what about overloading require in order to replicate react-packager's behavior?

@bartonhammond I've opened a SO question about this http://stackoverflow.com/questions/36479136/test-platform-specific-extension-code-for-react-native

Have you managed to test platform-specific code under snowflake?

+1

+1

what about overloading require in order to replicate react-packager's behavior

Something like:

// react-native-register-extension.js
var path = require('path');

var cwd = process.cwd();

function getRelativePath(filename) {
  return path.relative(cwd, filename);
}

function shouldIgnore(filename) {
  return getRelativePath(filename).split(path.sep).indexOf('node_modules') >= 0;
}

function loader(old, m, filename, platform) {
  var ext = path.extname(filename);
  var basename = path.basename(filename)
  var name = basename.substr(0, basename.length - ext.length);
  var newFilename = path.join(path.dirname(filename), name + '.' + platform + ext)
  old(m, newFilename);
}

function registerExtension(platform /* ios | android */) {
  platform = platform || 'ios';
  var old = require.extensions['.js'];

  require.extensions['.js'] = function (m, filename) {
    if (shouldIgnore(filename)) {
      old(m, filename);
    } else {
      loader(old, m, filename, platform);
    }
  };
}

module.exports = registerExtension;

Usage:

// index.js
require('./react-native-register-extension')();
// or require('./react-native-register-extension')('android');

require('./path/to/file');

Directory structure:

path/
  to/
    file.js <-- required even if empty otherwise `require()` throws
    file.ios.js
    file.android.jd

Thanks for the help @gcanti. I found that adding the following line in my test setup worked

require.extensions['.ios.js'] = require.extensions['.js'];

This is very cool @gcanti. Do you want me to introduce it into tcomb-form-native and send a PR?

@alvaromb The fix should be outside this library (i.e. in the test setup I guess) as it's a general issue, not specific to tcomb-form-native (i.e. every library which leverage that react-packager's behavior)

@frankrowe Awesome, a one liner solution ;)

So this should be included into Jest, right?

@frankrowe feel free to answer my question at SO :)

We might add a note/warning on this in the README

@gcanti, sorry for asking again, but is there something we can include into tcomb-form-native tests in order to support it, besides the README warning?

I don't know, tcomb-form-native tests are fine. What breaks user tests is tcomb-form-native _code_ so nothing we add to our _tests_ can make any difference I guess.

I mean, something like this https://github.com/boundlessgeo/spatialconnect-mobile/blob/develop/test/setup.js

Should we include this kind of setup into the library or just a notice?

Touching require.extensions is kinda hacky and must be done in your own project. For now it should be enough to add a clear warning in the README stating that if you run into this sort of issues you can add:

require.extensions['.ios.js'] = require.extensions['.js'];
// or require.extensions['.android.js'] = require.extensions['.js'];

in your own test setup.

👍 I can add this to the README if you want.

Sure, thanks!

@bartonhammond have you tried @gcanti's suggestions https://github.com/gcanti/tcomb-form-native/issues/134#issuecomment-217106365?

Oh - I missed this request!!! I am having this problem now as I try to upgrade my project. I don't understand the suggestion. Where does this one liner go? I'm using Jest. I know nothing about this require.extensions.

Where would I put this for JEST?

The following seems to work w/ JEST testing!

Here is the full package.json wrt Jest setup:

 "jest": {
    "setupEnvScriptFile": "./node_modules/react-native/jestSupport/env.js",
    "haste": {
      "defaultPlatform": "ios",
      "platforms": [
        "ios",
        "android"
      ],
      "providesModuleNodeModules": [
        "react-native"
      ]
    },
    "testPathIgnorePatterns": [
      "/node_modules/"
    ],
    "testFileExtensions": [
      "es6",
      "js"
    ],
    "moduleFileExtensions": [
      "js",
      "json",
      "es6",
      "ios.js"   <<<<<<<<<<<<<<<<<<<<<<<< this makes it work!
    ],
    "unmockedModulePathPatterns": [
      "react",
      "react-addons-test-utils",
      "react-native-router-flux",
      "promise",
      "source-map",
      "key-mirror",
      "immutable",
      "fetch",
      "redux",
      "redux-thunk",
      "fbjs"
    ],
    "collectCoverage": false,
    "verbose": true
  },

Would you like a PR w/ a note in the README?

Yes @bartonhammond!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

semirturgay picture semirturgay  ·  4Comments

alexicum picture alexicum  ·  6Comments

ishigamii picture ishigamii  ·  3Comments

chauthai picture chauthai  ·  4Comments

dvlprmartins picture dvlprmartins  ·  4Comments