npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@isthatcentered/charlies-factory

v1.4.0

Published

Makes making objects easy

Downloads

102

Readme

Make your tests obvious

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: [] } )  

Table of content

Installation

npm i @isthatcentered/charlies-factory 

How to use

Basic use

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()} />)

Overriding default data

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 )
} )

Dynamic data

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.

States

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.

Generating multiple items at a time

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

Give feedback

You're enjoying the package ?

Let me know at [email protected] or 🌟the repo.

Found a bug ?

You 🤟, let me know by opening an issue

Need a new feature ?

Nice, open an issue and let's talk about this ! 👩‍🚀