super_diff 0.1.0 → 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.
Files changed (206) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +117 -89
  3. data/lib/super_diff.rb +33 -47
  4. data/lib/super_diff/active_record.rb +41 -0
  5. data/lib/super_diff/active_record/diff_formatters.rb +10 -0
  6. data/lib/super_diff/active_record/diff_formatters/active_record_relation.rb +23 -0
  7. data/lib/super_diff/active_record/differs.rb +10 -0
  8. data/lib/super_diff/active_record/differs/active_record_relation.rb +30 -0
  9. data/lib/super_diff/active_record/object_inspection.rb +14 -0
  10. data/lib/super_diff/active_record/object_inspection/inspectors.rb +16 -0
  11. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_model.rb +38 -0
  12. data/lib/super_diff/active_record/object_inspection/inspectors/active_record_relation.rb +18 -0
  13. data/lib/super_diff/active_record/object_inspection/map_extension.rb +18 -0
  14. data/lib/super_diff/active_record/operation_sequences.rb +10 -0
  15. data/lib/super_diff/active_record/operation_sequences/active_record_relation.rb +16 -0
  16. data/lib/super_diff/active_record/operational_sequencers.rb +14 -0
  17. data/lib/super_diff/active_record/operational_sequencers/active_record_model.rb +19 -0
  18. data/lib/super_diff/active_record/operational_sequencers/active_record_relation.rb +24 -0
  19. data/lib/super_diff/active_support.rb +33 -0
  20. data/lib/super_diff/active_support/diff_formatters.rb +10 -0
  21. data/lib/super_diff/active_support/diff_formatters/hash_with_indifferent_access.rb +36 -0
  22. data/lib/super_diff/active_support/differs.rb +10 -0
  23. data/lib/super_diff/active_support/differs/hash_with_indifferent_access.rb +36 -0
  24. data/lib/super_diff/active_support/object_inspection.rb +14 -0
  25. data/lib/super_diff/active_support/object_inspection/inspectors.rb +12 -0
  26. data/lib/super_diff/active_support/object_inspection/inspectors/hash_with_indifferent_access.rb +18 -0
  27. data/lib/super_diff/active_support/object_inspection/map_extension.rb +15 -0
  28. data/lib/super_diff/active_support/operation_sequences.rb +10 -0
  29. data/lib/super_diff/active_support/operation_sequences/hash_with_indifferent_access.rb +16 -0
  30. data/lib/super_diff/active_support/operational_sequencers.rb +10 -0
  31. data/lib/super_diff/active_support/operational_sequencers/hash_with_indifferent_access.rb +21 -0
  32. data/lib/super_diff/colorized_document_extensions.rb +17 -0
  33. data/lib/super_diff/csi.rb +45 -15
  34. data/lib/super_diff/csi/bold_sequence.rb +9 -0
  35. data/lib/super_diff/csi/color.rb +62 -0
  36. data/lib/super_diff/csi/color_sequence_block.rb +28 -0
  37. data/lib/super_diff/csi/colorized_document.rb +72 -0
  38. data/lib/super_diff/csi/document.rb +183 -0
  39. data/lib/super_diff/csi/eight_bit_color.rb +72 -26
  40. data/lib/super_diff/csi/four_bit_color.rb +63 -29
  41. data/lib/super_diff/csi/twenty_four_bit_color.rb +79 -18
  42. data/lib/super_diff/csi/uncolorized_document.rb +29 -0
  43. data/lib/super_diff/diff_formatter.rb +10 -15
  44. data/lib/super_diff/diff_formatters.rb +10 -1
  45. data/lib/super_diff/diff_formatters/base.rb +12 -17
  46. data/lib/super_diff/diff_formatters/collection.rb +81 -50
  47. data/lib/super_diff/diff_formatters/{object.rb → custom_object.rb} +12 -9
  48. data/lib/super_diff/diff_formatters/default_object.rb +48 -0
  49. data/lib/super_diff/diff_formatters/multiline_string.rb +31 -0
  50. data/lib/super_diff/differ.rb +35 -32
  51. data/lib/super_diff/differs.rb +16 -1
  52. data/lib/super_diff/differs/array.rb +2 -2
  53. data/lib/super_diff/differs/base.rb +11 -21
  54. data/lib/super_diff/differs/custom_object.rb +26 -0
  55. data/lib/super_diff/differs/default_object.rb +25 -0
  56. data/lib/super_diff/differs/empty.rb +1 -1
  57. data/lib/super_diff/differs/hash.rb +2 -2
  58. data/lib/super_diff/differs/{multi_line_string.rb → multiline_string.rb} +6 -5
  59. data/lib/super_diff/equality_matcher.rb +9 -22
  60. data/lib/super_diff/equality_matchers.rb +19 -1
  61. data/lib/super_diff/equality_matchers/array.rb +6 -4
  62. data/lib/super_diff/equality_matchers/base.rb +8 -16
  63. data/lib/super_diff/equality_matchers/default.rb +60 -0
  64. data/lib/super_diff/equality_matchers/hash.rb +6 -4
  65. data/lib/super_diff/equality_matchers/{multi_line_string.rb → multiline_string.rb} +9 -6
  66. data/lib/super_diff/equality_matchers/primitive.rb +34 -0
  67. data/lib/super_diff/equality_matchers/{single_line_string.rb → singleline_string.rb} +7 -5
  68. data/lib/super_diff/helpers.rb +17 -81
  69. data/lib/super_diff/no_differ_available_error.rb +22 -0
  70. data/lib/super_diff/{errors.rb → no_operational_sequencer_available_error.rb} +0 -0
  71. data/lib/super_diff/object_inspection.rb +24 -0
  72. data/lib/super_diff/object_inspection/inspection_tree.rb +144 -0
  73. data/lib/super_diff/object_inspection/inspector.rb +27 -0
  74. data/lib/super_diff/object_inspection/inspectors.rb +18 -0
  75. data/lib/super_diff/object_inspection/inspectors/array.rb +22 -0
  76. data/lib/super_diff/object_inspection/inspectors/custom_object.rb +27 -0
  77. data/lib/super_diff/object_inspection/inspectors/default_object.rb +47 -0
  78. data/lib/super_diff/object_inspection/inspectors/hash.rb +22 -0
  79. data/lib/super_diff/object_inspection/inspectors/primitive.rb +13 -0
  80. data/lib/super_diff/object_inspection/inspectors/string.rb +13 -0
  81. data/lib/super_diff/object_inspection/map.rb +28 -0
  82. data/lib/super_diff/object_inspection/nodes.rb +49 -0
  83. data/lib/super_diff/object_inspection/nodes/base.rb +86 -0
  84. data/lib/super_diff/object_inspection/nodes/break.rb +15 -0
  85. data/lib/super_diff/object_inspection/nodes/inspection.rb +15 -0
  86. data/lib/super_diff/object_inspection/nodes/nesting.rb +16 -0
  87. data/lib/super_diff/object_inspection/nodes/text.rb +15 -0
  88. data/lib/super_diff/object_inspection/nodes/when_empty.rb +30 -0
  89. data/lib/super_diff/object_inspection/nodes/when_multiline.rb +22 -0
  90. data/lib/super_diff/object_inspection/nodes/when_non_empty.rb +30 -0
  91. data/lib/super_diff/object_inspection/nodes/when_singleline.rb +24 -0
  92. data/lib/super_diff/operation_sequences.rb +9 -0
  93. data/lib/super_diff/operation_sequences/base.rb +1 -1
  94. data/lib/super_diff/operation_sequences/{object.rb → custom_object.rb} +4 -3
  95. data/lib/super_diff/operation_sequences/default_object.rb +25 -0
  96. data/lib/super_diff/operational_sequencer.rb +23 -18
  97. data/lib/super_diff/operational_sequencers.rb +12 -1
  98. data/lib/super_diff/operational_sequencers/array.rb +65 -62
  99. data/lib/super_diff/operational_sequencers/base.rb +18 -26
  100. data/lib/super_diff/operational_sequencers/custom_object.rb +35 -0
  101. data/lib/super_diff/operational_sequencers/{object.rb → default_object.rb} +21 -11
  102. data/lib/super_diff/operational_sequencers/hash.rb +8 -5
  103. data/lib/super_diff/operational_sequencers/{multi_line_string.rb → multiline_string.rb} +11 -6
  104. data/lib/super_diff/operations.rb +6 -0
  105. data/lib/super_diff/operations/binary_operation.rb +14 -34
  106. data/lib/super_diff/operations/unary_operation.rb +11 -2
  107. data/lib/super_diff/rails.rb +1 -0
  108. data/lib/super_diff/recursion_guard.rb +47 -0
  109. data/lib/super_diff/rspec-rails.rb +2 -0
  110. data/lib/super_diff/rspec.rb +52 -8
  111. data/lib/super_diff/rspec/augmented_matcher.rb +98 -0
  112. data/lib/super_diff/rspec/configuration.rb +31 -0
  113. data/lib/super_diff/rspec/differ.rb +60 -16
  114. data/lib/super_diff/rspec/differs.rb +13 -0
  115. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +23 -0
  116. data/lib/super_diff/rspec/differs/partial_array.rb +22 -0
  117. data/lib/super_diff/rspec/differs/partial_hash.rb +22 -0
  118. data/lib/super_diff/rspec/differs/partial_object.rb +22 -0
  119. data/lib/super_diff/rspec/matcher_text_builders.rb +24 -0
  120. data/lib/super_diff/rspec/matcher_text_builders/base.rb +155 -0
  121. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +78 -0
  122. data/lib/super_diff/rspec/matcher_text_builders/contain_exactly.rb +14 -0
  123. data/lib/super_diff/rspec/matcher_text_builders/match.rb +23 -0
  124. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +13 -0
  125. data/lib/super_diff/rspec/matcher_text_builders/respond_to.rb +99 -0
  126. data/lib/super_diff/rspec/matcher_text_template.rb +240 -0
  127. data/lib/super_diff/rspec/monkey_patches.rb +601 -98
  128. data/lib/super_diff/rspec/object_inspection.rb +8 -0
  129. data/lib/super_diff/rspec/object_inspection/inspectors.rb +24 -0
  130. data/lib/super_diff/rspec/object_inspection/inspectors/collection_containing_exactly.rb +19 -0
  131. data/lib/super_diff/rspec/object_inspection/inspectors/partial_array.rb +22 -0
  132. data/lib/super_diff/rspec/object_inspection/inspectors/partial_hash.rb +21 -0
  133. data/lib/super_diff/rspec/object_inspection/inspectors/partial_object.rb +21 -0
  134. data/lib/super_diff/rspec/object_inspection/map_extension.rb +23 -0
  135. data/lib/super_diff/rspec/operational_sequencers.rb +22 -0
  136. data/lib/super_diff/rspec/operational_sequencers/collection_containing_exactly.rb +97 -0
  137. data/lib/super_diff/rspec/operational_sequencers/partial_array.rb +23 -0
  138. data/lib/super_diff/rspec/operational_sequencers/partial_hash.rb +32 -0
  139. data/lib/super_diff/rspec/operational_sequencers/partial_object.rb +64 -0
  140. data/lib/super_diff/version.rb +1 -1
  141. data/spec/examples.txt +328 -46
  142. data/spec/integration/rails/active_record_spec.rb +19 -0
  143. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +19 -0
  144. data/spec/integration/rspec/be_falsey_matcher_spec.rb +53 -0
  145. data/spec/integration/rspec/be_matcher_spec.rb +565 -0
  146. data/spec/integration/rspec/be_nil_matcher_spec.rb +53 -0
  147. data/spec/integration/rspec/be_predicate_matcher_spec.rb +546 -0
  148. data/spec/integration/rspec/be_truthy_matcher_spec.rb +57 -0
  149. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +368 -0
  150. data/spec/integration/rspec/eq_matcher_spec.rb +874 -0
  151. data/spec/integration/rspec/have_attributes_matcher_spec.rb +299 -0
  152. data/spec/integration/rspec/include_matcher_spec.rb +350 -0
  153. data/spec/integration/rspec/match_matcher_spec.rb +1258 -0
  154. data/spec/integration/rspec/raise_error_matcher_spec.rb +350 -0
  155. data/spec/integration/rspec/respond_to_matcher_spec.rb +994 -0
  156. data/spec/integration/rspec/unhandled_errors_spec.rb +94 -0
  157. data/spec/spec_helper.rb +19 -4
  158. data/spec/support/colorizer.rb +9 -0
  159. data/spec/support/command_runner.rb +4 -0
  160. data/spec/support/integration/helpers.rb +179 -0
  161. data/spec/support/integration/matchers/produce_output_when_run_matcher.rb +79 -41
  162. data/spec/support/models/a.rb +11 -0
  163. data/spec/support/models/active_record/person.rb +26 -0
  164. data/spec/support/models/active_record/shipping_address.rb +29 -0
  165. data/spec/support/models/customer.rb +24 -0
  166. data/spec/support/models/empty_class.rb +6 -0
  167. data/spec/support/models/item.rb +10 -0
  168. data/spec/support/models/order.rb +9 -0
  169. data/spec/support/models/person.rb +20 -0
  170. data/spec/support/models/player.rb +33 -0
  171. data/spec/support/models/shipping_address.rb +34 -0
  172. data/spec/support/ruby_versions.rb +7 -0
  173. data/spec/support/shared_examples/active_record.rb +338 -0
  174. data/spec/support/shared_examples/hash_with_indifferent_access.rb +233 -0
  175. data/spec/unit/equality_matcher_spec.rb +579 -171
  176. data/spec/unit/object_inspection_spec.rb +1092 -0
  177. data/spec/unit/rspec/matchers/be_compared_to_spec.rb +23 -0
  178. data/spec/unit/rspec/matchers/be_falsey_spec.rb +9 -0
  179. data/spec/unit/rspec/matchers/be_nil_spec.rb +9 -0
  180. data/spec/unit/rspec/matchers/be_predicate_spec.rb +31 -0
  181. data/spec/unit/rspec/matchers/be_spec.rb +17 -0
  182. data/spec/unit/rspec/matchers/be_truthy_spec.rb +9 -0
  183. data/spec/unit/rspec/matchers/contain_exactly_spec.rb +11 -0
  184. data/spec/unit/rspec/matchers/eq_spec.rb +9 -0
  185. data/spec/unit/rspec/matchers/have_attributes_spec.rb +11 -0
  186. data/spec/unit/rspec/matchers/include_spec.rb +21 -0
  187. data/spec/unit/rspec/matchers/match_spec.rb +9 -0
  188. data/spec/unit/rspec/matchers/raise_error_spec.rb +29 -0
  189. data/spec/unit/rspec/matchers/respond_to_spec.rb +78 -0
  190. data/super_diff.gemspec +4 -2
  191. metadata +231 -34
  192. data/lib/super_diff/csi/color_helper.rb +0 -52
  193. data/lib/super_diff/csi/eight_bit_sequence.rb +0 -27
  194. data/lib/super_diff/csi/four_bit_sequence.rb +0 -24
  195. data/lib/super_diff/csi/sequence.rb +0 -22
  196. data/lib/super_diff/csi/twenty_four_bit_sequence.rb +0 -27
  197. data/lib/super_diff/diff_formatters/multi_line_string.rb +0 -31
  198. data/lib/super_diff/differs/object.rb +0 -68
  199. data/lib/super_diff/equality_matchers/object.rb +0 -18
  200. data/lib/super_diff/value_inspection.rb +0 -11
  201. data/spec/integration/rspec_spec.rb +0 -261
  202. data/spec/support/color_helper.rb +0 -49
  203. data/spec/support/person.rb +0 -23
  204. data/spec/support/person_diff_formatter.rb +0 -15
  205. data/spec/support/person_operation_sequence.rb +0 -14
  206. data/spec/support/person_operational_sequencer.rb +0 -19
@@ -0,0 +1,11 @@
1
+ class A
2
+ attr_reader :name
3
+
4
+ def initialize(name)
5
+ @name = name
6
+ end
7
+
8
+ def attributes_for_super_diff
9
+ { name: name }
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ module SuperDiff
2
+ module Test
3
+ module Models
4
+ module ActiveRecord
5
+ class Person < ::ActiveRecord::Base
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ ActiveRecord::Base.connection.create_table(:people) do |t|
13
+ t.string :name, null: false
14
+ t.integer :age, null: false
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.before do
19
+ ActiveRecord::Base.connection.execute(
20
+ "DELETE FROM people",
21
+ )
22
+ ActiveRecord::Base.connection.execute(
23
+ "DELETE FROM sqlite_sequence WHERE name='people'",
24
+ )
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ module SuperDiff
2
+ module Test
3
+ module Models
4
+ module ActiveRecord
5
+ class ShippingAddress < ::ActiveRecord::Base
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
11
+
12
+ ActiveRecord::Base.connection.create_table(:shipping_addresses) do |t|
13
+ t.string :line_1, null: false, default: ""
14
+ t.string :line_2, null: false, default: ""
15
+ t.string :city, null: false, default: ""
16
+ t.string :state, null: false, default: ""
17
+ t.string :zip, null: false, default: ""
18
+ end
19
+
20
+ RSpec.configure do |config|
21
+ config.before do
22
+ ActiveRecord::Base.connection.execute(
23
+ "DELETE FROM shipping_addresses",
24
+ )
25
+ ActiveRecord::Base.connection.execute(
26
+ "DELETE FROM sqlite_sequence WHERE name='shipping_addresses'",
27
+ )
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ module SuperDiff
2
+ module Test
3
+ class Customer
4
+ attr_reader :name, :shipping_address, :phone
5
+
6
+ def initialize(name:, shipping_address:, phone:)
7
+ @name = name
8
+ @shipping_address = shipping_address
9
+ @phone = phone
10
+ end
11
+
12
+ def ==(other)
13
+ other.is_a?(self.class) &&
14
+ other.name == name &&
15
+ other.shipping_address == shipping_address &&
16
+ other.phone == phone
17
+ end
18
+
19
+ def attributes_for_super_diff
20
+ { name: name, shipping_address: shipping_address, phone: phone }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ module SuperDiff
2
+ module Test
3
+ class EmptyClass
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module SuperDiff
2
+ module Test
3
+ class Item
4
+ def initialize(name:, quantity:)
5
+ @name = name
6
+ @quantity = quantity
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module SuperDiff
2
+ module Test
3
+ class Order
4
+ def initialize(items)
5
+ @items = items
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module SuperDiff
2
+ module Test
3
+ class Person
4
+ attr_reader :name, :age
5
+
6
+ def initialize(name:, age:)
7
+ @name = name
8
+ @age = age
9
+ end
10
+
11
+ def ==(other)
12
+ other.is_a?(self.class) && other.name == name && other.age == age
13
+ end
14
+
15
+ def attributes_for_super_diff
16
+ { name: name, age: age }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ module SuperDiff
2
+ module Test
3
+ class Player
4
+ attr_reader :handle, :character, :inventory, :shields, :health, :ultimate
5
+
6
+ def initialize(
7
+ handle:,
8
+ character:,
9
+ inventory:,
10
+ shields:,
11
+ health:,
12
+ ultimate:
13
+ )
14
+ @handle = handle
15
+ @character = character
16
+ @inventory = inventory
17
+ @shields = shields
18
+ @health = health
19
+ @ultimate = ultimate
20
+ end
21
+
22
+ def ==(other)
23
+ other.is_a?(self.class) &&
24
+ other.handle == handle &&
25
+ other.character == character &&
26
+ other.inventory == inventory &&
27
+ other.shields == shields &&
28
+ other.health == health &&
29
+ other.ultimate == ultimate
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ module SuperDiff
2
+ module Test
3
+ class ShippingAddress
4
+ attr_reader :line_1, :line_2, :city, :state, :zip
5
+
6
+ def initialize(line_1:, line_2:, city:, state:, zip:)
7
+ @line_1 = line_1
8
+ @line_2 = line_2
9
+ @city = city
10
+ @state = state
11
+ @zip = zip
12
+ end
13
+
14
+ def ==(other)
15
+ other.is_a?(self.class) &&
16
+ other.line_1 == line_1 &&
17
+ other.line_2 == line_2 &&
18
+ other.city == city &&
19
+ other.state == state &&
20
+ other.zip == zip
21
+ end
22
+
23
+ def attributes_for_super_diff
24
+ {
25
+ line_1: line_1,
26
+ line_2: line_2,
27
+ city: city,
28
+ state: state,
29
+ zip: zip
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ module SuperDiff
2
+ module Test
3
+ def self.jruby?
4
+ defined?(JRUBY_VERSION)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,338 @@
1
+ shared_examples_for "integration with ActiveRecord" do
2
+ describe "and RSpec's #eq matcher" do
3
+ context "when comparing two instances of the same ActiveRecord model" do
4
+ it "produces the correct output" do
5
+ as_both_colored_and_uncolored do |color_enabled|
6
+ snippet = <<~TEST.strip
7
+ expected = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
8
+ line_1: "123 Main St.",
9
+ city: "Hill Valley",
10
+ state: "CA",
11
+ zip: "90382",
12
+ )
13
+ actual = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
14
+ line_1: "456 Ponderosa Ct.",
15
+ city: "Oakland",
16
+ state: "CA",
17
+ zip: "91234",
18
+ )
19
+ expect(actual).to eq(expected)
20
+ TEST
21
+ program = make_program(snippet, color_enabled: color_enabled)
22
+
23
+ expected_output = build_expected_output(
24
+ color_enabled: color_enabled,
25
+ snippet: "expect(actual).to eq(expected)",
26
+ expectation: proc {
27
+ line do
28
+ plain "Expected "
29
+ beta %|#<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: nil, city: "Oakland", line_1: "456 Ponderosa Ct.", line_2: "", state: "CA", zip: "91234">|
30
+ end
31
+
32
+ line do
33
+ plain " to eq "
34
+ alpha %|#<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: nil, city: "Hill Valley", line_1: "123 Main St.", line_2: "", state: "CA", zip: "90382">|
35
+ end
36
+ },
37
+ diff: proc {
38
+ plain_line %| #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress {|
39
+ plain_line %| id: nil,|
40
+ alpha_line %|- city: "Hill Valley",|
41
+ beta_line %|+ city: "Oakland",|
42
+ alpha_line %|- line_1: "123 Main St.",|
43
+ beta_line %|+ line_1: "456 Ponderosa Ct.",|
44
+ plain_line %| line_2: "",|
45
+ plain_line %| state: "CA",|
46
+ alpha_line %|- zip: "90382"|
47
+ beta_line %|+ zip: "91234"|
48
+ plain_line %| }>|
49
+ },
50
+ )
51
+
52
+ expect(program).
53
+ to produce_output_when_run(expected_output).
54
+ in_color(color_enabled)
55
+ end
56
+ end
57
+ end
58
+
59
+ context "when comparing instances of two different ActiveRecord models" do
60
+ it "produces the correct output" do
61
+ as_both_colored_and_uncolored do |color_enabled|
62
+ snippet = <<~TEST.strip
63
+ expected = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
64
+ line_1: "123 Main St.",
65
+ city: "Hill Valley",
66
+ state: "CA",
67
+ zip: "90382",
68
+ )
69
+ actual = SuperDiff::Test::Models::ActiveRecord::Person.new(
70
+ name: "Elliot",
71
+ age: 31,
72
+ )
73
+ expect(actual).to eq(expected)
74
+ TEST
75
+ program = make_program(snippet, color_enabled: color_enabled)
76
+
77
+ expected_output = build_expected_output(
78
+ color_enabled: color_enabled,
79
+ snippet: "expect(actual).to eq(expected)",
80
+ newline_before_expectation: true,
81
+ expectation: proc {
82
+ line do
83
+ plain "Expected "
84
+ beta %|#<SuperDiff::Test::Models::ActiveRecord::Person id: nil, age: 31, name: "Elliot">|
85
+ end
86
+
87
+ line do
88
+ plain " to eq "
89
+ alpha %|#<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: nil, city: "Hill Valley", line_1: "123 Main St.", line_2: "", state: "CA", zip: "90382">|
90
+ end
91
+ },
92
+ )
93
+
94
+ expect(program).
95
+ to produce_output_when_run(expected_output).
96
+ in_color(color_enabled)
97
+ end
98
+ end
99
+ end
100
+
101
+ context "when comparing an ActiveRecord object with nothing" do
102
+ it "produces the correct output" do
103
+ as_both_colored_and_uncolored do |color_enabled|
104
+ snippet = <<~TEST.strip
105
+ expected = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
106
+ line_1: "123 Main St.",
107
+ city: "Hill Valley",
108
+ state: "CA",
109
+ zip: "90382"
110
+ )
111
+ actual = nil
112
+ expect(actual).to eq(expected)
113
+ TEST
114
+ program = make_program(snippet, color_enabled: color_enabled)
115
+
116
+ expected_output = build_expected_output(
117
+ color_enabled: color_enabled,
118
+ snippet: "expect(actual).to eq(expected)",
119
+ newline_before_expectation: true,
120
+ expectation: proc {
121
+ line do
122
+ plain "Expected "
123
+ beta %|nil|
124
+ end
125
+
126
+ line do
127
+ plain " to eq "
128
+ alpha %|#<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: nil, city: "Hill Valley", line_1: "123 Main St.", line_2: "", state: "CA", zip: "90382">|
129
+ end
130
+ },
131
+ )
132
+
133
+ expect(program).
134
+ to produce_output_when_run(expected_output).
135
+ in_color(color_enabled)
136
+ end
137
+ end
138
+ end
139
+
140
+ context "when comparing two data structures that contain two instances of the same ActiveRecord model" do
141
+ it "produces the correct output" do
142
+ as_both_colored_and_uncolored do |color_enabled|
143
+ snippet = <<~TEST.strip
144
+ expected = {
145
+ name: "Marty McFly",
146
+ shipping_address: SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
147
+ line_1: "123 Main St.",
148
+ city: "Hill Valley",
149
+ state: "CA",
150
+ zip: "90382",
151
+ )
152
+ }
153
+ actual = {
154
+ name: "Marty McFly",
155
+ shipping_address: SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
156
+ line_1: "456 Ponderosa Ct.",
157
+ city: "Oakland",
158
+ state: "CA",
159
+ zip: "91234",
160
+ )
161
+ }
162
+ expect(actual).to eq(expected)
163
+ TEST
164
+ program = make_program(snippet, color_enabled: color_enabled)
165
+
166
+ expected_output = build_expected_output(
167
+ color_enabled: color_enabled,
168
+ snippet: "expect(actual).to eq(expected)",
169
+ expectation: proc {
170
+ line do
171
+ plain "Expected "
172
+ beta %|{ name: "Marty McFly", shipping_address: #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: nil, city: "Oakland", line_1: "456 Ponderosa Ct.", line_2: "", state: "CA", zip: "91234"> }|
173
+ end
174
+
175
+ line do
176
+ plain " to eq "
177
+ alpha %|{ name: "Marty McFly", shipping_address: #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: nil, city: "Hill Valley", line_1: "123 Main St.", line_2: "", state: "CA", zip: "90382"> }|
178
+ end
179
+ },
180
+ diff: proc {
181
+ plain_line %| {|
182
+ plain_line %| name: "Marty McFly",|
183
+ plain_line %| shipping_address: #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress {|
184
+ plain_line %| id: nil,|
185
+ alpha_line %|- city: "Hill Valley",|
186
+ beta_line %|+ city: "Oakland",|
187
+ alpha_line %|- line_1: "123 Main St.",|
188
+ beta_line %|+ line_1: "456 Ponderosa Ct.",|
189
+ plain_line %| line_2: "",|
190
+ plain_line %| state: "CA",|
191
+ alpha_line %|- zip: "90382"|
192
+ beta_line %|+ zip: "91234"|
193
+ plain_line %| }>|
194
+ plain_line %| }|
195
+ },
196
+ )
197
+
198
+ expect(program).
199
+ to produce_output_when_run(expected_output).
200
+ in_color(color_enabled)
201
+ end
202
+ end
203
+ end
204
+
205
+ context "when comparing two data structures that contain instances of two different ActiveRecord models" do
206
+ it "produces the correct output" do
207
+ as_both_colored_and_uncolored do |color_enabled|
208
+ snippet = <<~TEST.strip
209
+ expected = {
210
+ name: "Marty McFly",
211
+ shipping_address: SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
212
+ line_1: "123 Main St.",
213
+ city: "Hill Valley",
214
+ state: "CA",
215
+ zip: "90382",
216
+ )
217
+ }
218
+ actual = {
219
+ name: "Marty McFly",
220
+ shipping_address: SuperDiff::Test::Models::ActiveRecord::Person.new(
221
+ name: "Elliot",
222
+ age: 31,
223
+ )
224
+ }
225
+ expect(actual).to eq(expected)
226
+ TEST
227
+ program = make_program(snippet, color_enabled: color_enabled)
228
+
229
+ expected_output = build_expected_output(
230
+ color_enabled: color_enabled,
231
+ snippet: "expect(actual).to eq(expected)",
232
+ expectation: proc {
233
+ line do
234
+ plain "Expected "
235
+ beta %|{ name: "Marty McFly", shipping_address: #<SuperDiff::Test::Models::ActiveRecord::Person id: nil, age: 31, name: "Elliot"> }|
236
+ end
237
+
238
+ line do
239
+ plain " to eq "
240
+ alpha %|{ name: "Marty McFly", shipping_address: #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: nil, city: "Hill Valley", line_1: "123 Main St.", line_2: "", state: "CA", zip: "90382"> }|
241
+ end
242
+ },
243
+ diff: proc {
244
+ plain_line %| {|
245
+ plain_line %| name: "Marty McFly",|
246
+ alpha_line %|- shipping_address: #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress {|
247
+ alpha_line %|- id: nil,|
248
+ alpha_line %|- city: "Hill Valley",|
249
+ alpha_line %|- line_1: "123 Main St.",|
250
+ alpha_line %|- line_2: "",|
251
+ alpha_line %|- state: "CA",|
252
+ alpha_line %|- zip: "90382"|
253
+ alpha_line %|- }>|
254
+ beta_line %|+ shipping_address: #<SuperDiff::Test::Models::ActiveRecord::Person {|
255
+ beta_line %|+ id: nil,|
256
+ beta_line %|+ age: 31,|
257
+ beta_line %|+ name: "Elliot"|
258
+ beta_line %|+ }>|
259
+ plain_line %| }|
260
+ },
261
+ )
262
+
263
+ expect(program).
264
+ to produce_output_when_run(expected_output).
265
+ in_color(color_enabled)
266
+ end
267
+ end
268
+ end
269
+
270
+ context "when comparing an ActiveRecord::Relation object with an array" do
271
+ it "produces the correct output" do
272
+ as_both_colored_and_uncolored do |color_enabled|
273
+ snippet = <<~TEST.strip
274
+ SuperDiff::Test::Models::ActiveRecord::ShippingAddress.delete_all
275
+ shipping_addresses = [
276
+ SuperDiff::Test::Models::ActiveRecord::ShippingAddress.create!(
277
+ line_1: "123 Main St.",
278
+ city: "Hill Valley",
279
+ state: "CA",
280
+ zip: "90382",
281
+ ),
282
+ SuperDiff::Test::Models::ActiveRecord::ShippingAddress.create!(
283
+ line_1: "456 Ponderosa Ct.",
284
+ city: "Oakland",
285
+ state: "CA",
286
+ zip: "91234",
287
+ )
288
+ ]
289
+ expected = [shipping_addresses.first]
290
+ actual = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.all
291
+ expect(actual).to eq(expected)
292
+ TEST
293
+ program = make_program(snippet, color_enabled: color_enabled)
294
+
295
+ expected_output = build_expected_output(
296
+ color_enabled: color_enabled,
297
+ snippet: "expect(actual).to eq(expected)",
298
+ expectation: proc {
299
+ line do
300
+ plain "Expected "
301
+ beta %|#<ActiveRecord::Relation [#<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: 1, city: "Hill Valley", line_1: "123 Main St.", line_2: "", state: "CA", zip: "90382">, #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: 2, city: "Oakland", line_1: "456 Ponderosa Ct.", line_2: "", state: "CA", zip: "91234">]>|
302
+ end
303
+
304
+ line do
305
+ plain " to eq "
306
+ alpha %|[#<SuperDiff::Test::Models::ActiveRecord::ShippingAddress id: 1, city: "Hill Valley", line_1: "123 Main St.", line_2: "", state: "CA", zip: "90382">]|
307
+ end
308
+ },
309
+ diff: proc {
310
+ plain_line %| #<ActiveRecord::Relation [|
311
+ plain_line %| #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress {|
312
+ plain_line %| id: 1,|
313
+ plain_line %| city: "Hill Valley",|
314
+ plain_line %| line_1: "123 Main St.",|
315
+ plain_line %| line_2: "",|
316
+ plain_line %| state: "CA",|
317
+ plain_line %| zip: "90382"|
318
+ plain_line %| }>,|
319
+ beta_line %|+ #<SuperDiff::Test::Models::ActiveRecord::ShippingAddress {|
320
+ beta_line %|+ id: 2,|
321
+ beta_line %|+ city: "Oakland",|
322
+ beta_line %|+ line_1: "456 Ponderosa Ct.",|
323
+ beta_line %|+ line_2: "",|
324
+ beta_line %|+ state: "CA",|
325
+ beta_line %|+ zip: "91234"|
326
+ beta_line %|+ }>|
327
+ plain_line %| ]>|
328
+ },
329
+ )
330
+
331
+ expect(program).
332
+ to produce_output_when_run(expected_output).
333
+ in_color(color_enabled)
334
+ end
335
+ end
336
+ end
337
+ end
338
+ end