Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Joi.attempt(config, Schema.schwifty) validation fails in Jest tests #68

Closed
kmenshov opened this issue May 4, 2019 · 6 comments
Closed
Labels

Comments

@kmenshov
Copy link

kmenshov commented May 4, 2019

I'm getting a Joi validation error on configuration object inside the internals.schwifty when trying to create a server inside Jest tests. Everywhere else (including NODE_ENV=test npm start) the server is being created just fine. The error disappears if I don't export any models.

Details and steps to reproduce:

// package.json

"scripts": {
    "test:jest": "NODE_ENV=test jest",
}

In any Jest test file:

// example.test.js

const Glue = require('glue');
const Manifest = require('../server/config/manifest');

const createServer = Glue.compose(Manifest.get('/'));

test('some test', async () => {
  const server = await createServer;
});

the command npm run test:jest -- example.test.js fails with the following:

ValidationError: {
      "knex": {
        "debug": false,
        "client": "pg",
        "connection": {
          "host": "127.0.0.1",
          "user": "user",
          "password": "password",
          "database": "db_test"
        }
      },
      "models": [
        function Users() {\n    _classCallCheck(this, Users);\n\n    return _possibleConstructorReturn(this, _getPrototypeOf(Users).apply(this, arguments));\n  } [2]
      ],
      "migrationsDir": "/server/config/migrations",
      "value" [1]: -- missing --
    }
    
    [1] "value" must be a Function
    [2] "0" must be a class

      at Object.<anonymous>.exports.process (node_modules/joi/lib/errors.js:203:19)
      at Object.<anonymous>.internals.Alternatives._validateWithOptions (node_modules/joi/lib/types/any/index.js:764:31)
      at Object.<anonymous>.module.exports.internals.Any.root.validate (node_modules/joi/lib/index.js:147:23)
      at Object.<anonymous>.module.exports.internals.Any.root.attempt (node_modules/joi/lib/index.js:177:29)
      at Object.<anonymous>.internals.schwifty (node_modules/schwifty/lib/index.js:190:18)
      at Object.register (node_modules/schwifty/lib/index.js:79:19)
      at Object.<anonymous>.internals.Server.register (node_modules/hapi/lib/server.js:453:35)

but if I transform the test file into a plain JS script:

// example.js

const Glue = require('glue');
const Manifest = require('../server/config/manifest');

const createServer = Glue.compose(Manifest.get('/'));

(async () => {
  const server = await createServer;
  console.log(server);
})();

and run it with NODE_ENV=test node example.js everything works fine and I see the server object being printed to stdout without any errors.

The error also disappears if I export an empty array for models:

// /server/models/index.js

const Users = require('./Users');

module.exports = [
  // Users,
];

I'm using Schwifty 4.2.0

@devinivy
Copy link
Member

devinivy commented May 5, 2019

Curious! Is jest configured to use any sort of transpilation (e.g. via babel)?

@kmenshov
Copy link
Author

kmenshov commented May 5, 2019

Ah, why didn't I think about it! Indeed it is:

// test/jest.setup.js
require('@babel/polyfill');

But without it I get the ReferenceError: regeneratorRuntime is not defined in tests. :(

@kmenshov
Copy link
Author

kmenshov commented May 5, 2019

Yep, seems like it's mutually exclusive. I've tried to replace babel polyfill with regenerator-runtime:

// test/jest.setup.js

// require('@babel/polyfill');
require('regenerator-runtime/runtime');

and got the same Joi validation error as described in the first post.

Can maybe the Joi schema be made less restrictive?

// schwifty/lib/schema.js

// internals.model = Joi.func().class();
internals.model = Joi.func();

@devinivy
Copy link
Member

devinivy commented May 5, 2019

There's really no need to transpile classes away in nodejs, and I highly suggest testing the code you're going to run in production, which I hope is not transpiled for a variety of reasons. I think the fix here is to your project's test suite. Mostly likely the polyfill itself is not responsible for the transpilation of classes to functions—you likely have @babel/preset-env setup somewhere, and you can try to configure that to omit certain transformations, or to only transpile your client-side directories.

@kmenshov
Copy link
Author

kmenshov commented May 5, 2019

I was wrong, sorry for bothering you. :) For anyone facing the same problem: indeed, the solution is just to exclude the server (but not the client) code from being transpiled altogether:

// jest.config.js

transformIgnorePatterns: ['<rootDir>/server/', '<rootDir>/node_modules/'],

See details here: https://jestjs.io/docs/en/configuration#transformignorepatterns-array-string

@kmenshov kmenshov closed this as completed May 5, 2019
@devinivy
Copy link
Member

devinivy commented May 5, 2019

Glad you got it sorted out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants