Changelog
View SourceAll 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?: falseno longer raises when used on non-struct factories (or inherited from a parent module). Non-struct factories always generate theirbuild_*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,1andbuild_*_list/1,2instead ofbuild_*_params/0,1andbuild_*_params_list/1,2. The_paramssuffix was misleading for factories that can return any value. Struct factories are unchanged.
[0.3.2] - 2026-03-10
Added
params_for_*andstring_params_for_*functions for Ecto schema factories. These build a struct then strip Ecto metadata (__meta__, autogenerated IDs,NotLoadedassociations,belongs_tostructs), returning a clean map for changesets or controller tests. Foreign keys are set automatically for persistedbelongs_toassociations.- Unlike ExMachina's
params_for, nil values are preserved (not silently dropped) andstring_params_forleaves struct values likeDateTimeuntouched (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
:structare 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 tobuild_params?for consistency withbuild_struct?
[0.2.2] - 2026-03-10
Added
- Duplicate option warnings: FactoryMan now emits a compile-time
Logger.warningwhen a child factory module ordeffactoryspecifies an option that is already defined by the parent with the same value. Helps catch redundant copy-pasted options. suppress_duplicate_option_warning: trueoption 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
:asoption fordefvariantto customize the generated function name. By default, variant functions are named{variant}_{base}(e.g.build_admin_user_struct). The:asoption overrides this combined name (e.g.as: :modgeneratesbuild_mod_structinstead ofbuild_moderator_user_struct).
[0.2.0] - 2026-03-08
Added
build_params?: falseoption fordeffactory. When set, the factory body returns a struct directly instead of a params map. Nobuild_*_paramsfunctions 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.defvariantmacro 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?: falsewithoutstruct:raisesArgumentError - Compile-time validation:
defvariantreferencing undefined base factory raisesArgumentError
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
:hookskey. 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 tobuild_api_payload_params(), missingMap.mergecalls in examples)
Changed
- Replaced
List.pop_atwithEnum.atinFactoryMan.Sequencefor 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 renamedwith_after_build_params_hooktohooked - Refactored test suite: reorganized into
describeblocks 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
deffactorymacro for defining factories- Automatic struct building with
build_*_structfunctions - Database insertion with
insert_*!functions - Params-only factories without database dependency (i.e. only has
build_*_paramsandbuild_*_params_list) - Sequence generation for unique values
- Lazy evaluation for computed attributes
- Factory inheritance via
:extendsoption - Hooks system for custom transformations
- List factories for bulk data creation (
*_listvariants) - Support for embedded schemas (Build struct, but do not attempt to generate
insert_*functions)