Only show the data that matters in your fixtures.
// Before: What data do you think matters about this card ? 😬
const card = {
title: "Batman rocks",
comments: [],
owner: {
username: "batman",
picture: "some-picture-of-batman.png"
}
}
// After: It's obvious, it's about the empty comments 😊
import {factory} from "@isthatcentered/charlies-factory"
const makeCardResource = factory({
// ...define your defaults
})
const card = makeCardResource( { comments: [] } )
npm i @isthatcentered/charlies-factory
At the end of the day, this thing makes objects.
You set up a default once and it feeds it back to you with a simple function call every time you need it.
Here's how to do that (keep on reading though, basic use is nice but it's intended to be way more usefull/powerfull thant that 😇)
import {factory} from "@isthatcentered/charlies-factory"
export const makeCard = factory({
title: "Title",
status: "done",
comments: [],
owner: makeUser( ), // You can totally nest factories
})
// Then enjoy the simplicity of it all
const wrapper = shallow(<KanbanCard card={makeCard()} />)
This is the selling point of this thing. Overrides are what will make your tests obvious by explicitely stating what data matters.
Let's say I want to test how my <KanbanCard/>
component from earlier behaves when the card has no comments.
import { makeCard } from "some-file-where-i-set-up-the-default-as-shown-in-basic-use"
test( `Comment indicator is hidden when card has no comments`, () => {
const card = makeCard( { comments: [] } ),
wrapper = shallow(<KanbanCard card={card} />)
expect( wrapper.find( CardCommentsIndicator ).props().display ).toBe( false )
} )
And just for kicks, here's how the test would look like without charlies-factory. Try to find the data that matters 😳
// (This is WITHOUT charlies-factory)
test( `Comment indicator is hidden when card has no comments`, () => {
const card = {
title: "Batman rocks",
comments: [],
owner: {
username: "batman",
picture: "some-picture-of-batman.png"
}
},
wrapper = shallow(<KanbanCard card={card} />)
expect( wrapper.find( CardCommentsIndicator ).props().display ).toBe( false )
} )
I've shown earlier (see basic use) that you can totally nest factories inside factories. But the way we did this earlier (by providing an object as default), the nested factory will only be executed once and therefore always return the same data.
You might not want that or might need to compute some data for the defaults.
It's easy, you can actually pass a function as default.
const seedFunction = (generator: FakerStatic, index: seedId) => { // Yes, we give you a data generator (Faker) because we're nice like that but more on that later 😇
const someComputedStuff = computeMeSomeStuffFromCurrentAppState(appState)
return {
id: index, // each factory you define starts it's own index sequence
status: someComputedStuff,
email: generator.internet.email()
// ... you get the ide
}
}
const makeThing = factory( seedFunction )
// The function will be executed every time you call the factory 😙
console.log(makeThing()) // {id: 1, status: "active", email: "whatever.com", ... }
console.log(makeThing()) // {id: 2, status: "disabled", email: "newEmail.com", ... }
The seed as function also work for the overrides and the states.
For overrides
const makeThing = factory({id: 0})
const overrides = (generator, index) => ({id: generator.random.number()})
console.log(makeThing(overrides)) // {id: 45 } (or whatever number has been generated)
For states
const states = {
"discounted": (generator, index) => ({
discount: generator.random.number()
}),
"inStock": (generator, index) => ({
stockCount: generator.random.number() // (I'm not doing Faker justice, it can do way much more than generate random numbers)
})
}
const makeThing = factory({stockCount: 1, discount: 0}, states)
console.log(makeThing({}, "discounted", "inStock")) // {discount: 20, stockCount: 42}
Dynamic data extravaganza
// Erh... @todo, sorry. But you get the idea, your factory can have a function as default, for a or every state you define, and for your last minute overrides if you want.
You can define default states for the generated objects like active
, done
or whatever you fancy.
I haven't had time to add docs for this yet but you can checkout the example right above or the src/features.spec.ts
for the how to use.
Sometimes, you need a bunch of objects. We got you covered with the pack
function. Think you want a pack
of things from the factory
.
Here's the how to
// We provide the loop index in case you need some ID 👮
const cards = pack(3, index => makeCard({id: index})) // Remember, you still have acces to overrides
Let me know at e.peninb@gmail.com or 🌟the repo.
You 🤟, let me know by opening an issue
Nice, open an issue and let's talk about this ! 👩🚀