Module: FactorySloth::ExecutionCheck
- Defined in:
- lib/factory_sloth/execution_check.rb
Overview
This adds code that makes a spec run fail and thus prevents changes if: a) the patched factory in the given line is never called b) the built record was persisted later anyway The rationale behind a) is that things like skipped examples should not be broken. The rationale behind b) is that not much DB work would be saved, but diff noise would be increased and ease of editing the example reduced.
Note: the caller column is only available in a roundabout way in Ruby >= 3.1, bugs.ruby-lang.org/issues/17930, 19452, so multiple replacements in one line would not be validated correctly iff they had mixed validity.
Constant Summary collapse
- FACTORY_UNUSED_CODE =
77- FACTORY_PERSISTED_LATER_CODE =
78
Class Method Summary collapse
Class Method Details
.for(line, variant) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/factory_sloth/execution_check.rb', line 16 def self.for(line, variant) " ; defined?(FactoryBot) && defined?(RSpec) && RSpec.configure do |config|\n records_by_line = {} # track records initialized through factories per line\n\n FactoryBot::Syntax::Methods.class_eval do\n original_variant = instance_method(\"\#{variant}\") # e.g. build\n\n define_method(\"\#{variant}\") do |*args, **kwargs, &blk|\n result = original_variant.bind_call(self, *args, **kwargs, &blk)\n list = records_by_line[caller_locations(1, 1)&.first&.lineno] ||= []\n list.concat([result].flatten) # to work with single, list, and pair\n result\n end\n end\n\n config.after(:suite) do\n records = records_by_line[\#{line}]\n records&.any? || exit!(\#{FACTORY_UNUSED_CODE})\n unless \"\#{variant}\".include?('stub') # factory_bot stub stubs persisted? as true\n records.any? { |r| r.respond_to?(:persisted?) && r.persisted? } &&\n exit!(\#{FACTORY_PERSISTED_LATER_CODE})\n end\n end\n end\n RUBY\nend\n" |