Neurotic Programmer Masquerade

    factory-bot-ts
    TypeScript icon, indicating that this package has built-in type declarations

    0.1.5 • Public • Published

    factory-bot-ts

    A simple library for setting up TypeScript objects as test data - heavily inspired by the awesome Ruby's factory_bot.

    • Fully written in TypeScript
    • With (optional) type checking
    • With no persistence layer
    • And no promises. ☺️

    Installation

    1. Add to your project

    npm i -D factory-bot-ts
    yarn add factory-bot-ts --dev

    Basics

    1. Ok, suppose we've got a Ninja model..

      // ../src/models/ninja.model.ts
     
      export enum NinjaRank {
        GENIN = 'Genin',
        CHUUNIN = 'Chuunin',
        JONIN = 'Jonin'
      }
     
      export class Ninja {
        id?: number
        name?: string
        username?: string
        level?: NinjaRank
        sensor?: boolean
     
        constructor(attrs?: Partial<Ninja>) {
          Object.assign(this, attrs)
        }
      }

    2. We would define our factories..

      // ../src/tests/index.ts
     
      import * as Faker from 'faker'
      import { sample } from 'lodash'
     
      import { FactoryBot } from 'factory-bot-ts'
     
      import { Ninja, NinjaRank, Village } from '../src/models'
     
      FactoryBot.define('ninja', {
        id: () => Faker.random.number(),
        name: () => Faker.name.findName(),
        username: () => FactoryBot.seq(seq => `${Faker.internet.userName()}_${seq}`),
        level: () => FactoryBot.rand(NinjaRank),
        sensor: () => sample([true, false])
      }, Ninja)
     
      FactoryBot.define('village', {
        id: () => Faker.random.uuid(),
        name: () => Faker.name.findName(),
        members: () => FactoryBot.buildList<Ninja>('ninja', 2)
      }, Village)
     
      export {
        FactoryBot
      }

    3. And then we'd just use them on our tests!

      // ../src/models/ninja.model.spec.ts
     
      import { FactoryBot } from '../src/tests'
     
      import { Ninja, NinjaRank, Village } from '.'
     
      export class NinjaSpec {
        let instance: Ninja
     
        before(() => {
          instance = FactoryBot.build('ninja', { name: 'Kakashi Hatake' })
        })
     
        it('builds a Ninja! 👹', () => {
          expect(instance).to.be.an
            .instanceof(Ninja)
        })
      }

    More

    Factory-bot-ts also allow us to..

    1. Define untyped factories with static data

      FactoryBot.define('ninja', {
        id: 1,
        name: 'Sasuke Uchiha',
        username: 'sasuke',
        level: NinjaRank.GENIN,
        sensor: false,
        sharingan: true
      })
     
      FactoryBot.build('ninja') /* => {
        id: 1,
        name: 'Sasuke Uchiha',
        username: 'sasuke',
        level: 'Genin',
        sensor: false,
        sharingan: true
      } */

    2. Define factories with type checking

      FactoryBot.define<Ninja>('ninja', {
        id: 1,
        name: 'Sasuke Uchiha',
        username: 'sasuke',
        level: NinjaRank.GENIN,
        sensor: false
      }, Ninja)
     
      FactoryBot.build('ninja') /* => Ninja {
        id: 1,
        name: 'Sasuke Uchiha',
        username: 'sasuke',
        level: 'Genin',
        sensor: false
      } */

    3. Define factories with Dynamic data

      FactoryBot.define('ninja', {
        id: () => Faker.random.number(),
        name: () => Faker.name.findName(),
        username: () => Faker.internet.userName(),
        level: () => FactoryBot.rand(NinjaRank),
        sensor: () => sample([true, false])
      }, Ninja)
     
      FactoryBot.build('ninja') /* => Ninja {
        id: 43748,
        name: 'Martine Romaguera MD',
        username: 'Kaleb_Homenick',
        level: 'Jonin',
        sensor: true
      } */

    4. Define factories with custom, random and sequenced data

      FactoryBot.define('ninja', {
        id: () => Faker.random.number(),
        name: () => Faker.name.findName(),
        username: () => FactoryBot.seq(seq => `${Faker.internet.userName()}_${seq}`),
        level: () => FactoryBot.rand(NinjaRank),
        sensor: () => sample([true, false])
      }, Ninja)
     
      FactoryBot.build<Ninja>('ninja', { name: 'Uzimaki Naruto' }) /* => Ninja {
        id: 11941,
        name: 'Uzimaki Naruto',
        username: 'Art_Crist36_1',
        level: 'Genin',
        sensor: true
      } */
     
      FactoryBot.build<Ninja>('ninja', { name: 'Sasuke Uchiha', username: 'sasuke-kun' }) /* => Ninja {
        id: 52565,
        name: 'Sasuke Uchiha',
        username: 'sasuke-kun',
        level: 'Chuunin',
        sensor: false
      } */

    5. Define chained factories

      FactoryBot.define('ninja', {
        id: () => Faker.random.number(),
        name: () => Faker.name.findName(),
        username: () => FactoryBot.seq(seq => `${Faker.internet.userName()}_${seq}`),
        level: () => FactoryBot.rand(NinjaRank),
        sensor: () => sample([true, false])
      }, Ninja)
     
      FactoryBot.define('village', {
        id: () => Faker.random.uuid(),
        name: 'Leaf',
        members: () => FactoryBot.buildList<Ninja>('ninja', 2)
      }, Village)
     
      FactoryBot.build('village') /* => Village {
        id: '7ec17407-cfdb-4a3f-b434-de788eb41591',
        name: 'Leaf',
        members: [ Ninja {
          id: 11941,
          name: 'Herta Hane',
          username: 'Kaleb_Homenick_5',
          level: 'Genin',
          sensor: true
        }, Ninja {
          id: 52565,
          name: 'Corbin Koss',
          username: 'Art_Crist36_6',
          level: 'Genin',
          sensor: false
        }]
      } */

    6. Extend existing factories in order to generate specialized data

      FactoryBot.define<Ninja>('ninja', {
        id: 1,
        name: 'Kakashi Hatake',
        username: 'kakashi',
        level: NinjaRank.GENIN,
        sensor: false
      }, Ninja)
     
      FactoryBot.extend<Ninja>('ninja', 'jōnin', {
        level: NinjaRank.JONIN
      })
     
      FactoryBot.build<Ninja>('ninja') /* => Ninja {
        id: 1,
        name: 'Kakashi Hatake',
        username: 'kakashi',
        level: Genin,
        sensor: false
      } */
     
      FactoryBot.build<Ninja>('jōnin') /* => Ninja {
        id: 1,
        name: 'Kakashi Hatake',
        username: 'kakashi',
        level: Jōnin,
        sensor: false
      } */

    For more examples, please, check out the project's specs.

    Dependencies

    To run this project we need to have:

    Development

    1. Install the dependencies above
    2. $ git clone https://github.com/roalcantara/factory-bot-ts.git - Clone the project
    3. $ cd factory-bot-ts - Go into the project folder
    4. $ yarn - Run the setup script

    Running specs

    $ yarn test to run the specs

    How to contribute

    Code of Conduct

    Everyone interacting in the factory-bot-ts project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

    License

    The package is available as open source under the terms of the CC BY-SA 4.0.

    Install

    npm i factory-bot-ts

    DownloadsWeekly Downloads

    498

    Version

    0.1.5

    License

    CC-BY-SA-4.0

    Unpacked Size

    104 kB

    Total Files

    20

    Last publish

    Collaborators

    • roalcantara