factory-girl icon indicating copy to clipboard operation
factory-girl copied to clipboard

Removes undefined values when populating

Open pdokas opened this issue 7 years ago • 2 comments

Factory-girl does not support being passed an object spec where a member has the value undefined. This happens:

$ npm test -- test/utils/asyncPopulateSpec.js 

> [email protected] test /Users/pdokas/dev/factory-girl
> NODE_ENV=test mocha "test/utils/asyncPopulateSpec.js"



  asyncPopulate
    ✓ returns a promise
    ✓ throws error if target or source is not an object
    1) populates objects correctly
    ✓ overrides only provided data


  3 passing (28ms)
  1 failing

  1) asyncPopulate populates objects correctly:
     TypeError: Cannot convert undefined or null to object
      at getPrototypeOf (<anonymous>)
      at isPlainObject (src/utils/asyncPopulate.js:35:10)
      at src/utils/asyncPopulate.js:19:16
      at Array.map (<anonymous>)
      at asyncPopulate (src/utils/asyncPopulate.js:10:40)
      at _callee3$ (test/utils/asyncPopulateSpec.js:62:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14
      at new Promise (<anonymous>)
      at new F (node_modules/core-js/library/modules/_export.js:35:28)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:14:12
      at _callee$ (test/test-helper/asyncFunction.js:4:11)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:62:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:296:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:114:21)
      at step (node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
      at node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14
      at new Promise (<anonymous>)
      at new F (node_modules/core-js/library/modules/_export.js:35:28)
      at Context.<anonymous> (node_modules/babel-runtime/helpers/asyncToGenerator.js:14:12)
      at Context.<anonymous> (test/test-helper/asyncFunction.js:2:23)

If source[attr] is defined as undefined, then asyncPopulate calls isPlainObject which passes undefined to Object.getPrototypeOf which throws a TypeError.

This PR alleviates this by having factory-girl remove members where the value is undefined. A use case where this comes up is when using factory-girl with structure. Structure validates objects against a spec, and allows you to define default values for individual members.

So if I have an object spec and a factory for it like this:

module.exports = structure({
  is_followed: {
    type: Boolean,
    default: false,
  }
});

factory.define('person', exports, {
  is_followed: factory.chance('bool'),
});

This is great for tests, except when you want to test that the default works because there is no way to tell factory-girl "completely leave this one value out". And so, this PR alleviates this need by allowing someone to build a factory and tell it to drop a member from the built object.

pdokas avatar Feb 23 '18 21:02 pdokas

P.S. I would love to document this in the readme, but I don’t see an obvious place to add the info. I’m absolutely open to suggestions!

pdokas avatar Feb 23 '18 21:02 pdokas

@aexmachina: Hi there, I don't mean to pester but I was wondering if you have any thoughts about this. Thank you!

pdokas avatar Mar 10 '18 00:03 pdokas