What is rosie?
Rosie is a factory for building JavaScript objects, useful for setting up test data or creating objects with default values.
What are rosie's main functionalities?
Defining a Factory
This feature allows you to define a factory with attributes. In this example, a user factory is created with an 'id' attribute that generates a random number and a 'name' attribute with a default value of 'John Doe'.
const Factory = require('rosie').Factory;
const userFactory = new Factory()
.attr('id', () => Math.floor(Math.random() * 1000))
.attr('name', 'John Doe');
Building an Object
This feature allows you to build an object using the defined factory. The 'build' method generates an object with the specified attributes. In this example, it creates a user object with a random 'id' and the name 'John Doe'.
const user = userFactory.build();
console.log(user);
Overriding Attributes
This feature allows you to override default attributes when building an object. In this example, the 'name' attribute is overridden to 'Jane Doe' while the 'id' attribute remains randomly generated.
const customUser = userFactory.build({ name: 'Jane Doe' });
console.log(customUser);
Defining Sequences
This feature allows you to define sequences for attributes. In this example, the 'id' attribute is a sequence that increments with each build, while the 'name' attribute remains 'Sequence User'.
const sequenceFactory = new Factory()
.sequence('id')
.attr('name', 'Sequence User');
const user1 = sequenceFactory.build();
const user2 = sequenceFactory.build();
console.log(user1, user2);
Other packages similar to rosie
factory-girl
Factory-girl is another library for setting up JavaScript objects for tests. It offers similar functionality to Rosie, such as defining factories and building objects, but also includes support for associations and adapters for different ORMs.
test-data-bot
Test-data-bot is a library for generating test data with a focus on simplicity and composability. It allows you to define blueprints and build objects, similar to Rosie, but with a more functional approach.
faker
Faker is a library for generating fake data. While it doesn't provide factory definitions like Rosie, it can be used in conjunction with Rosie to generate realistic data for attributes.
Rosie


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')
.sequence('id')
.attr('is_over', false)
.attr('created_at', function() { return new Date(); })
.attr('random_seed', function() { return Math.random(); })
.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; })
.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,
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')
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:
var Factory = require('rosie').Factory;
module.exports = new Factory()
.sequence('id')
.attr('is_over', false)
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:
import { Factory } from 'rosie';
export default new Factory()
.sequence('id')
.attr('is_over', false)
import Game from './factories/game');
const game = Game.build({is_over: true});
A tool like babel is currently required to use this syntax.
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Install the test dependencies (
script/bootstrap
- requires NodeJS and npm) - Make your changes and make sure the tests pass (
npm test
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
Credits
Thanks to Daniel Morrison for the name and Jon Hoyt for inspiration and brainstorming the idea.