Giter Site home page Giter Site logo

sails-factory's Introduction

sails-factory

Sails Factory is a simple model factory for Sails.js. Inspired by factory_girl and rosie.

Installation

npm install sails-factory

Usage

Defining factories

Define a factory by giving it a name and an optional model name. The factory name will be the default model name if model name is not provided.

var factory = require("sails-factory");

factory.define("user")
  .attr("first_name", "First Name")
  .attr("last_name", "Last Name")
  .attr("random_id", function() { return Math.random(); });

factory.define("active_user").parent("user")
  .attr("active", true);

factory.define("admin_user", "Admin").parent("user");

Using factories

//-- synchronous
var active_user = factory.build("active_user");
// active_user: non-persistent "active_user" instance
// {
//    first_name: "First Name",
//    last_name: "Last Name",
//    random_id: <number>,
//    active: true
// }

var user = factory.build("user", {first_name: "Hello", last_name: function() { return "World"; }});
// user: non-persistent "user" instance
// {
//    first_name: "Hello",
//    last_name: "World",
//    random_id: <number>
// }

//-- asynchronous
factory.build("active_user", function(active_user) {
  // active_user: non-persistent "active_user" instance
  // {
  //    first_name: "First Name",
  //    last_name: "Last Name",
  //    random_id: <number>,
  //    active: true
  // }
});

factory.build("user", {first_name: "Hello", last_name: function() { return "World"; }}, function(user) {
  // user: non-persistent "user" instance
  // {
  //    first_name: "Hello",
  //    last_name: "World",
  //    random_id: <number>
  // }
});

factory.create("active_user", function(active_user) {
  // active_user: sails User model instance
  // {
  //    id: <id>,
  //    first_name: "First Name",
  //    last_name: "Last Name",
  //    random_id: <number>,
  //    active: true,
  //    createdAt: <date>,
  //    updatedAt: <date>
  // }
});

Auto increment attributes

Attributes can have an auto_increment option. By default, sequence will increment by 1, otherwise it will increment by whatever value the auto_increment option is set to. Counting starts at the initial value given. Sequence is shared among parent and children.

factory.define("user")
  .attr("id", 0, {auto_increment: true})
  .attr("first_name", "First Name - ", {auto_increment: 5});

factory.define("other_user").parent("user");

factory.build("user", function(user) {
  // user:
  // {
  //    id: 1,
  //    first_name: "First Name - 5",
  //    ...
  // }
});

factory.create("user", function(user) {
  // user:
  // {
  //    id: 2,
  //    first_name: "First Name - 10",
  //    ...
  // }
});

factory.build("other_user", function(other_user) {
  // other_user:
  // {
  //    id: 3,
  //    first_name: "First Name - 15",
  //    ...
  // }
});

Loading factories

Calling .load() without parameter will try to load factory definitions from test/factories folder. By default, the model name will be set to factory file name if not provided on define parameters.

// api/models/User.js
module.exports = {
  attributes: {
    first_name: "string",
    last_name: "string",
    random_id: "integer",
    active: "boolean"
  }
};

// test/factories/User.js
module.exports = function(factory) {
  factory.define("user")
    .attr("first_name", "First Name")
    .attr("last_name", "Last Name")
    .attr("random_id", function() { return Math.random(); });

  factory.define("active_user").parent("user")
    .attr("active", true);
};

// test/bootstrap.js
before(function(done) {
  require("sails").lift({
    log: {
      level: "error"
    }
  }, function(err, sails) {
    if (sails) {
      //-- load factory definition files from test/factories
      require("sails-factory").load();
    }
    done(err);
  });
});

To load factory files from different folder:

factory.load("/path/to/factories");

To get the total number of loaded factory files:

factory.load(function(count) {
  // count is the total number of loaded files
});

sails-factory's People

Contributors

zand3rs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

sails-factory's Issues

Sub-factories

It would be nice to be able to define "sub-factories" within a factory so associations can be built with one factory call. factory_boy has an example of this.

Could not load facroy with ES6

I am using ES6 with sails and sails-factory

Here bootstrap.js

/* eslint strict: [2, "global"] */

'use strict';

const Sails = require('sails');
const babel = require('sails-hook-babel/node_modules/babel/register');

const options = {
  loose: 'all',
  stage: 2,
  ignore: null,
  only: null,
  extensions: null,
};
global.babel = babel(options);

before(done => {
  Sails.lift({}, (err, sails) => {
    if (err) return done(err);
    require('sails-factory').load();
    done(err, sails);
  });
});

after(done => Sails.lower(done));

And here is error logs

$ npm test

> [email protected] test /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler
> mocha test/bootstrap.js test/unit/**/*.test.js --timeout 60000



info: 
info:                .-..-.
info: 
info:    Sails              <|    .-..-.
info:    v0.11.2             |\
info:                       /|.\
info:                      / || \
info:                    ,'  |'  \
info:                 .-'.-==|/_--'
info:                 `--'-------' 
info:    __---___--___---___--___---___--___
info:  ____---___--___---___--___---___--___-__
info: 
info: Server lifted in `/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler`
info: To see your app, visit http://localhost:1337
info: To shut down Sails, press <CTRL> + C at any time.

debug: --------------------------------------------------------
debug: :: Tue Oct 20 2015 15:32:21 GMT+0700 (ICT)

debug: Environment : development
debug: Port        : 1337
debug: --------------------------------------------------------
error: The bootstrap function threw an error after its callback was called :: TypeError: Cannot read property 'caller' of null
    at Function.Factory.define (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails-factory/index.js:69:39)
    at module.exports (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/test/factories/Job.js:2:11)
    at requireFactory (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails-factory/index.js:200:18)
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails-factory/index.js:189:18
    at Array.forEach (native)
    at requireAll (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails-factory/index.js:183:9)
    at Function.Factory.load (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails-factory/index.js:172:3)
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/test/bootstrap.js:20:30
    at sailsReady (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/lib/app/lift.js:49:12)
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:251:17
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:154:25
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:248:21
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:612:34
    at afterBootstrap (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/lib/app/private/initialize.js:57:5)
    at bootstrapDone (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/lib/app/private/bootstrap.js:51:14)
    at Object.module.exports.bootstrap (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/config/bootstrap.js:7:3)
    at Sails.runBootstrap (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/lib/app/private/bootstrap.js:44:25)
    at Sails.bound [as runBootstrap] (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/lodash/dist/lodash.js:729:21)
    at Sails.initialize (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/lib/app/private/initialize.js:48:9)
    at bound (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/lodash/dist/lodash.js:729:21)
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:607:21
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:246:17
    at iterate (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:146:13)
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:157:25
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:248:21
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:612:34
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/lib/app/load.js:201:13
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:451:17
    at /Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:441:17
    at _each (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:46:13)
    at Immediate.taskComplete (/Volumes/DATA/TRUSTCIRCLE/BACKEND/backend-scheduler/node_modules/sails/node_modules/async/lib/async.js:440:13)
    at processImmediate [as _immediateCallback] (timers.js:368:17) [TypeError: Cannot read property 'caller' of null]

Support for promises

Would be nice to have a promise interface, instead of callbacks, so methods could be chained like:

var createUser = factory.create('user', { name: 'Bob' })
var createGroup = factory.create('group', { name: 'Group 1' })

createUser
  .then(function(user){
    return [user, createGroup];
  })
  .spread(function(user, group) {
     // do some testing
  });

inflection.classify causes the model name to change

I have a model that I named "Data", the problem is that when I try to use Factory.create the name of the model changes to "datum" which doesn't exists as a model and the module throws an error.

The line that is causing this is the line 137

var modelId = inflection.classify(factory.modelName).toLowerCase();

Everything works as expected if I remove inflection.classify and change it to:

´´´
var modelId = factory.modelName.toLowerCase();
´´´

Before I make a patch can you please clarify why use inflection.classify? This is not a module I'm familiar with but from what I understand, the classify method just changes the name of the model, is that necessary? If so, how can we solve this kind of situations when the model changed because of inflection and then sails doesn't detect it.

Define position of auto_increment

It would be nice to be able to define the position for the auto incrementing value.
This is necessary for example if you have a Model with a unique email attribute. Using .attr('email', '[email protected]', { auto_increment: 1 }) appends the auto incrementing value to the end, which makes the email invalid. Instead it would be nice to have something similar as Factory Bots Sequences

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.