Module: Synthra::PropertyTesting
- Defined in:
- lib/synthra/property_testing.rb
Instance Method Summary collapse
-
#shrink_counterexample(schema_name, failing_record, registry: nil) {|Hash| ... } ⇒ Hash
Shrink a failing test case to find minimal counterexample.
-
#verify_property(schema_name, count: 100, seed: nil, mode: :random, registry: nil) {|Hash| ... } ⇒ Object
Verify a property holds for generated data.
-
#verify_property_stream(schema_name, count: 1000, seed: nil, mode: :random, registry: nil) {|Hash| ... } ⇒ Object
Verify a property holds for a stream of generated data.
Instance Method Details
#shrink_counterexample(schema_name, failing_record, registry: nil) {|Hash| ... } ⇒ Hash
Shrink a failing test case to find minimal counterexample
When a property fails, attempts to shrink the failing record to find a smaller counterexample.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/synthra/property_testing.rb', line 115 def shrink_counterexample(schema_name, failing_record, registry: nil, &block) registry ||= Registry.new schema = registry.schema(schema_name) current = failing_record.dup improved = true while improved improved = false # Try removing optional fields current.keys.each do |key| next unless schema.field(key)&.optional? candidate = current.dup candidate.delete(key) begin block.call(candidate) rescue RSpec::Expectations::ExpectationNotMetError # Still fails with smaller record current = candidate improved = true break end end # Try simplifying array values current.each do |key, value| next unless value.is_a?(Array) && value.length > 1 candidate = current.dup candidate[key] = value[0..0] # Single element begin block.call(candidate) rescue RSpec::Expectations::ExpectationNotMetError current = candidate improved = true break end end end current end |
#verify_property(schema_name, count: 100, seed: nil, mode: :random, registry: nil) {|Hash| ... } ⇒ Object
Verify a property holds for generated data
Generates multiple records from a schema and verifies a property holds for all of them. Raises if property fails for any record.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/synthra/property_testing.rb', line 51 def verify_property(schema_name, count: 100, seed: nil, mode: :random, registry: nil) registry ||= Registry.new schema = registry.schema(schema_name) records = schema.generate_many(count, seed: seed, mode: mode, registry: registry) records.each_with_index do |record, idx| begin yield(record) rescue RSpec::Expectations::ExpectationNotMetError => e raise RSpec::Expectations::ExpectationNotMetError, "Property failed for record #{idx + 1}/#{count} (seed: #{seed || 'random'}):\n" \ "#{e.}\n" \ "Record: #{record.inspect}" end end end |
#verify_property_stream(schema_name, count: 1000, seed: nil, mode: :random, registry: nil) {|Hash| ... } ⇒ Object
Verify a property holds for a stream of generated data
Generates records lazily and verifies property for each. More memory-efficient for large counts.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/synthra/property_testing.rb', line 86 def verify_property_stream(schema_name, count: 1000, seed: nil, mode: :random, registry: nil) registry ||= Registry.new schema = registry.schema(schema_name) stream = schema.generate_many_stream(count, seed: seed, mode: mode, registry: registry) stream.each_with_index do |record, idx| begin yield(record) rescue RSpec::Expectations::ExpectationNotMetError => e raise RSpec::Expectations::ExpectationNotMetError, "Property failed for record #{idx + 1}/#{count} (seed: #{seed || 'random'}):\n" \ "#{e.}\n" \ "Record: #{record.inspect}" end end end |