kylezeeuwen / rosie

factory for building JavaScript objects, mostly useful for setting up test data. Inspired by factory_girl

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rosie

Build Status

Rosie the Riveter

Rosie is a factory for building JavaScript objects, mostly useful for setting up test data. It is inspired by factory_girl.

Usage

Define your factory, giving it a name and optionally a constructor function (Game in this example):

Factory.define('game'/*, Game*/)
  .sequence('id')
  .attr('is_over', false)
  .attr('created_at', function() { return new Date(); })
  .attr('random_seed', function() { return Math.random(); })

  // Default to two players. If players were given, fill in
  // whatever attributes might be missing.
  .attr('players', ['players'], function(players) {
    if (!players) { players = [{}, {}]; }
    return players.map(function(data) {
      return Factory.attributes('player', data);
    });
  });

Factory.define('player')
  .sequence('id')
  .sequence('name', function(i) { return 'player' + i; })

  // Define `position` to depend on `id`.
  .attr('position', ['id'], function(id) {
    var positions = ['pitcher', '1st base', '2nd base', '3rd base'];
    return positions[id % positions.length];
  });

Factory.define('disabled-player').extend('player').attr('state', 'disabled')

Now you can build an object, passing in attributes that you want to override:

var game = Factory.build('game', {is_over:true});

Which returns an object that looks roughly like:

{
    id:           1,
    is_over:      true,   // overriden when building
    created_at:   Fri Apr 15 2011 12:02:25 GMT-0400 (EDT),
    random_seed:  0.8999513240996748,
    players: [
                {id: 1, name:'Player 1'},
                {id: 2, name:'Player 2'}
    ]
}

For a factory with a constructor, if you want just the attributes:

Factory.attributes('game') // return just the attributes

You can also define a callback function to be run after building an object:

Factory.define('coach')
  .option('buildPlayer', false)
  .sequence('id')
  .attr('players', ['id', 'buildPlayer'], function(id, buildPlayer) {
    if (buildPlayer) {
      return [Factory.build('player', {coach_id: id})];
    }
  })
  .after(function(coach, options) {
    if (options.buildPlayer) {
      console.log('built player:', coach.players[0]);
    }
  });

Factory.build('coach', {}, {buildPlayer: true});

Node.js

To use Rosie in node, you'll need to require it first:

var Factory = require('rosie').Factory;

You might also choose to use unregistered factories, as it fits better with node's module pattern:

// factories/game.js
var Factory = require('rosie').Factory;

module.exports = new Factory()
  .sequence('id')
  .attr('is_over', false)
  // etc

To use the unregistered Game factory defined above:

var Game = require('./factories/game');

var game = Game.build({is_over: true});

ES6

Unregistered factories are even more natural in ES6:

// factories/game.js
import { Factory } from 'rosie';

export default new Factory()
  .sequence('id')
  .attr('is_over', false)
  // etc
  
// index.js
import Game from './factories/game');

const game = Game.build({is_over: true});

A tool like babel is currently required to use this syntax.

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Install the test dependencies (script/bootstrap - requires NodeJS and npm)
  4. Make your changes and make sure the tests pass (npm test)
  5. Commit your changes (git commit -am 'Added some feature')
  6. Push to the branch (git push origin my-new-feature)
  7. Create new Pull Request

Credits

Thanks to Daniel Morrison for the name and Jon Hoyt for inspiration and brainstorming the idea.

About

factory for building JavaScript objects, mostly useful for setting up test data. Inspired by factory_girl

License:Other


Languages

Language:JavaScript 99.6%Language:Ruby 0.3%Language:Shell 0.1%