lambdaisland / lambdaisland/facai
Complex traits
Nobody has claimed this yet.
- Dominant language
- Clojure
- Stars
- 48
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Problem statement
I would like to reference other traits and set field data conditionally within traits.
Background / Examples
In another fixture-replacement library factory_bot, traits are defined using Ruby blocks, which are basically anonymous functions/callbacks. This allows for a given trait to perform more complex logic than just column value substitution. Here are some examples.
A trait can reference another trait, allowing for deduplication:
factory :order do
trait :completed do
completed_at { 3.days.ago }
end
trait :refunded do
completed
refunded_at { 1.day.ago }
end
end
A trait can set multiple attributes based on random data:
factory :order do
trait :chaos do
if rand(1) == 0
status { :in_progress }
completed_at { nil }
else
status { :complete }
completed_at { 1.day.ago }
end
end
end
In factory_bot, they can also hold before/after handlers, but that's outside of the scope of this issue.
Potential solutions
Base idea is that trait definitions could take a function that returns a map instead of a map literal. Building on that are a number of other solutions:
- Referencing other traits could be a "lazy reference", so it's not evaluated until the factory produces an instance. Not sure how to apply it without state.
- There could be a helper function that accepts and returns a map (to be used as the return value of the trait function), but has overloads for referencing other traits or performing other actions.
- The trait function itself could be a 1-parameter function that provides the factory map, allowing for threading changes to it directly (instead of relying on merging in values after). Along with helper functions, this could allow for referencing traits as well (
(apply-trait factory-map ::trait-name)).
I'm willing and interested in helping build this functionality, if y'all are interested!
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing facai’s current trait-definition API and factory-building path, then compare it with the factory_bot examples in the issue. Determine how trait references and conditional field maps should be represented, and define tests showing that referenced traits and conditional attributes work when a factory produces an instance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- clojure
- Domain
- testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100