I'm very pleased to announce the first release of Smokestack, a library for generating test fixtures for your Ash resources.
Smokestack uses a Spark, the system behind all the DSLs in the Ash ecosystem to define very simple factories:
defmodule MyApp.Factory do use Smokestack factory Character do attribute :name, &Faker.StarWars.character/0 attribute :affiliation, choose(["Galactic Empire", "Rebel Alliance"]) end end
Smokestack uses the introspection built in to Spark to introspect your resources and validate that each attribute refers to an actual attribute, what relationships are defined and how to build them.
Each attribute uses a template to generate a value when building a factory. Templates can be anything that implements the
Smokestack.Template protocol. This protocol is automatically implemented for functions with arities zero through two - meaning you can just drop in your own functions - or use one of the built-in helpers.
Sometimes you need to define more than one factory for a resource to put it in a slightly different state. You can do this using variants, which allow you to name the factory with an atom.
Here's an example defining an alternate
:trek variant for the character factory defined above:
factory Character, :trek do attribute :name, choose(["J.L. Pipes", "Severn", "Slickback"]) attribute :affiliation, choose(["Entrepreneur", "Voyager"]) end
Smokestack can use your factory definitions to build records in your data storage using
Ash.Seed.seed!/2 via the
insert!/2 functions which are automatically defined on your factory module. It can also automatically build related records by passing a
build option, much like an Ash load statement and load relationships, calculations and aggregates.
I hope that Smokestack improves the ergonomics of writing tests for Ash applications and look forward to seeing how it works (and how it doesn't) in the future. Happy coding!