factory-js

    1.3.2 • Public • Published

    Factory Build Status

    Building JavaScript objects inspired by rosie and factory_girl.

    Factory can integrate with JavaScript framework persistence layer through Adapters.

    Usage

    Factory.define('vote')
      .sequence('id')
      .attr('value', 0)
      .trait('up', function() {
        return this.attr('value', 1);
      })
      .trait('down', function() {
        return this.attr('value', -1);
      });
    
    Factory.define('post')
      .sequence('id')
      .sequence('title', function(i) {
        return "Post " + i;
      })
      .attr('content', null)
      .hasMany('votes', 'vote')
      .after(function() {
        if (!this.content) {
          return this.content = "" + this.title + " content";
        }
      });
    
    Factory.define('category')
      .sequence('id')
      .sequence('name', function(i) {
        return "Category " + i;
      })
      .ignore('postsCount', 0)
      .after(function(attributes) {
        return this.posts = Factory.buildList('post', attributes.postsCount);
      });
    

    Build with no attributes

    Factory.build('post')
    

    result:

    {
      "id":1,
      "title":"Post 1",
      "content":"Post 1 content"
    }
    

    Build with attributes

    Factory.build('post', {content: 'my content'})
    

    result:

    {
      "id":1,
      "title":"Post 1",
      "content":"my content"
    }
    

    Build with ignored attribute and after() callback

    Factory.build('category',{name: 'First category', postsCount: 2})
    

    result:

    {
      "name":"First category",
      "id":1,
      "posts":[
        {"id":1,"title":"Post 1","content":"Post 1 content"},
        {"id":2,"title":"Post 2","content":"Post 2 content"}
      ]
    }
    

    Build post with votes count

    Factory.build('post', {votes: 2})
    

    result:

    {
      "content" : "Post 1 content",
      "id" : 1,
      "title" : "Post 1",
      "votes" : [
          {"id":1,"value":1},
          {"id":2,"value":1}
        ]
    }
    

    Build post with votes traits or attributes

    Factory.build('post', {votes: ['up', 'down', 'up']})
    

    or

    Factory.build('post', {votes: [{value: 1}, {value: -1}, {value: 1}]})
    

    result:

    {
      "content" : "Post 1 content",
      "id" : 1,
      "title" : "Post 1",
      "votes" : [
          {"id":1,"value":1},
          {"id":2,"value":-1},
          {"id":3,"value":1}
        ]
    }
    

    Adapters

    By default factory is building JavaScript objects using default Factory.Adapter

    class Factory.Adapter
      constructor: (factory) -> @factory = factory
      build: (name, attrs) -> attrs
      create: (name, attrs) -> attrs
      push: (name, object) -> @[name].push object
    

    Factory integrates with Ember.js through Factory.EmberDataAdapter (used by Factory.setupForEmber(App))

    class Factory.EmberDataAdapter extends Factory.Adapter
      build: (name, attrs) -> Ember.run => App.__container__.lookup('store:main').createRecord name, attrs
      create: (name, attrs) -> @build name, attrs
      push: (name, object) -> Ember.run => @get(name).addObject object
    

    You can set adapter globally

    Factory.adapter = Factory.YourAdapter
    

    or per factory definition

    Factory.define 'yourModel', ->
      @adapter Factory.YourAdapter
    

    Setup for Ember.js

    Call Factory.setupForEmber(App) before factory definitions. See live example at jsbin

    NOTE: You need to call Factory.reset() to reset sequences for each test run.

    Contributing

    git clone git@github.com:tb/factory.git
    cd factory
    npm install
    grunt build
    

    Install

    npm i factory-js

    DownloadsWeekly Downloads

    101

    Version

    1.3.2

    License

    MIT

    Last publish

    Collaborators

    • tomaszbak