structure_compare 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +134 -2
- data/lib/structure_compare/structure_comparison.rb +2 -2
- data/lib/structure_compare/version.rb +1 -1
- data/test/structure_compare_test.rb +3 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8c287f81bf6a357ccd1aba5c8c703696ebaccab
|
4
|
+
data.tar.gz: 1647b3afd3d1e259cb5c019bafdc17a15bd2179c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bb1354657e93c9d83df484233f5660ae50adfe7dacc31fae9b1f944f6961c14c8c2f8f9ae4feb8a789a6c492c577b57de26695fd4227b143e8709faa8d8ee9a
|
7
|
+
data.tar.gz: c198a58a79d70d6521c6b0e93dda95872034ad70a4bee0b3fd2280b3723ef8274444a1d3526e0511489c42155aff39a607d432cd2b995be329b3725fcdcf84b1
|
data/README.md
CHANGED
@@ -1,6 +1,138 @@
|
|
1
1
|
# structure_compare
|
2
|
+
|
2
3
|
Compares the structure of two deep nested Ruby structures
|
3
4
|
|
4
|
-
|
5
|
+
## General
|
6
|
+
|
7
|
+
Use case: you're writing an API response or a JSON export and want to unit test it.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
```
|
12
|
+
gem install structure_compare
|
13
|
+
```
|
14
|
+
|
15
|
+
or add it to your `Gemfile`
|
16
|
+
|
17
|
+
### quick-n-dirty example:
|
18
|
+
```ruby
|
19
|
+
require 'structure_compare'
|
20
|
+
comparison = StructureCompare::StructureComparison.new
|
21
|
+
|
22
|
+
expected = { a: 1, b: 2, c: [1, 2, 3] }
|
23
|
+
actual = { a: 1, b: 2, c: [1, 2, "A"] }
|
24
|
+
|
25
|
+
comparison.structures_are_equal?(expected, actual)
|
26
|
+
puts comparison.error
|
27
|
+
# => root[:c][2] : expected String to be kind of Fixnum
|
28
|
+
```
|
29
|
+
|
30
|
+
### MiniTest
|
31
|
+
```ruby
|
32
|
+
require 'structure_compare'
|
33
|
+
require 'structure_compare/minitest'
|
34
|
+
|
35
|
+
assert_structures_equal({ a: 1, b: 2 }, { a: 1, b: 2 })
|
36
|
+
refute_structures_equal({ a: 1, b: 2 }, { c: 1, d: 2 })
|
37
|
+
```
|
38
|
+
|
39
|
+
### Options
|
40
|
+
|
41
|
+
#### Strict key ordering
|
42
|
+
name: `strict_key_order`
|
43
|
+
default: false
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
expected = { a: 1, b: 2 }
|
47
|
+
actual = { b: 2, a: 1 }
|
48
|
+
|
49
|
+
comparison = StructureCompare::StructureComparison.new(strict_key_order: false)
|
50
|
+
comparison.structures_are_equal?(expected, actual)
|
51
|
+
# => true
|
52
|
+
```
|
53
|
+
|
54
|
+
#### Value checking
|
55
|
+
name: `strict_key_order`
|
56
|
+
default: true
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
expected = { a: 1, b: { c: 1 } }
|
60
|
+
actual = { a: 8, b: { c: 8 } }
|
61
|
+
|
62
|
+
comparison = StructureCompare::StructureComparison.new
|
63
|
+
comparison.structures_are_equal?(expected, actual)
|
64
|
+
# => false
|
65
|
+
|
66
|
+
comparison = StructureCompare::StructureComparison.new(check_values: false)
|
67
|
+
comparison.structures_are_equal?(expected, actual)
|
68
|
+
# => true
|
69
|
+
```
|
70
|
+
|
71
|
+
#### Indifferent Access
|
72
|
+
Hash symbol keys are treated as equal to string keys
|
73
|
+
NOTE: an exception will be raised if there's a key present as symbol _and_ string
|
74
|
+
|
75
|
+
name: `indifferent_access`
|
76
|
+
default: false
|
77
|
+
|
78
|
+
expected = { a: 1 }
|
79
|
+
actual = { "a" => 1 }
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
comparison = StructureCompare::StructureComparison.new
|
83
|
+
comparison.structures_are_equal?(expected, actual)
|
84
|
+
# => false
|
85
|
+
|
86
|
+
comparison = StructureCompare::StructureComparison.new(indifferent_access: true)
|
87
|
+
comparison.structures_are_equal?(expected, actual)
|
88
|
+
# => true
|
89
|
+
|
90
|
+
hash = { a: 1, "a" => 2 }
|
91
|
+
comparison = StructureCompare::StructureComparison.new(indifferent_access: true)
|
92
|
+
comparison.structures_are_equal?(hash, hash)
|
93
|
+
# => StructureCompare::IndifferentAccessError
|
94
|
+
```
|
95
|
+
|
96
|
+
#### Float tolerance
|
97
|
+
|
98
|
+
When dealing with floats, you will want to introduce a tolerance.
|
99
|
+
NOTE: Float::EPSILON is _always_ used for comparing Float type values.
|
100
|
+
NOTE: The `check_values` option must be set.
|
101
|
+
|
102
|
+
name: `float_tolerance_factor`
|
103
|
+
default: 0
|
104
|
+
|
105
|
+
```
|
106
|
+
tolerance = +- (expected * (1.0 + tolerance_factor) + Float::EPSILON)
|
107
|
+
```
|
108
|
+
|
109
|
+
This means a `float_tolerance_factor` setting of 0.01 means that `actual`
|
110
|
+
can be 1% different from `expected` to still be treated equal.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
expected = { a: 10.0 }
|
114
|
+
actual_1 = { a: 10.1 }
|
115
|
+
actual_2 = { a: 10.11 }
|
116
|
+
|
117
|
+
# 1% tolerance factor
|
118
|
+
comparison = StructureCompare::StructureComparison.new(
|
119
|
+
float_tolerance_factor: 0.01, check_values: true
|
120
|
+
)
|
121
|
+
comparison.structures_are_equal?(expected, actual_1)
|
122
|
+
# => true
|
123
|
+
|
124
|
+
comparison.structures_are_equal?(expected, actual_2)
|
125
|
+
# => false
|
126
|
+
```
|
127
|
+
|
128
|
+
## TODOS
|
129
|
+
|
130
|
+
RSpec helpers.
|
131
|
+
|
132
|
+
## Contribution
|
133
|
+
|
134
|
+
Fork me and send me a pull request with working tests.
|
135
|
+
|
136
|
+
## License
|
5
137
|
|
6
|
-
|
138
|
+
MIT License, see `LICENSE` file in the root directory
|
@@ -4,7 +4,7 @@ module StructureCompare
|
|
4
4
|
def initialize(options = {})
|
5
5
|
@options = {
|
6
6
|
strict_key_order: false,
|
7
|
-
check_values:
|
7
|
+
check_values: true,
|
8
8
|
indifferent_access: false,
|
9
9
|
float_tolerance_factor: 0
|
10
10
|
}.merge(options)
|
@@ -118,7 +118,7 @@ module StructureCompare
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def check_values_equal!(expected, actual, failure_message = nil)
|
121
|
-
if expected.is_a?(Float)
|
121
|
+
if expected.is_a?(Float) || actual.is_a?(Float)
|
122
122
|
is_equal = float_equal_with_tolerance_factor?(
|
123
123
|
expected, actual, @options[:float_tolerance_factor]
|
124
124
|
)
|
@@ -34,7 +34,7 @@ class StructureCompareTest < MiniTest::Test
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_leaf_values_are_compared_if_option_set
|
37
|
-
assert_structures_equal({a: 1, b: 2}, {a: 111, b: 222})
|
37
|
+
assert_structures_equal({a: 1, b: 2}, {a: 111, b: 222}, check_values: false)
|
38
38
|
refute_structures_equal({a: 1, b: 2}, {a: 111, b: 222}, check_values: true)
|
39
39
|
|
40
40
|
assert_structures_equal(%w(a b c d), %w(a b c d))
|
@@ -71,7 +71,8 @@ class StructureCompareTest < MiniTest::Test
|
|
71
71
|
structure_a = { x: 1, a: [{ b: [1, "FOO", 1] }] }
|
72
72
|
structure_b = { x: 1, a: [{ b: [1, "BAR", 1] }] }
|
73
73
|
|
74
|
-
assert_structures_equal(structure_a, structure_b)
|
74
|
+
assert_structures_equal(structure_a, structure_b, check_values: false)
|
75
|
+
|
75
76
|
comparison = StructureCompare::StructureComparison.new(check_values: true)
|
76
77
|
comparison.structures_are_equal?(structure_a, structure_b)
|
77
78
|
assert_match "FOO", comparison.error
|