BUGFIX: Parent/Child implicit trait results depend on build order. #1717
+46
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes: #1716
Summary
When a parent with an implicit trait is built at the same time as a child
that inherits, and calls, that trait, the result changes based on which is built first.
In the scenario below a
:user
factory and its child factory:admin
areboth created at the same time, but in a different order within each test.
Keeping everything the same, except the order in which the factories are run, raises a different error in each test.
Scenario
Test User First
Test Admin First
Note:
There is no issue when either factory is built and tested on their own,
only when built together and an implied trait is used by both.
The Cause
The cause, was that an implicit trait is evaluated in the context of its
first run, storing the reference to the implied trait.
In the scenario above where
:admin
is built first:new_name
call to the admin's:new_name
trait:change_name
trait has already been evaluated (still pointing to admin's:new_name
)The Solution
When running a child factory, it inherits the parent's traits. The solution was two-fold:
Note: Cloning ALL inherited traits is a bit over-kill, but it's actually faster
than detecting and cloning only the implicit traits; and should help future-proof any other
context issues.
Changes
In
Definition
I added a new helper method to return an array of the names for all traits already defined:In
Trait
I added a method to create a new 'clean' clone of the trait:In
Factory
I added:defined_traits_names
to the@definition
delegation list:I added a new private method
:inherit_parent_traits
to manage the inheritance:And finally I altered
:compile
to call the new:inherit_parent_traits
method:Testing
spec/acceptance/traits_spec
.😃