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

Create a non-Meteor factory/fixtures solution #4246

Closed
aldeed opened this issue May 15, 2018 · 1 comment · Fixed by #4296
Closed

Create a non-Meteor factory/fixtures solution #4246

aldeed opened this issue May 15, 2018 · 1 comment · Fixed by #4296
Assignees
Milestone

Comments

@aldeed
Copy link
Contributor

aldeed commented May 15, 2018

Goal

Remove the large similar objects we've been copy-pasting in all of the integration tests (and some Jest unit tests). Instead use a factory pattern to get fake data.

Proposal

Here is my proposal for API, but feel free to alter this as necessary to get everything we need to keep our tests simple.

Make it an NPM package (maybe @reactioncommerce/data-factory?)
Depend on https://www.npmjs.com/package/simpl-schema-mockdoc

In the reaction files where schemas are defined, do something like:

import { createFactoryForSchema } from "@reactioncommerce/data-factory";
createFactoryForSchema("Shop", ShopSchema);

This will add Shop property to a Factory object that can be imported in tests, in devtools, anywhere.

import { Factory } from "@reactioncommerce/data-factory";

const shop = Factory.Shop.makeOne({ prop: val });
const shops = Factory.Shop.makeMany(5, { prop: val });

makeOne returns a single object to be inserted/used, while makeMany returns multiple in an array (array length = first arg value).

The { prop: val } object is where you specify override properties you specifically want. For any properties not there, or if you omit that object, you'll get back the object created by the simpl-schema-mockdoc package.

If simpl-schema-mockdoc does not meet our needs or is buggy, we can copy the relevant code into this data-factory package and update it to work for us.

Work

  1. Create the package
  2. Add the package to Reaction, pass in all the schemas.
  3. Change all of the integration tests in the /tests folder to use this to build their mock data objects.
@aldeed aldeed added this to the Elbert milestone May 15, 2018
@aldeed
Copy link
Contributor Author

aldeed commented May 18, 2018

Here is more specifically how I envision this looking. This is untested but should be a starting point to see how it works. We will definitely have to make this more robust over time (allow overriding nested props, maybe some helpers for relationships).

import { getMockDoc } from "simpl-schema-mockdoc";

export const Factory = {};

/**
 * @name createFactoryForSchema
 * @function
 * @summary Creates Factory[propName] for building fake documents with the given schema.
 * @param {String} propName The property name to add to the `Factory` object. This should match the 
 *   schema variable's name.
 * @param {SimpleSchema} schema A SimpleSchema instance
 */
export function createFactoryForSchema(propName, schema) {
  if (Factory.hasOwnProperty(propName)) {
    throw new Error(`Factory already has a "${propName}" property`);
  }

  Factory[propName] = {
    makeOne(props) {
      const doc = getMockDoc(schema, 'mock', true);

      // Most likely it is fine to mutate doc, and will be faster. If this causes problems,
      // can change this to return { ...doc, ...props }
      Object.assign(doc, props);

      return doc;
    },
    makeMany(length, props) {
      return Array.from({ length }).map(() => this.makeOne(props));
    }
  };
}

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

Successfully merging a pull request may close this issue.

3 participants