Factory Sequence: bug-fix + new methods for setting, generating and rewinding #1742
Merged
neilvcarvalho merged 3 commits intothoughtbot:mainfrom Jun 2, 2025
Merged
Factory Sequence: bug-fix + new methods for setting, generating and rewinding #1742neilvcarvalho merged 3 commits intothoughtbot:mainfrom
neilvcarvalho merged 3 commits intothoughtbot:mainfrom
Conversation
Member
neilvcarvalho
left a comment
There was a problem hiding this comment.
Thank you so much for this awesome contribution! It seems correct as far as I've read, though I'm still going to test more thoroughly later.
The comments are mostly supplementary to the code - specs and documentation. I reviewed it in a few batches and ended up adding lots of them 😅 I can take over if you'd like.
Contributor
Author
|
Hi @neilvcarvalho, happy for you to take over and make any changes you want. 👍 |
Contributor
Author
|
Hi @neilvcarvalho, I've seen the comments about the sequence bug. Is there anything I can do to help speed this up for you? 🏎️ |
:generate and :generate_list expanded to work with factory sequences: - generate(:sequence_name) - generate(:factory_name, :sequence_name) - generate_list(:sequence_name, 3) - generate_list(:factory_name, :sequence_name, 3) :rewind_seqence added to rewind individual sequences - rewind_sequence(:factory_name, :trait_name, :sequence_name) :set_sequence added to set the sequence to a new value: - set_sequence(:sequence_name, new_value) - set_sequence(:factory_name, :sequence_name, new_value) Test coverage at 100% & docs updated.
When calling :peek on the Enumerator class, internally it calls :next. There was an issue when stubbing the :next method to raise an exception, then triggering it when calling :peek. This was only an issue in Truffleruby.
a5b6686 to
ef07e6b
Compare
Member
|
@CodeMeister Thanks for offering help. I'm finished with my changes and I'm going to merge this PR soon. |
neilvcarvalho
approved these changes
Jun 2, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
I found an odd bug when inheriting sequences that don't have a block. With no block to compare, determining if it was an inherited sequence was problematic.
The solution was to give each sequence it's own unique reference (URI).
Once this was in place, it became an easy process to expand
:generate,generate_listand:rewind_sequencesto target factory sequences, not just the global ones as it does now.Being able to generate factory sequences makes testing much easier, without have to build multiple objects just to increment the sequence!
It also became a simple process to allow the sequence to be set to a different value, either for testing or from the console.
Full tests & documentation are included.
BugFix
When a factory trait that includes a sequence with no block is included in a child factory build, an exception is raised.
To solve this, each sequence now includes a list of URIs that identify it. (the multiple URIs allow for factory and trait aliases)
There is no change to the existing user API.
Sequence URIs
Each URI is composed of up to three names:
Here's a complete example showing the URIs, by calling
generatefor the matching sequence:You can get the full details in the updated docs.
Generating sequences & lists
generateandgenerate_listwork as normal. Following the URI definition above, a global sequence URI is simply it's name.Factory sequences are generated using their URI:
generate(:my_factory, :sequence)Rewinding sequences
FactoryBot.rewind_sequencesis untouched and still rewinds all sequences.'FactoryBot.rewind_sequence(URI)` is a new method that will rewind the targed sequence:
Setting the sequence value
FactoryBot.set_sequence(URI, new_value)is a new method that allows the sequence to be set to a new value, provided:Logic
If it's an Integer sequence, and the new value is an integer, set it directly.
If it responds to
:find_index, use it because it is faster & doesn't change the sequence if the value is not foundFor all other sequences: rewind the sequence, then keep incrementing until a match is found or the search times-out. Reset the original value if not found.
The timeout defaults to 3 seconds, but can be changed with an ENV variable.
Internal helper methods for developers
FactoryBot::Sequence.find(URI)will return the sequence that matches the given URI, checking both global and inline sequences.FactoryBot::Sequence.sequence_setting_timeoutwill return the number of seconds allowed for setting a sequence to a new value.