test-data-bot
Advanced tools
Comparing version 0.5.0 to 0.6.0
@@ -0,1 +1,5 @@ | ||
### 0.6.0 [03 August] | ||
- rebuilt to enable fully nested builders | ||
### 0.5.0 [03 August] | ||
@@ -2,0 +6,0 @@ |
{ | ||
"name": "test-data-bot", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "Generate test data for your tests easily.", | ||
@@ -5,0 +5,0 @@ "engines": { |
109
src/index.js
@@ -0,58 +1,27 @@ | ||
const Generator = require('./generator') | ||
class Field { | ||
constructor(name, value) { | ||
this.name = name | ||
this.value = value | ||
this.sequenceStart = 1 | ||
constructor(name, generator) { | ||
this._name = name | ||
this._generator = generator | ||
this._sequenceCount = 1 | ||
} | ||
recurseOntoBuilder(builderType, fieldName, nextBuilder) { | ||
return new Field( | ||
`${builderType}(${fieldName})`, | ||
nextBuilder | ||
).generateValue() | ||
} | ||
generateValue() { | ||
if (this.value && this.value._testDataBotType) { | ||
if (this.value._testDataBotType === 'fakeData') { | ||
return this.value.fakeFn(require('faker')) | ||
} else if (this.value._testDataBotType === 'sequenceData') { | ||
const sequenceResponse = this.value.sequenceFn(this.sequenceStart++) | ||
if (sequenceResponse.hasOwnProperty('_testDataBotType')) { | ||
return this.recurseOntoBuilder( | ||
'sequence', | ||
this.name, | ||
sequenceResponse | ||
) | ||
} else { | ||
return sequenceResponse | ||
} | ||
} else if (this.value._testDataBotType === 'perBuild') { | ||
return this.value.buildFn() | ||
} else if (this.value._testDataBotType === 'oneOf') { | ||
const randomIndex = Math.floor( | ||
Math.random() * this.value.oneOfOptions.length | ||
) | ||
return this.value.oneOfOptions[randomIndex] | ||
} else if (this.value._testDataBotType === 'arrayOf') { | ||
return Array.from({ length: this.value.count }).map(_ => { | ||
return this.recurseOntoBuilder( | ||
'arrayOf', | ||
this.name, | ||
this.value.builder | ||
) | ||
}) | ||
} else { | ||
throw new Error( | ||
`Unknown test-data-bot type ${this.value._testDataBotType}` | ||
) | ||
} | ||
if (this._generator instanceof Generator) { | ||
return this._generator.generate({ | ||
sequenceCount: this._sequenceCount++, | ||
}) | ||
} else { | ||
// primitive type so just return it as is | ||
return this.value | ||
// must be a primitive value | ||
return new Generator().fullyExpandReturn( | ||
this._generator, | ||
this._sequenceCount++ | ||
) | ||
} | ||
} | ||
generateIntoObject(overrides, resultingObject) { | ||
return Object.assign({}, resultingObject, { | ||
[this.name]: overrides[this.name] || this.generateValue(), | ||
[this._name]: overrides[this._name] || this.generateValue(), | ||
}) | ||
@@ -64,3 +33,3 @@ } | ||
constructor(name) { | ||
this.name = name | ||
this._name = name | ||
this._fields = [] | ||
@@ -93,29 +62,29 @@ } | ||
const fake = fakeFn => ({ | ||
_testDataBotType: 'fakeData', | ||
fakeFn, | ||
}) | ||
const fake = fakeFn => | ||
new Generator('fake', { | ||
fakeFn, | ||
}) | ||
const sequence = sequenceFn => ({ | ||
_testDataBotType: 'sequenceData', | ||
sequenceFn, | ||
}) | ||
const sequence = sequenceFn => | ||
new Generator('sequence', { | ||
sequenceFn, | ||
}) | ||
const perBuild = buildFn => ({ | ||
_testDataBotType: 'perBuild', | ||
buildFn, | ||
}) | ||
const perBuild = buildFn => | ||
new Generator('perBuild', { | ||
buildFn, | ||
}) | ||
const incrementingId = () => sequence(x => x) | ||
const oneOf = (...oneOfOptions) => ({ | ||
_testDataBotType: 'oneOf', | ||
oneOfOptions, | ||
}) | ||
const oneOf = (...oneOfOptions) => | ||
new Generator('oneOf', { | ||
oneOfOptions, | ||
}) | ||
const arrayOf = (builder, count = 1) => ({ | ||
_testDataBotType: 'arrayOf', | ||
builder, | ||
count, | ||
}) | ||
const arrayOf = (builder, count = 1) => | ||
new Generator('arrayOf', { | ||
builder, | ||
count, | ||
}) | ||
@@ -122,0 +91,0 @@ const bool = () => oneOf(true, false) |
@@ -132,5 +132,6 @@ const { | ||
}) | ||
const user = userBuilder() | ||
expect(user.email).toMatch(/(\w+)1/) | ||
expect(user.email).toMatch(/(.+)1/) | ||
}) | ||
@@ -174,2 +175,71 @@ | ||
}) | ||
it('allows deeply nested fake data', () => { | ||
const itemBuilder = build('Item').fields({ | ||
images: perBuild(() => ({ | ||
medium: arrayOf(fake(f => f.image.imageUrl()), 3), | ||
large: arrayOf(fake(f => f.image.imageUrl()), 3), | ||
original: arrayOf(fake(f => f.image.imageUrl()), 3), | ||
})), | ||
}) | ||
const item = itemBuilder() | ||
expect(item.images.medium).toEqual( | ||
expect.arrayContaining(Array(3).fill(expect.any(String))) | ||
) | ||
expect(item.images.large).toEqual( | ||
expect.arrayContaining(Array(3).fill(expect.any(String))) | ||
) | ||
expect(item.images.original).toEqual( | ||
expect.arrayContaining(Array(3).fill(expect.any(String))) | ||
) | ||
expect(item.images.medium[0]).toMatch(/lorempixel/) | ||
}) | ||
it('allows deeply nested array data', () => { | ||
const itemBuilder = build('Item').fields({ | ||
images: { | ||
medium: [fake(f => f.image.imageUrl())], | ||
}, | ||
}) | ||
const item = itemBuilder() | ||
expect(item.images.medium).toEqual( | ||
expect.arrayContaining(Array(1).fill(expect.any(String))) | ||
) | ||
expect(item.images.medium[0]).toMatch(/lorempixel/) | ||
}) | ||
it('lets oneOf take a builder', () => { | ||
const fooBuilder = build('Foo').fields({ | ||
name: 'foo', | ||
}) | ||
const barBuilder = build('Bar').fields({ | ||
name: 'bar', | ||
}) | ||
const testBuilder = build('Testing').fields({ | ||
data: oneOf(fooBuilder, barBuilder), | ||
}) | ||
const test = testBuilder() | ||
expect(test.data.name === 'foo' || test.data.name === 'bar').toEqual(true) | ||
}) | ||
it('does the right thing with arrays and sequences', () => { | ||
const userBuilder = build('User').fields({ | ||
emails: arrayOf(sequence(x => `jack${x}@gmail.com`), 3), | ||
}) | ||
const user = userBuilder() | ||
expect(user.emails).toEqual([ | ||
'jack1@gmail.com', | ||
'jack2@gmail.com', | ||
'jack3@gmail.com', | ||
]) | ||
}) | ||
}) |
15143
8
368