Changelog

View Source

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.4.1] - 2026-03-11

Fixed

  • build_params?: false no longer raises when used on non-struct factories (or inherited from a parent module). Non-struct factories always generate their build_* functions regardless of this option. Previously, the compile-time validation predated barebones factories and incorrectly rejected this combination.

[0.4.0] - 2026-03-10

Changed

  • Breaking: Non-struct factories now generate build_*/0,1 and build_*_list/1,2 instead of build_*_params/0,1 and build_*_params_list/1,2. The _params suffix was misleading for factories that can return any value. Struct factories are unchanged.

[0.3.2] - 2026-03-10

Added

  • params_for_* and string_params_for_* functions for Ecto schema factories. These build a struct then strip Ecto metadata (__meta__, autogenerated IDs, NotLoaded associations, belongs_to structs), returning a clean map for changesets or controller tests. Foreign keys are set automatically for persisted belongs_to associations.
  • Unlike ExMachina's params_for, nil values are preserved (not silently dropped) and string_params_for leaves struct values like DateTime untouched (not converted to maps).

[0.3.1] - 2026-03-10

Added

  • Factory bodies can now return arbitrary values (strings, keyword lists, tuples, nil, etc.), not just maps. Factories without :struct are no longer restricted to returning maps.
  • Lazy evaluation now works in keyword lists — 0-arity and 1-arity function values are resolved at build time, matching the existing behavior for maps and structs.

Fixed

  • build_*_params_list/1 (single-arity convenience) now calls the factory with its actual default argument instead of always passing %{}. Previously, factories with non-map defaults would crash when using the list builder without explicit arguments.

[0.3.0] - 2026-03-10

Changed

  • Breaking: Renamed params? option to build_params? for consistency with build_struct?

[0.2.2] - 2026-03-10

Added

  • Duplicate option warnings: FactoryMan now emits a compile-time Logger.warning when a child factory module or deffactory specifies an option that is already defined by the parent with the same value. Helps catch redundant copy-pasted options.
  • suppress_duplicate_option_warning: true option to silence the warning at module or factory level when the duplication is intentional. This option does not propagate to child modules.

[0.2.1] - 2026-03-09

Added

  • :as option for defvariant to customize the generated function name. By default, variant functions are named {variant}_{base} (e.g. build_admin_user_struct). The :as option overrides this combined name (e.g. as: :mod generates build_mod_struct instead of build_moderator_user_struct).

[0.2.0] - 2026-03-08

Added

  • build_params?: false option for deffactory. When set, the factory body returns a struct directly instead of a params map. No build_*_params functions are generated. Useful for complex factories that need full control over struct construction (e.g. resolving associations from other factories, conditional logic). Can be set at module level or factory level.
  • defvariant macro for defining variant factories that wrap a base factory. The variant body is a preprocessor: it transforms caller params before delegating to the base factory. Generates the full set of named functions (e.g. build_admin_user_struct/0,1, insert_admin_user!/0,1,2).
  • Compile-time validation: build_params?: false without struct: raises ArgumentError
  • Compile-time validation: defvariant referencing undefined base factory raises ArgumentError

Fixed

  • Flaky "circular sequence cycles through values" test that depended on test ordering. Added FactoryMan.Sequence.reset() to ensure predictable starting position.

[0.1.1] - 2026-03-07

Fixed

  • Factory-level hooks were being flattened into top-level options instead of staying nested under the :hooks key. This caused _factory_opts() and _<name>_factory_opts() debug functions to return a polluted keyword list with hook keys (e.g. :after_insert) mixed in alongside configuration keys (e.g. :repo, :struct). Hooks now stay properly nested.
  • Fixed several inaccurate examples in moduledoc and README (e.g. build_api_payload() corrected to build_api_payload_params(), missing Map.merge calls in examples)

Changed

  • Replaced List.pop_at with Enum.at in FactoryMan.Sequence for list-based sequences (avoids constructing an unused remainder list)
  • Reorganized demo factory definitions into logical sections: core, lazy evaluation, sequences, factory options, and parameter patterns
  • Removed redundant demo factories (params_only, with_custom_param_name) and renamed with_after_build_params_hook to hooked
  • Refactored test suite: reorganized into describe blocks by feature, removed ~21 redundant tests, fixed misleading test names and broken assertions. 69 tests remain (was 90), all meaningful.
  • Added Dialyzer configuration (plt_add_apps: [:ex_unit]). Zero warnings.
  • Expanded hooks documentation with pipeline diagram, reference table, precedence rules, and practical examples
  • Added lazy evaluation ordering warning explaining that 1-arity lazy functions receive the pre-evaluation map
  • Rewrote AGENTS.md with usage rules, canonical patterns, and anti-patterns

[0.1.0] - 2026-02-08

Added

  • Initial alpha release
  • deffactory macro for defining factories
  • Automatic struct building with build_*_struct functions
  • Database insertion with insert_*! functions
  • Params-only factories without database dependency (i.e. only has build_*_params and build_*_params_list)
  • Sequence generation for unique values
  • Lazy evaluation for computed attributes
  • Factory inheritance via :extends option
  • Hooks system for custom transformations
  • List factories for bulk data creation (*_list variants)
  • Support for embedded schemas (Build struct, but do not attempt to generate insert_* functions)