Class: Kumi::Dev::Golden::ValueNormalizer
- Inherits:
-
Object
- Object
- Kumi::Dev::Golden::ValueNormalizer
- Defined in:
- lib/kumi/dev/golden/value_normalizer.rb
Overview
Normalizes values for test comparisons, handling decimal precision
Class Method Summary collapse
- .compare_values(actual, expected, language:) ⇒ Object
- .decimal_string?(str) ⇒ Boolean
- .normalize(value, language: :ruby) ⇒ Object
- .values_equal?(actual, expected, language: :ruby) ⇒ Boolean
Class Method Details
.compare_values(actual, expected, language:) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/kumi/dev/golden/value_normalizer.rb', line 40 def self.compare_values(actual, expected, language:) # Handle decimal comparisons with tolerance for floating-point errors case [actual, expected] in [Array, Array] actual.length == expected.length && actual.zip(expected).all? { |a, e| compare_values(a, e, language: language) } in [Hash, Hash] actual.keys == expected.keys && actual.all? { |k, v| compare_values(v, expected[k], language: language) } in [BigDecimal, BigDecimal] actual == expected in [BigDecimal, (Integer | Float)] BigDecimal(actual.to_s) == BigDecimal(expected.to_s) in [(Integer | Float), BigDecimal] BigDecimal(actual.to_s) == BigDecimal(expected.to_s) in [(Integer | Float), String] | [String, (Integer | Float)] # Compare number with decimal string (e.g., JavaScript number vs expected string) actual_bd = BigDecimal(actual.to_s) expected_bd = BigDecimal(expected.to_s) # Allow small floating-point differences (within 1e-10) (actual_bd - expected_bd).abs < BigDecimal("1e-10") in [String, String] # Both strings - try to parse as decimals and compare begin actual_bd = BigDecimal(actual) expected_bd = BigDecimal(expected) (actual_bd - expected_bd).abs < BigDecimal("1e-10") rescue ArgumentError # If not valid decimals, compare as strings actual == expected end else actual == expected end end |
.decimal_string?(str) ⇒ Boolean
35 36 37 38 |
# File 'lib/kumi/dev/golden/value_normalizer.rb', line 35 def self.decimal_string?(str) # Match decimal number strings like "10.50", "123", "-45.67" str.match?(/\A-?\d+(\.\d+)?\z/) end |
.normalize(value, language: :ruby) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/kumi/dev/golden/value_normalizer.rb', line 10 def self.normalize(value, language: :ruby) case value when Hash value.transform_values { |v| normalize(v, language: language) } when Array value.map { |v| normalize(v, language: language) } when String # Try to parse as decimal if it looks like one if decimal_string?(value) language == :ruby ? BigDecimal(value) : value else value end else value end end |
.values_equal?(actual, expected, language: :ruby) ⇒ Boolean
28 29 30 31 32 33 |
# File 'lib/kumi/dev/golden/value_normalizer.rb', line 28 def self.values_equal?(actual, expected, language: :ruby) norm_actual = normalize(actual, language: language) norm_expected = normalize(expected, language: language) compare_values(norm_actual, norm_expected, language: language) end |