super_diff 0.4.2 → 0.5.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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -8
  3. data/lib/super_diff.rb +20 -11
  4. data/lib/super_diff/active_record.rb +20 -24
  5. data/lib/super_diff/active_record/diff_formatters/active_record_relation.rb +3 -3
  6. data/lib/super_diff/active_record/differs/active_record_relation.rb +3 -5
  7. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_model.rb +32 -22
  8. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_relation.rb +17 -7
  9. data/lib/super_diff/active_record/operation_tree_builders.rb +14 -0
  10. data/lib/super_diff/active_record/{operational_sequencers → operation_tree_builders}/active_record_model.rb +2 -2
  11. data/lib/super_diff/active_record/{operational_sequencers → operation_tree_builders}/active_record_relation.rb +4 -4
  12. data/lib/super_diff/active_record/{operation_sequences.rb → operation_trees.rb} +2 -2
  13. data/lib/super_diff/active_record/{operation_sequences → operation_trees}/active_record_relation.rb +2 -2
  14. data/lib/super_diff/active_support.rb +16 -19
  15. data/lib/super_diff/active_support/diff_formatters/hash_with_indifferent_access.rb +3 -3
  16. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +3 -5
  17. data/lib/super_diff/active_support/object_inspection/inspectors/hash_with_indifferent_access.rb +17 -7
  18. data/lib/super_diff/active_support/operation_tree_builders.rb +10 -0
  19. data/lib/super_diff/active_support/{operational_sequencers → operation_tree_builders}/hash_with_indifferent_access.rb +2 -2
  20. data/lib/super_diff/active_support/{operation_sequences.rb → operation_trees.rb} +2 -2
  21. data/lib/super_diff/active_support/{operation_sequences → operation_trees}/hash_with_indifferent_access.rb +2 -2
  22. data/lib/super_diff/configuration.rb +60 -0
  23. data/lib/super_diff/diff_formatters.rb +3 -3
  24. data/lib/super_diff/diff_formatters/array.rb +3 -3
  25. data/lib/super_diff/diff_formatters/base.rb +3 -2
  26. data/lib/super_diff/diff_formatters/collection.rb +2 -2
  27. data/lib/super_diff/diff_formatters/custom_object.rb +3 -3
  28. data/lib/super_diff/diff_formatters/default_object.rb +6 -8
  29. data/lib/super_diff/diff_formatters/defaults.rb +10 -0
  30. data/lib/super_diff/diff_formatters/hash.rb +3 -3
  31. data/lib/super_diff/diff_formatters/main.rb +41 -0
  32. data/lib/super_diff/diff_formatters/multiline_string.rb +3 -3
  33. data/lib/super_diff/differs.rb +4 -11
  34. data/lib/super_diff/differs/array.rb +2 -11
  35. data/lib/super_diff/differs/base.rb +20 -3
  36. data/lib/super_diff/differs/custom_object.rb +2 -11
  37. data/lib/super_diff/differs/default_object.rb +2 -8
  38. data/lib/super_diff/differs/defaults.rb +12 -0
  39. data/lib/super_diff/differs/hash.rb +2 -11
  40. data/lib/super_diff/differs/main.rb +48 -0
  41. data/lib/super_diff/differs/multiline_string.rb +2 -14
  42. data/lib/super_diff/differs/time_like.rb +15 -0
  43. data/lib/super_diff/equality_matchers.rb +3 -9
  44. data/lib/super_diff/equality_matchers/array.rb +1 -7
  45. data/lib/super_diff/equality_matchers/base.rb +1 -1
  46. data/lib/super_diff/equality_matchers/default.rb +1 -7
  47. data/lib/super_diff/equality_matchers/defaults.rb +12 -0
  48. data/lib/super_diff/equality_matchers/hash.rb +1 -7
  49. data/lib/super_diff/equality_matchers/main.rb +21 -0
  50. data/lib/super_diff/equality_matchers/multiline_string.rb +1 -7
  51. data/lib/super_diff/errors.rb +16 -0
  52. data/lib/super_diff/errors/no_diff_formatter_available_error.rb +21 -0
  53. data/lib/super_diff/errors/no_differ_available_error.rb +24 -0
  54. data/lib/super_diff/errors/no_operational_sequencer_available_error.rb +22 -0
  55. data/lib/super_diff/implementation_checks.rb +19 -0
  56. data/lib/super_diff/object_inspection.rb +1 -10
  57. data/lib/super_diff/object_inspection/inspection_tree.rb +6 -2
  58. data/lib/super_diff/object_inspection/inspectors.rb +5 -1
  59. data/lib/super_diff/object_inspection/inspectors/array.rb +20 -10
  60. data/lib/super_diff/object_inspection/inspectors/base.rb +36 -0
  61. data/lib/super_diff/object_inspection/inspectors/custom_object.rb +24 -14
  62. data/lib/super_diff/object_inspection/inspectors/default_object.rb +44 -30
  63. data/lib/super_diff/object_inspection/inspectors/defaults.rb +15 -0
  64. data/lib/super_diff/object_inspection/inspectors/hash.rb +20 -10
  65. data/lib/super_diff/object_inspection/inspectors/main.rb +35 -0
  66. data/lib/super_diff/object_inspection/inspectors/primitive.rb +20 -5
  67. data/lib/super_diff/object_inspection/inspectors/string.rb +15 -5
  68. data/lib/super_diff/object_inspection/inspectors/time_like.rb +23 -0
  69. data/lib/super_diff/object_inspection/nodes/inspection.rb +9 -2
  70. data/lib/super_diff/operation_tree_builders.rb +18 -0
  71. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/array.rb +38 -59
  72. data/lib/super_diff/operation_tree_builders/base.rb +98 -0
  73. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/custom_object.rb +3 -3
  74. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/default_object.rb +8 -3
  75. data/lib/super_diff/operation_tree_builders/defaults.rb +5 -0
  76. data/lib/super_diff/operation_tree_builders/hash.rb +226 -0
  77. data/lib/super_diff/operation_tree_builders/main.rb +42 -0
  78. data/lib/super_diff/{operational_sequencers → operation_tree_builders}/multiline_string.rb +3 -3
  79. data/lib/super_diff/operation_tree_builders/time_like.rb +34 -0
  80. data/lib/super_diff/operation_trees.rb +13 -0
  81. data/lib/super_diff/{operation_sequences → operation_trees}/array.rb +5 -1
  82. data/lib/super_diff/{operation_sequences → operation_trees}/base.rb +7 -1
  83. data/lib/super_diff/{operation_sequences → operation_trees}/custom_object.rb +5 -1
  84. data/lib/super_diff/{operation_sequences → operation_trees}/default_object.rb +10 -8
  85. data/lib/super_diff/operation_trees/defaults.rb +5 -0
  86. data/lib/super_diff/{operation_sequences → operation_trees}/hash.rb +5 -1
  87. data/lib/super_diff/operation_trees/main.rb +35 -0
  88. data/lib/super_diff/operation_trees/multiline_string.rb +18 -0
  89. data/lib/super_diff/operations/unary_operation.rb +3 -0
  90. data/lib/super_diff/rspec.rb +45 -13
  91. data/lib/super_diff/rspec/augmented_matcher.rb +1 -1
  92. data/lib/super_diff/rspec/differ.rb +2 -17
  93. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +2 -7
  94. data/lib/super_diff/rspec/differs/collection_including.rb +2 -7
  95. data/lib/super_diff/rspec/differs/hash_including.rb +2 -7
  96. data/lib/super_diff/rspec/differs/object_having_attributes.rb +2 -7
  97. data/lib/super_diff/rspec/matcher_text_builders/match.rb +1 -1
  98. data/lib/super_diff/rspec/matcher_text_builders/respond_to.rb +1 -1
  99. data/lib/super_diff/rspec/matcher_text_template.rb +1 -1
  100. data/lib/super_diff/rspec/object_inspection.rb +0 -1
  101. data/lib/super_diff/rspec/object_inspection/inspectors.rb +16 -0
  102. data/lib/super_diff/rspec/object_inspection/inspectors/collection_containing_exactly.rb +17 -8
  103. data/lib/super_diff/rspec/object_inspection/inspectors/collection_including.rb +15 -9
  104. data/lib/super_diff/rspec/object_inspection/inspectors/hash_including.rb +20 -10
  105. data/lib/super_diff/rspec/object_inspection/inspectors/instance_of.rb +23 -0
  106. data/lib/super_diff/rspec/object_inspection/inspectors/kind_of.rb +23 -0
  107. data/lib/super_diff/rspec/object_inspection/inspectors/object_having_attributes.rb +20 -11
  108. data/lib/super_diff/rspec/object_inspection/inspectors/primitive.rb +13 -0
  109. data/lib/super_diff/rspec/object_inspection/inspectors/value_within.rb +29 -0
  110. data/lib/super_diff/rspec/operation_tree_builders.rb +22 -0
  111. data/lib/super_diff/rspec/{operational_sequencers → operation_tree_builders}/collection_containing_exactly.rb +5 -5
  112. data/lib/super_diff/rspec/{operational_sequencers → operation_tree_builders}/collection_including.rb +2 -2
  113. data/lib/super_diff/rspec/{operational_sequencers → operation_tree_builders}/hash_including.rb +3 -11
  114. data/lib/super_diff/rspec/{operational_sequencers → operation_tree_builders}/object_having_attributes.rb +4 -8
  115. data/lib/super_diff/version.rb +1 -1
  116. data/spec/examples.txt +397 -393
  117. data/spec/integration/rspec/have_attributes_matcher_spec.rb +354 -227
  118. data/spec/integration/rspec/include_matcher_spec.rb +2 -2
  119. data/spec/integration/rspec/unhandled_errors_spec.rb +68 -12
  120. data/spec/support/command_runner.rb +3 -0
  121. data/spec/support/integration/helpers.rb +12 -96
  122. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +14 -29
  123. data/spec/support/integration/test_programs/base.rb +120 -0
  124. data/spec/support/integration/test_programs/plain.rb +13 -0
  125. data/spec/support/integration/test_programs/rspec_active_record.rb +17 -0
  126. data/spec/support/integration/test_programs/rspec_rails.rb +17 -0
  127. data/spec/support/models/active_record/person.rb +4 -11
  128. data/spec/support/models/active_record/shipping_address.rb +10 -14
  129. data/spec/support/object_id.rb +6 -5
  130. data/spec/tmp/integration_spec.rb +15 -0
  131. data/spec/unit/{equality_matcher_spec.rb → equality_matchers/main_spec.rb} +157 -1
  132. data/spec/unit/object_inspection_spec.rb +77 -1
  133. data/super_diff.gemspec +0 -1
  134. metadata +72 -64
  135. data/lib/super_diff/active_record/object_inspection/map_extension.rb +0 -18
  136. data/lib/super_diff/active_record/operational_sequencers.rb +0 -14
  137. data/lib/super_diff/active_support/object_inspection/map_extension.rb +0 -15
  138. data/lib/super_diff/active_support/operational_sequencers.rb +0 -10
  139. data/lib/super_diff/diff_formatter.rb +0 -32
  140. data/lib/super_diff/differ.rb +0 -51
  141. data/lib/super_diff/differs/time.rb +0 -24
  142. data/lib/super_diff/equality_matcher.rb +0 -32
  143. data/lib/super_diff/no_differ_available_error.rb +0 -22
  144. data/lib/super_diff/no_operational_sequencer_available_error.rb +0 -20
  145. data/lib/super_diff/object_inspection/inspector.rb +0 -27
  146. data/lib/super_diff/object_inspection/inspectors/time.rb +0 -13
  147. data/lib/super_diff/object_inspection/map.rb +0 -30
  148. data/lib/super_diff/operation_sequences.rb +0 -9
  149. data/lib/super_diff/operational_sequencer.rb +0 -48
  150. data/lib/super_diff/operational_sequencers.rb +0 -17
  151. data/lib/super_diff/operational_sequencers/base.rb +0 -89
  152. data/lib/super_diff/operational_sequencers/hash.rb +0 -85
  153. data/lib/super_diff/operational_sequencers/time_like.rb +0 -30
  154. data/lib/super_diff/rspec/configuration.rb +0 -31
  155. data/lib/super_diff/rspec/object_inspection/map_extension.rb +0 -23
  156. data/lib/super_diff/rspec/operational_sequencers.rb +0 -22
@@ -1,255 +1,369 @@
1
1
  require "spec_helper"
2
2
 
3
3
  RSpec.describe "Integration with RSpec's #have_attributes matcher", type: :integration do
4
- context "when given a small set of attributes" do
5
- context "when all of the names are methods on the actual object" do
6
- it "produces the correct output when used in the positive" do
7
- as_both_colored_and_uncolored do |color_enabled|
8
- snippet = <<~TEST.strip
9
- expected = { name: "b" }
10
- actual = SuperDiff::Test::Person.new(name: "a", age: 9)
11
- expect(actual).to have_attributes(expected)
12
- TEST
13
- program = make_plain_test_program(
14
- snippet,
15
- color_enabled: color_enabled,
16
- )
4
+ context "when the actual value is an object" do
5
+ context "with a small set of attributes" do
6
+ context "when all of the names are methods on the actual object" do
7
+ it "produces the correct output when used in the positive" do
8
+ as_both_colored_and_uncolored do |color_enabled|
9
+ snippet = <<~TEST.strip
10
+ expected = { name: "b" }
11
+ actual = SuperDiff::Test::Person.new(name: "a", age: 9)
12
+ expect(actual).to have_attributes(expected)
13
+ TEST
14
+ program = make_plain_test_program(
15
+ snippet,
16
+ color_enabled: color_enabled,
17
+ )
17
18
 
18
- expected_output = build_expected_output(
19
- color_enabled: color_enabled,
20
- snippet: %|expect(actual).to have_attributes(expected)|,
21
- expectation: proc {
22
- line do
23
- plain "Expected "
24
- beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
25
- plain " to have attributes "
26
- alpha %|(name: "b")|
27
- plain "."
28
- end
29
- },
30
- diff: proc {
31
- plain_line %| #<SuperDiff::Test::Person {|
32
- # alpha_line %|- name: "b",| # FIXME
33
- alpha_line %|- name: "b"|
34
- beta_line %|+ name: "a",|
35
- plain_line %| age: 9|
36
- plain_line %| }>|
37
- },
38
- )
19
+ expected_output = build_expected_output(
20
+ color_enabled: color_enabled,
21
+ snippet: %|expect(actual).to have_attributes(expected)|,
22
+ expectation: proc {
23
+ line do
24
+ plain "Expected "
25
+ beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
26
+ plain " to have attributes "
27
+ alpha %|(name: "b")|
28
+ plain "."
29
+ end
30
+ },
31
+ diff: proc {
32
+ plain_line %| #<SuperDiff::Test::Person {|
33
+ # alpha_line %|- name: "b",| # FIXME
34
+ alpha_line %|- name: "b"|
35
+ beta_line %|+ name: "a",|
36
+ plain_line %| age: 9|
37
+ plain_line %| }>|
38
+ },
39
+ )
39
40
 
40
- expect(program).
41
- to produce_output_when_run(expected_output).
42
- in_color(color_enabled)
41
+ expect(program).
42
+ to produce_output_when_run(expected_output).
43
+ in_color(color_enabled)
44
+ end
43
45
  end
44
- end
45
46
 
46
- it "produces the correct output when used in the negative" do
47
- as_both_colored_and_uncolored do |color_enabled|
48
- snippet = <<~TEST.strip
49
- expected = { name: "a" }
50
- actual = SuperDiff::Test::Person.new(name: "a", age: 9)
51
- expect(actual).not_to have_attributes(expected)
52
- TEST
53
- program = make_plain_test_program(
54
- snippet,
55
- color_enabled: color_enabled,
56
- )
47
+ it "produces the correct output when used in the negative" do
48
+ as_both_colored_and_uncolored do |color_enabled|
49
+ snippet = <<~TEST.strip
50
+ expected = { name: "a" }
51
+ actual = SuperDiff::Test::Person.new(name: "a", age: 9)
52
+ expect(actual).not_to have_attributes(expected)
53
+ TEST
54
+ program = make_plain_test_program(
55
+ snippet,
56
+ color_enabled: color_enabled,
57
+ )
57
58
 
58
- expected_output = build_expected_output(
59
- color_enabled: color_enabled,
60
- snippet: %|expect(actual).not_to have_attributes(expected)|,
61
- expectation: proc {
62
- line do
63
- plain "Expected "
64
- beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
65
- plain " not to have attributes "
66
- alpha %|(name: "a")|
67
- plain "."
68
- end
69
- },
70
- )
59
+ expected_output = build_expected_output(
60
+ color_enabled: color_enabled,
61
+ snippet: %|expect(actual).not_to have_attributes(expected)|,
62
+ expectation: proc {
63
+ line do
64
+ plain "Expected "
65
+ beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
66
+ plain " not to have attributes "
67
+ alpha %|(name: "a")|
68
+ plain "."
69
+ end
70
+ },
71
+ )
71
72
 
72
- expect(program).
73
- to produce_output_when_run(expected_output).
74
- in_color(color_enabled)
73
+ expect(program).
74
+ to produce_output_when_run(expected_output).
75
+ in_color(color_enabled)
76
+ end
75
77
  end
76
78
  end
77
- end
78
79
 
79
- context "when some of the names are not methods on the actual object" do
80
- it "produces the correct output" do
81
- as_both_colored_and_uncolored do |color_enabled|
82
- snippet = <<~TEST.strip
83
- expected = { name: "b", foo: "bar" }
84
- actual = SuperDiff::Test::Person.new(name: "a", age: 9)
85
- expect(actual).to have_attributes(expected)
86
- TEST
87
- program = make_plain_test_program(
88
- snippet,
89
- color_enabled: color_enabled,
90
- )
80
+ context "when some of the names are not methods on the actual object" do
81
+ it "produces the correct output" do
82
+ as_both_colored_and_uncolored do |color_enabled|
83
+ snippet = <<~TEST.strip
84
+ expected = { name: "b", foo: "bar" }
85
+ actual = SuperDiff::Test::Person.new(name: "a", age: 9)
86
+ expect(actual).to have_attributes(expected)
87
+ TEST
88
+ program = make_plain_test_program(
89
+ snippet,
90
+ color_enabled: color_enabled,
91
+ )
91
92
 
92
- expected_output = build_expected_output(
93
- color_enabled: color_enabled,
94
- snippet: %|expect(actual).to have_attributes(expected)|,
95
- expectation: proc {
96
- line do
97
- plain "Expected "
98
- beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
99
- plain " to respond to "
100
- alpha %|:foo|
101
- plain " with "
102
- alpha %|0|
103
- plain " arguments."
104
- end
105
- },
106
- diff: proc {
107
- plain_line %| #<SuperDiff::Test::Person {|
108
- plain_line %| name: "a",|
109
- # plain_line %| age: 9,| # FIXME
110
- plain_line %| age: 9|
111
- # alpha_line %|- foo: "bar",| # FIXME
112
- alpha_line %|- foo: "bar"|
113
- plain_line %| }>|
114
- },
115
- )
93
+ expected_output = build_expected_output(
94
+ color_enabled: color_enabled,
95
+ snippet: %|expect(actual).to have_attributes(expected)|,
96
+ expectation: proc {
97
+ line do
98
+ plain "Expected "
99
+ beta %|#<SuperDiff::Test::Person name: "a", age: 9>|
100
+ plain " to respond to "
101
+ alpha %|:foo|
102
+ plain " with "
103
+ alpha %|0|
104
+ plain " arguments."
105
+ end
106
+ },
107
+ diff: proc {
108
+ plain_line %| #<SuperDiff::Test::Person {|
109
+ plain_line %| name: "a",|
110
+ # plain_line %| age: 9,| # FIXME
111
+ plain_line %| age: 9|
112
+ # alpha_line %|- foo: "bar",| # FIXME
113
+ alpha_line %|- foo: "bar"|
114
+ plain_line %| }>|
115
+ },
116
+ )
116
117
 
117
- expect(program).
118
- to produce_output_when_run(expected_output).
119
- in_color(color_enabled)
118
+ expect(program).
119
+ to produce_output_when_run(expected_output).
120
+ in_color(color_enabled)
121
+ end
120
122
  end
121
123
  end
122
124
  end
123
- end
124
125
 
125
- context "when given a large set of attributes" do
126
- context "when all of the names are methods on the actual object" do
127
- it "produces the correct output when used in the positive" do
128
- as_both_colored_and_uncolored do |color_enabled|
129
- snippet = <<~TEST.strip
130
- expected = {
131
- line_1: "123 Main St.",
132
- city: "Oakland",
133
- state: "CA",
134
- zip: "91234"
135
- }
136
- actual = SuperDiff::Test::ShippingAddress.new(
137
- line_1: "456 Ponderosa Ct.",
138
- line_2: nil,
139
- city: "Hill Valley",
140
- state: "CA",
141
- zip: "90382"
126
+ context "with a large set of attributes" do
127
+ context "when all of the names are methods on the actual object" do
128
+ it "produces the correct output when used in the positive" do
129
+ as_both_colored_and_uncolored do |color_enabled|
130
+ snippet = <<~TEST.strip
131
+ expected = {
132
+ line_1: "123 Main St.",
133
+ city: "Oakland",
134
+ state: "CA",
135
+ zip: "91234"
136
+ }
137
+ actual = SuperDiff::Test::ShippingAddress.new(
138
+ line_1: "456 Ponderosa Ct.",
139
+ line_2: nil,
140
+ city: "Hill Valley",
141
+ state: "CA",
142
+ zip: "90382"
143
+ )
144
+ expect(actual).to have_attributes(expected)
145
+ TEST
146
+ program = make_plain_test_program(
147
+ snippet,
148
+ color_enabled: color_enabled,
142
149
  )
143
- expect(actual).to have_attributes(expected)
144
- TEST
145
- program = make_plain_test_program(
146
- snippet,
147
- color_enabled: color_enabled,
148
- )
149
150
 
150
- expected_output = build_expected_output(
151
- color_enabled: color_enabled,
152
- snippet: %|expect(actual).to have_attributes(expected)|,
153
- expectation: proc {
154
- line do
155
- plain " Expected "
156
- beta %|#<SuperDiff::Test::ShippingAddress line_1: "456 Ponderosa Ct.", line_2: nil, city: "Hill Valley", state: "CA", zip: "90382">|
157
- end
151
+ expected_output = build_expected_output(
152
+ color_enabled: color_enabled,
153
+ snippet: %|expect(actual).to have_attributes(expected)|,
154
+ expectation: proc {
155
+ line do
156
+ plain " Expected "
157
+ beta %|#<SuperDiff::Test::ShippingAddress line_1: "456 Ponderosa Ct.", line_2: nil, city: "Hill Valley", state: "CA", zip: "90382">|
158
+ end
158
159
 
159
- line do
160
- plain "to have attributes "
161
- alpha %|(line_1: "123 Main St.", city: "Oakland", state: "CA", zip: "91234")|
162
- end
163
- },
164
- diff: proc {
165
- plain_line %| #<SuperDiff::Test::ShippingAddress {|
166
- alpha_line %|- line_1: "123 Main St.",|
167
- beta_line %|+ line_1: "456 Ponderosa Ct.",|
168
- plain_line %| line_2: nil,|
169
- alpha_line %|- city: "Oakland",|
170
- beta_line %|+ city: "Hill Valley",|
171
- plain_line %| state: "CA",|
172
- # alpha_line %|- zip: "91234",| # FIXME
173
- alpha_line %|- zip: "91234"|
174
- beta_line %|+ zip: "90382"|
175
- plain_line %| }>|
176
- },
177
- )
160
+ line do
161
+ plain "to have attributes "
162
+ alpha %|(line_1: "123 Main St.", city: "Oakland", state: "CA", zip: "91234")|
163
+ end
164
+ },
165
+ diff: proc {
166
+ plain_line %| #<SuperDiff::Test::ShippingAddress {|
167
+ alpha_line %|- line_1: "123 Main St.",|
168
+ beta_line %|+ line_1: "456 Ponderosa Ct.",|
169
+ plain_line %| line_2: nil,|
170
+ alpha_line %|- city: "Oakland",|
171
+ beta_line %|+ city: "Hill Valley",|
172
+ plain_line %| state: "CA",|
173
+ # alpha_line %|- zip: "91234",| # FIXME
174
+ alpha_line %|- zip: "91234"|
175
+ beta_line %|+ zip: "90382"|
176
+ plain_line %| }>|
177
+ },
178
+ )
178
179
 
179
- expect(program).
180
- to produce_output_when_run(expected_output).
181
- in_color(color_enabled)
180
+ expect(program).
181
+ to produce_output_when_run(expected_output).
182
+ in_color(color_enabled)
183
+ end
184
+ end
185
+
186
+ it "produces the correct output when used in the negative" do
187
+ as_both_colored_and_uncolored do |color_enabled|
188
+ snippet = <<~TEST.strip
189
+ expected = {
190
+ line_1: "123 Main St.",
191
+ city: "Oakland",
192
+ state: "CA",
193
+ zip: "91234"
194
+ }
195
+ actual = SuperDiff::Test::ShippingAddress.new(
196
+ line_1: "123 Main St.",
197
+ line_2: nil,
198
+ city: "Oakland",
199
+ state: "CA",
200
+ zip: "91234"
201
+ )
202
+ expect(actual).not_to have_attributes(expected)
203
+ TEST
204
+ program = make_plain_test_program(
205
+ snippet,
206
+ color_enabled: color_enabled,
207
+ )
208
+
209
+ expected_output = build_expected_output(
210
+ color_enabled: color_enabled,
211
+ snippet: %|expect(actual).not_to have_attributes(expected)|,
212
+ newline_before_expectation: true,
213
+ expectation: proc {
214
+ line do
215
+ plain " Expected "
216
+ beta %|#<SuperDiff::Test::ShippingAddress line_1: "123 Main St.", line_2: nil, city: "Oakland", state: "CA", zip: "91234">|
217
+ end
218
+
219
+ line do
220
+ plain "not to have attributes "
221
+ alpha %|(line_1: "123 Main St.", city: "Oakland", state: "CA", zip: "91234")|
222
+ end
223
+ },
224
+ )
225
+
226
+ expect(program).
227
+ to produce_output_when_run(expected_output).
228
+ in_color(color_enabled)
229
+ end
182
230
  end
183
231
  end
184
232
 
185
- it "produces the correct output when used in the negative" do
186
- as_both_colored_and_uncolored do |color_enabled|
187
- snippet = <<~TEST.strip
188
- expected = {
189
- line_1: "123 Main St.",
190
- city: "Oakland",
191
- state: "CA",
192
- zip: "91234"
193
- }
194
- actual = SuperDiff::Test::ShippingAddress.new(
195
- line_1: "123 Main St.",
196
- line_2: nil,
197
- city: "Oakland",
198
- state: "CA",
199
- zip: "91234"
233
+ context "when some of the names are not methods on the actual object" do
234
+ it "produces the correct output" do
235
+ as_both_colored_and_uncolored do |color_enabled|
236
+ snippet = <<~TEST.strip
237
+ expected = {
238
+ line_1: "123 Main St.",
239
+ city: "Oakland",
240
+ state: "CA",
241
+ zip: "91234",
242
+ foo: "bar",
243
+ baz: "qux"
244
+ }
245
+ actual = SuperDiff::Test::ShippingAddress.new(
246
+ line_1: "456 Ponderosa Ct.",
247
+ line_2: nil,
248
+ city: "Hill Valley",
249
+ state: "CA",
250
+ zip: "90382"
251
+ )
252
+ expect(actual).to have_attributes(expected)
253
+ TEST
254
+ program = make_plain_test_program(
255
+ snippet,
256
+ color_enabled: color_enabled,
200
257
  )
201
- expect(actual).not_to have_attributes(expected)
202
- TEST
203
- program = make_plain_test_program(
204
- snippet,
205
- color_enabled: color_enabled,
206
- )
207
258
 
208
- expected_output = build_expected_output(
209
- color_enabled: color_enabled,
210
- snippet: %|expect(actual).not_to have_attributes(expected)|,
211
- newline_before_expectation: true,
212
- expectation: proc {
213
- line do
214
- plain " Expected "
215
- beta %|#<SuperDiff::Test::ShippingAddress line_1: "123 Main St.", line_2: nil, city: "Oakland", state: "CA", zip: "91234">|
216
- end
259
+ expected_output = build_expected_output(
260
+ color_enabled: color_enabled,
261
+ snippet: %|expect(actual).to have_attributes(expected)|,
262
+ expectation: proc {
263
+ line do
264
+ plain " Expected "
265
+ beta %|#<SuperDiff::Test::ShippingAddress line_1: "456 Ponderosa Ct.", line_2: nil, city: "Hill Valley", state: "CA", zip: "90382">|
266
+ end
217
267
 
218
- line do
219
- plain "not to have attributes "
220
- alpha %|(line_1: "123 Main St.", city: "Oakland", state: "CA", zip: "91234")|
221
- end
222
- },
223
- )
268
+ line do
269
+ plain "to respond to "
270
+ alpha %|:foo|
271
+ plain " and "
272
+ alpha %|:baz|
273
+ plain " with "
274
+ alpha %|0|
275
+ plain " arguments"
276
+ end
277
+ },
278
+ diff: proc {
279
+ plain_line %| #<SuperDiff::Test::ShippingAddress {|
280
+ plain_line %| line_1: "456 Ponderosa Ct.",|
281
+ plain_line %| line_2: nil,|
282
+ plain_line %| city: "Hill Valley",|
283
+ plain_line %| state: "CA",|
284
+ # plain_line %| zip: "90382",| # FIXME
285
+ plain_line %| zip: "90382"|
286
+ # alpha_line %|- foo: "bar",| # FIXME
287
+ alpha_line %|- foo: "bar"|
288
+ alpha_line %|- baz: "qux"|
289
+ plain_line %| }>|
290
+ },
291
+ )
224
292
 
225
- expect(program).
226
- to produce_output_when_run(expected_output).
227
- in_color(color_enabled)
293
+ expect(program).
294
+ to produce_output_when_run(expected_output).
295
+ in_color(color_enabled)
296
+ end
228
297
  end
229
298
  end
230
299
  end
300
+ end
301
+
302
+ context "when the actual value is actually a hash instead of an object" do
303
+ it "displays the diff as if we were comparing hashes" do
304
+ as_both_colored_and_uncolored do |color_enabled|
305
+ snippet = <<~TEST.strip
306
+ expected = { name: "Elliot", age: 32 }
307
+ actual = {}
308
+ expect(actual).to have_attributes(expected)
309
+ TEST
310
+
311
+ program = make_plain_test_program(snippet, color_enabled: color_enabled)
231
312
 
232
- context "when some of the names are not methods on the actual object" do
233
- it "produces the correct output" do
313
+ expected_output = build_expected_output(
314
+ color_enabled: color_enabled,
315
+ snippet: %|expect(actual).to have_attributes(expected)|,
316
+ expectation: proc {
317
+ line do
318
+ plain "Expected "
319
+ beta %|{}|
320
+ plain " to respond to "
321
+ alpha %|:name|
322
+ plain " and "
323
+ alpha %|:age|
324
+ plain " with "
325
+ alpha %|0|
326
+ plain " arguments."
327
+ end
328
+ },
329
+ diff: proc {
330
+ plain_line %| {|
331
+ alpha_line %|- name: "Elliot",|
332
+ alpha_line %|- age: 32|
333
+ plain_line %| }|
334
+ },
335
+ )
336
+
337
+ expect(program).
338
+ to produce_output_when_run(expected_output).
339
+ in_color(color_enabled)
340
+ end
341
+ end
342
+
343
+ # TODO: Add as many fuzzy matchers as we can here
344
+ context "that contains fuzzy matcher objects instead of an object" do
345
+ it "displays the hash correctly" do
234
346
  as_both_colored_and_uncolored do |color_enabled|
235
347
  snippet = <<~TEST.strip
236
348
  expected = {
237
- line_1: "123 Main St.",
238
- city: "Oakland",
239
- state: "CA",
240
- zip: "91234",
241
- foo: "bar",
242
- baz: "qux"
349
+ name: "Elliot",
350
+ shipping_address: an_object_having_attributes(
351
+ line_1: a_kind_of(String),
352
+ line_2: nil,
353
+ city: an_instance_of(String),
354
+ state: "CA",
355
+ zip: "91234"
356
+ ),
357
+ order_ids: a_collection_including(1, 2),
358
+ data: a_hash_including(active: true),
359
+ created_at: a_value_within(1).of(Time.utc(2020, 4, 9))
243
360
  }
244
- actual = SuperDiff::Test::ShippingAddress.new(
245
- line_1: "456 Ponderosa Ct.",
246
- line_2: nil,
247
- city: "Hill Valley",
248
- state: "CA",
249
- zip: "90382"
250
- )
361
+
362
+ actual = {}
363
+
251
364
  expect(actual).to have_attributes(expected)
252
365
  TEST
366
+
253
367
  program = make_plain_test_program(
254
368
  snippet,
255
369
  color_enabled: color_enabled,
@@ -261,31 +375,44 @@ RSpec.describe "Integration with RSpec's #have_attributes matcher", type: :integ
261
375
  expectation: proc {
262
376
  line do
263
377
  plain " Expected "
264
- beta %|#<SuperDiff::Test::ShippingAddress line_1: "456 Ponderosa Ct.", line_2: nil, city: "Hill Valley", state: "CA", zip: "90382">|
378
+ beta %|{}|
265
379
  end
266
380
 
267
381
  line do
268
382
  plain "to respond to "
269
- alpha %|:foo|
383
+ alpha %|:name|
384
+ plain ", "
385
+ alpha %|:shipping_address|
386
+ plain ", "
387
+ alpha %|:order_ids|
388
+ plain ", "
389
+ alpha %|:data|
270
390
  plain " and "
271
- alpha %|:baz|
391
+ alpha %|:created_at|
272
392
  plain " with "
273
393
  alpha %|0|
274
394
  plain " arguments"
275
395
  end
276
396
  },
277
397
  diff: proc {
278
- plain_line %| #<SuperDiff::Test::ShippingAddress {|
279
- plain_line %| line_1: "456 Ponderosa Ct.",|
280
- plain_line %| line_2: nil,|
281
- plain_line %| city: "Hill Valley",|
282
- plain_line %| state: "CA",|
283
- # plain_line %| zip: "90382",| # FIXME
284
- plain_line %| zip: "90382"|
285
- # alpha_line %|- foo: "bar",| # FIXME
286
- alpha_line %|- foo: "bar"|
287
- alpha_line %|- baz: "qux"|
288
- plain_line %| }>|
398
+ plain_line %| {|
399
+ alpha_line %|- name: "Elliot",|
400
+ alpha_line %|- shipping_address: #<an object having attributes (|
401
+ alpha_line %|- line_1: #<a kind of String>,|
402
+ alpha_line %|- line_2: nil,|
403
+ alpha_line %|- city: #<an instance of String>,|
404
+ alpha_line %|- state: "CA",|
405
+ alpha_line %|- zip: "91234"|
406
+ alpha_line %|- )>,|
407
+ alpha_line %|- order_ids: #<a collection including (|
408
+ alpha_line %|- 1,|
409
+ alpha_line %|- 2|
410
+ alpha_line %|- )>,|
411
+ alpha_line %|- data: #<a hash including (|
412
+ alpha_line %|- active: true|
413
+ alpha_line %|- )>,|
414
+ alpha_line %|- created_at: #<a value within 1 of 2020-04-09 00:00:00.000 UTC +00:00 (Time)>|
415
+ plain_line %| }|
289
416
  },
290
417
  )
291
418