0.3.0 • Published 7 months ago

@binary-stars/bs-uuid-generator v0.3.0

Weekly downloads
-
License
MIT
Repository
bitbucket
Last release
7 months ago

README

When you create objects with auto-generated IDs then it's cumbersome to test them for equality because the generated attribute value is (duh!) auto-generated. This library enables you to inject the UUID generator via the strategy pattern and choose the appropriate implementation for testing as opposed to production. As for the production-ready implmentation, you can either use UuidGeneratorUuidv4Impl (which uses the "uuid" npm package) or use any other tool via UuidGeneratorDelegatingImpl. Brought to you by binary stars GmbH, written in TypeScript and tested with 100% coverage.

Installation

  • npm i --save @binary-stars/bs-uuid-generator

How to use

In your production code:

// this type is just a tweak, you can use whatever
type Entity<T> = T & {
  id: string
}

type User = {
  name: string
}

// In this example I'm injecting the uuidGenerator into the Data Access Object.
// I think this is a nice design choice but you can have the uuid generated whereever you want instead.
class MyUserDaoWithAutoId {
  constructor(private uuidGenerator: UuidGenerator) {}

  put(user: User): Entity<User> {
    return {
      ...user,
      id: this.uuidGenerator.create(),
    }
  }
}

In your production initialization/dependency injection/factory code:

import UuidGeneratorUuidv4Impl from '@binary-stars/bs-uuid-generator/dist/UuidGeneratorUuidv4Impl'
const dao = new MyUserDaoWithAutoId(new UuidGeneratorUuidv4Impl())

/* ALTERNATIVELY, use any other way to create a UUID Generator */
import UuidGeneratorDelegatingImpl from '@binary-stars/bs-uuid-generator/dist/UuidGeneratorDelegatingImpl'

const genSimpleRandom = () => {
  let out = ''
  for (let i = 0; i < 32; i++) {
    const rand = Math.floor(Math.random() * 16)
    if (rand < 10) {
      out += `${rand}`
    } else {
      out += String.fromCharCode(rand + 87)
    }
  }
  return out
}

const dao = new MyUserDaoWithAutoId(
  new UuidGeneratorDelegatingImpl(genSimpleRandom),
)

In your tests

import UuidGenerator, {
  isUuid,
  UuidGeneratorDelegatingImpl,
} from '@binary-stars/bs-uuid-generator/dist/UuidGenerator'
import {
  UuidGeneratorFixedImpl,
  UuidGeneratorSequenceImpl,
} from '@binary-stars/bs-uuid-generator/dist/UuidGenerators'


let dao: MyUserDaoWithAutoId

describe('Demo', () => {
  test("Production Mode: in production we want to use a ROBUST implementation, so let's use the uuid4 lib", () => {
    // given
    dao = new MyUserDaoWithAutoId(new UuidGeneratorUuidv4Impl())

    // when
    const actual = dao.put({name: 'Joey'})

    // then
    expect(actual.name).toEqual('Joey')
    expect(actual.id).toBeTruthy()
    expect(isUuid(actual.id)).toBe(true)
  })

  test('... but we could use any other implementation just as well', () => {
    // given
    const genSimpleRandom = () => {
      let out = ''
      for (let i = 0; i < 32; i++) {
        const rand = Math.floor(Math.random() * 16)
        if (rand < 10) {
          out += `${rand}`
        } else {
          out += String.fromCharCode(rand + 87)
        }
      }
      return out
    }

    dao = new MyUserDaoWithAutoId(
      new UuidGeneratorDelegatingImpl(genSimpleRandom),
    )

    // when
    const actual = dao.put({name: 'Joey'})

    // then
    expect(actual.name).toEqual('Joey')
    expect(actual.id).toBeTruthy()
    expect(isUuid(actual.id)).toBe(true)
  })


  test('Testing Mode: in testing we want to use a test friendly implementation, e.g. one that always yields the same value', () => {
    // given
    dao = new MyUserDaoWithAutoId(UuidGeneratorFixedImpl.ONE)

    // when
    let actual = dao.put({name: 'Joey'})

    // then
    expect(actual).toEqual({
      name: 'Joey',
      id: '00000000-0000-0000-0000-000000000001',
    })
    // the same fact as above:
    expect(actual.id).toEqual(UuidGeneratorFixedImpl.ONE.create())

    // when 2
    actual = dao.put({name: 'CJ'})
    // then 2
    expect(actual).toEqual({
      name: 'CJ',
      id: '00000000-0000-0000-0000-000000000001',
    })
    // the same fact as above:
    expect(actual.id).toEqual(UuidGeneratorFixedImpl.ONE.create())
  })


  test('Testing Mode: ... or an implementation that works like a sequence', () => {
    // given
    const uuidGenerator = new UuidGeneratorSequenceImpl()
    dao = new MyUserDaoWithAutoId(uuidGenerator)

    // when
    let actual = dao.put({name: 'Joey'})

    // then
    expect(actual).toEqual({
      name: 'Joey',
      id: UuidGeneratorSequenceImpl.get(1),
    })
    // the same fact as above:
    expect(actual.id).toEqual('00000000-0000-0000-0000-000000000001')

    // when 2
    actual = dao.put({name: 'CJ'})
    // then 2
    expect(actual).toEqual({
      name: 'CJ',
      id: UuidGeneratorSequenceImpl.get(2),
    })
    // the same fact as above:
    expect(actual.id).toEqual('00000000-0000-0000-0000-000000000002')
  })
})

Contribution guidelines

  • 100% code coverage
  • run npm run review to check style, eslint, run tests and check coverage

About us

  • binary stars GmbH, Hausinger Str. 8, 40764 Langenfeld, Germany
  • #clean-code #clean-architecture #tdd #xp #agile
  • We offer a CTO2Go for your software projects & products + developers, QA engineers and agile project managers
  • Wanna know how we achieve 100% coverage EVERY TIME? Contact us about our training & consulting services.
  • Our open source projects: https://www.binary-stars.eu/en/open-source-projects/

Version History

  • 0.3.0
    • Remove dashes if dashes = false
    • Bump to 0.3 to indicate 'more major' change
  • 0.2.4
    • Improve build process
    • Fix FormattingDecorator as it wasn't really a decorator before
  • 0.2.3 (finally public)
    • improve readme and demo testss
  • 0.2.2 (private)
    • fix README & CI script
  • 0.2.1 (private)
    • fix README & CI script
  • 0.2.0 (private)
    • create README
  • 0.1.0 (private)
    • first working release
0.3.0

7 months ago

0.2.4

7 months ago

0.2.3

7 months ago

0.2.2

8 months ago

0.2.1

8 months ago

0.2.0

8 months ago

0.1.0

8 months ago