super_diff 0.10.0 → 0.11.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders/active_record_model.rb +24 -12
  3. data/lib/super_diff/active_record/object_inspection/inspection_tree_builders/active_record_relation.rb +15 -6
  4. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders/hash_with_indifferent_access.rb +23 -8
  5. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders/ordered_options.rb +46 -0
  6. data/lib/super_diff/active_support/object_inspection/inspection_tree_builders.rb +4 -0
  7. data/lib/super_diff/active_support.rb +2 -1
  8. data/lib/super_diff/differs/date_like.rb +15 -0
  9. data/lib/super_diff/differs/defaults.rb +1 -0
  10. data/lib/super_diff/differs.rb +1 -0
  11. data/lib/super_diff/errors.rb +0 -4
  12. data/lib/super_diff/object_inspection/inspection_tree.rb +25 -20
  13. data/lib/super_diff/object_inspection/inspection_tree_builders/array.rb +31 -12
  14. data/lib/super_diff/object_inspection/inspection_tree_builders/custom_object.rb +19 -9
  15. data/lib/super_diff/object_inspection/inspection_tree_builders/date_like.rb +51 -0
  16. data/lib/super_diff/object_inspection/inspection_tree_builders/default_object.rb +46 -21
  17. data/lib/super_diff/object_inspection/inspection_tree_builders/defaults.rb +1 -0
  18. data/lib/super_diff/object_inspection/inspection_tree_builders/hash.rb +39 -14
  19. data/lib/super_diff/object_inspection/inspection_tree_builders/primitive.rb +3 -5
  20. data/lib/super_diff/object_inspection/inspection_tree_builders/time_like.rb +31 -20
  21. data/lib/super_diff/object_inspection/inspection_tree_builders.rb +4 -0
  22. data/lib/super_diff/object_inspection/nodes/as_lines_when_rendering_to_lines.rb +3 -2
  23. data/lib/super_diff/operation_tree_builders/date_like.rb +15 -0
  24. data/lib/super_diff/operation_tree_builders/defaults.rb +1 -1
  25. data/lib/super_diff/operation_tree_builders.rb +1 -0
  26. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +3 -7
  27. data/lib/super_diff/rspec/monkey_patches.rb +59 -8
  28. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/collection_containing_exactly.rb +14 -7
  29. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/collection_including.rb +19 -13
  30. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/double.rb +30 -26
  31. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/generic_describable_matcher.rb +19 -0
  32. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/hash_including.rb +19 -14
  33. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/instance_of.rb +9 -10
  34. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/kind_of.rb +9 -10
  35. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/object_having_attributes.rb +14 -7
  36. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders/value_within.rb +10 -11
  37. data/lib/super_diff/rspec/object_inspection/inspection_tree_builders.rb +4 -0
  38. data/lib/super_diff/rspec.rb +10 -9
  39. data/lib/super_diff/version.rb +1 -1
  40. data/lib/super_diff.rb +9 -0
  41. data/spec/examples.txt +543 -493
  42. data/spec/integration/rails/engines_spec.rb +8 -3
  43. data/spec/integration/rspec/contain_exactly_matcher_spec.rb +19 -19
  44. data/spec/integration/rspec/eq_matcher_spec.rb +111 -39
  45. data/spec/integration/rspec/generic_describable_matchers_spec.rb +177 -0
  46. data/spec/integration/rspec/have_attributes_matcher_spec.rb +25 -25
  47. data/spec/integration/rspec/include_matcher_spec.rb +23 -23
  48. data/spec/integration/rspec/magic_metadata_spec.rb +51 -0
  49. data/spec/integration/rspec/match_array_matcher_spec.rb +30 -30
  50. data/spec/integration/rspec/match_matcher_spec.rb +93 -93
  51. data/spec/integration/rspec/raise_error_matcher_spec.rb +813 -69
  52. data/spec/internal/log/test.log +0 -0
  53. data/spec/spec_helper.rb +3 -0
  54. data/spec/support/integration/helpers.rb +15 -10
  55. data/spec/support/integration/matchers.rb +34 -0
  56. data/spec/support/integration/test_programs/base.rb +6 -6
  57. data/spec/support/integration/test_programs/rspec_rails_engine.rb +3 -13
  58. data/spec/support/shared_examples/active_record.rb +33 -33
  59. data/spec/support/shared_examples/active_support.rb +125 -4
  60. data/spec/support/shared_examples/elided_diffs.rb +48 -48
  61. data/spec/support/shared_examples/hash_with_indifferent_access.rb +88 -88
  62. data/spec/support/shared_examples/key.rb +10 -10
  63. data/spec/unit/active_support/object_inspection_spec.rb +170 -0
  64. data/spec/unit/rspec/matchers/raise_error_spec.rb +43 -11
  65. data/spec/unit/rspec/object_inspection/rspec_matcher_spec.rb +91 -0
  66. data/spec/unit/rspec/object_inspection_spec.rb +2 -2
  67. data/spec/unit/super_diff_spec.rb +64 -0
  68. metadata +17 -4
  69. data/lib/super_diff/errors/no_diff_formatter_available_error.rb +0 -21
  70. data/lib/super_diff/errors/no_operational_sequencer_available_error.rb +0 -22
File without changes
data/spec/spec_helper.rb CHANGED
@@ -65,6 +65,9 @@ RSpec.configure do |config|
65
65
  config.default_formatter = "documentation" if !%w[true 1].include?(ENV["CI"])
66
66
 
67
67
  config.filter_run_excluding active_record: true unless active_record_available
68
+ unless defined?(ActiveSupport)
69
+ config.filter_run_excluding active_support: true
70
+ end
68
71
 
69
72
  config.order = :random
70
73
  Kernel.srand config.seed
@@ -9,13 +9,13 @@ module SuperDiff
9
9
  def make_plain_test_program(
10
10
  test,
11
11
  color_enabled:,
12
- configuration: {},
12
+ super_diff_configuration: {},
13
13
  preserve_as_whole_file: false
14
14
  )
15
15
  TestPrograms::Plain.new(
16
16
  test,
17
17
  color_enabled: color_enabled,
18
- configuration: configuration,
18
+ super_diff_configuration: super_diff_configuration,
19
19
  preserve_as_whole_file: preserve_as_whole_file
20
20
  )
21
21
  end
@@ -32,15 +32,13 @@ module SuperDiff
32
32
  TestPrograms::RSpecRails.new(test, color_enabled: color_enabled)
33
33
  end
34
34
 
35
- def make_rspec_rails_engine_program(
35
+ def make_rspec_rails_engine_with_action_controller_program(
36
36
  test,
37
- color_enabled:,
38
- combustion_initialize:
37
+ color_enabled:
39
38
  )
40
- TestPrograms::RspecRailsEngine.new(
39
+ TestPrograms::RspecRailsEngineWithActionController.new(
41
40
  test,
42
- color_enabled: color_enabled,
43
- combustion_initialize: combustion_initialize
41
+ color_enabled: color_enabled
44
42
  )
45
43
  end
46
44
 
@@ -48,15 +46,17 @@ module SuperDiff
48
46
  color_enabled:,
49
47
  snippet:,
50
48
  expectation:,
49
+ test_name: "test passes",
51
50
  key_enabled: true,
52
51
  newline_before_expectation: false,
53
52
  indentation: 7,
54
- diff: nil
53
+ diff: nil,
54
+ extra_failure_lines: nil
55
55
  )
56
56
  colored(color_enabled: color_enabled) do
57
57
  line "Failures:\n"
58
58
 
59
- line "1) test passes", indent_by: 2
59
+ line "1) #{test_name}", indent_by: 2
60
60
 
61
61
  line indent_by: 5 do
62
62
  bold "Failure/Error: "
@@ -106,6 +106,11 @@ module SuperDiff
106
106
  newline
107
107
  end
108
108
  end
109
+
110
+ if extra_failure_lines
111
+ newline
112
+ evaluate_block(&extra_failure_lines)
113
+ end
109
114
  end
110
115
  end
111
116
 
@@ -32,6 +32,40 @@ module SuperDiff
32
32
  PassWithSinglelineFailureMessageMatcher.new
33
33
  end
34
34
 
35
+ RSpec::Matchers.define :failing_custom_matcher_from_dsl do |value|
36
+ match { false }
37
+
38
+ description do
39
+ "custom matcher defined via the DSL with value #{value.inspect}"
40
+ end
41
+ end
42
+
43
+ def failing_custom_matcher_from_scratch(value)
44
+ FailingCustomMatcherFromScratch.new(value)
45
+ end
46
+
47
+ class FailingCustomMatcherFromScratch
48
+ def initialize(value)
49
+ @value = value
50
+ end
51
+
52
+ def matches?(_)
53
+ false
54
+ end
55
+
56
+ def description
57
+ "custom matcher defined from scratch with value #{value.inspect}"
58
+ end
59
+
60
+ def failure_message
61
+ "Expected custom matcher not to fail, but did"
62
+ end
63
+
64
+ private
65
+
66
+ attr_reader :value
67
+ end
68
+
35
69
  class FailWithIndentedMultilineFailureMessageMatcher
36
70
  def matches?(_)
37
71
  false
@@ -13,12 +13,12 @@ module SuperDiff
13
13
  def initialize(
14
14
  code,
15
15
  color_enabled:,
16
- configuration: {},
16
+ super_diff_configuration: {},
17
17
  preserve_as_whole_file: false
18
18
  )
19
19
  @code = code.strip
20
20
  @color_enabled = color_enabled
21
- @configuration = configuration
21
+ @super_diff_configuration = super_diff_configuration
22
22
  @preserve_as_whole_file = preserve_as_whole_file
23
23
  end
24
24
 
@@ -38,7 +38,7 @@ module SuperDiff
38
38
 
39
39
  private
40
40
 
41
- attr_reader :code, :configuration
41
+ attr_reader :code, :super_diff_configuration
42
42
 
43
43
  def color_enabled?
44
44
  @color_enabled
@@ -74,8 +74,8 @@ module SuperDiff
74
74
  color_option,
75
75
  "--no-pry",
76
76
  tempfile.to_s,
77
- "--configuration",
78
- JSON.generate(configuration)
77
+ "--super-diff-configuration",
78
+ JSON.generate(super_diff_configuration)
79
79
  ]
80
80
  else
81
81
  ["rspec", "--options", "/tmp/dummy-rspec-config", tempfile.to_s]
@@ -110,7 +110,7 @@ module SuperDiff
110
110
  test_plan = TestPlan.new(
111
111
  using_outside_of_zeus: true,
112
112
  color_enabled: #{color_enabled?.inspect},
113
- configuration: #{configuration.inspect}
113
+ super_diff_configuration: #{super_diff_configuration.inspect}
114
114
  )
115
115
  #{test_plan_prelude}
116
116
  test_plan.#{test_plan_command}
@@ -1,29 +1,19 @@
1
1
  module SuperDiff
2
2
  module IntegrationTests
3
3
  module TestPrograms
4
- class RspecRailsEngine < Base
5
- def initialize(*args, combustion_initialize:, **options)
6
- super(*args, **options)
7
- @combustion_initialize = combustion_initialize
8
- end
9
-
4
+ class RspecRailsEngineWithActionController < Base
10
5
  protected
11
6
 
12
7
  def test_plan_prelude
13
8
  <<~PRELUDE.strip
14
- test_plan.boot_rails_engine(
15
- combustion_initialize: #{combustion_initialize.inspect}
16
- )
9
+ test_plan.boot
10
+ test_plan.boot_rails_engine_with_action_controller
17
11
  PRELUDE
18
12
  end
19
13
 
20
14
  def test_plan_command
21
15
  "run_rspec_rails_test"
22
16
  end
23
-
24
- private
25
-
26
- attr_reader :combustion_initialize
27
17
  end
28
18
  end
29
19
  end
@@ -4,18 +4,18 @@ shared_examples_for "integration with ActiveRecord" do
4
4
  it "produces the correct output" do
5
5
  as_both_colored_and_uncolored do |color_enabled|
6
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
7
  actual = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
14
8
  line_1: "456 Ponderosa Ct.",
15
9
  city: "Oakland",
16
10
  state: "CA",
17
11
  zip: "91234",
18
12
  )
13
+ expected = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
14
+ line_1: "123 Main St.",
15
+ city: "Hill Valley",
16
+ state: "CA",
17
+ zip: "90382",
18
+ )
19
19
  expect(actual).to eq(expected)
20
20
  TEST
21
21
  program = make_program(snippet, color_enabled: color_enabled)
@@ -63,16 +63,16 @@ shared_examples_for "integration with ActiveRecord" do
63
63
  it "produces the correct output" do
64
64
  as_both_colored_and_uncolored do |color_enabled|
65
65
  snippet = <<~TEST.strip
66
+ actual = SuperDiff::Test::Models::ActiveRecord::Person.new(
67
+ name: "Elliot",
68
+ age: 31,
69
+ )
66
70
  expected = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
67
71
  line_1: "123 Main St.",
68
72
  city: "Hill Valley",
69
73
  state: "CA",
70
74
  zip: "90382",
71
75
  )
72
- actual = SuperDiff::Test::Models::ActiveRecord::Person.new(
73
- name: "Elliot",
74
- age: 31,
75
- )
76
76
  expect(actual).to eq(expected)
77
77
  TEST
78
78
  program = make_program(snippet, color_enabled: color_enabled)
@@ -107,13 +107,13 @@ shared_examples_for "integration with ActiveRecord" do
107
107
  it "produces the correct output" do
108
108
  as_both_colored_and_uncolored do |color_enabled|
109
109
  snippet = <<~TEST.strip
110
+ actual = nil
110
111
  expected = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
111
112
  line_1: "123 Main St.",
112
113
  city: "Hill Valley",
113
114
  state: "CA",
114
115
  zip: "90382"
115
116
  )
116
- actual = nil
117
117
  expect(actual).to eq(expected)
118
118
  TEST
119
119
  program = make_program(snippet, color_enabled: color_enabled)
@@ -148,22 +148,22 @@ shared_examples_for "integration with ActiveRecord" do
148
148
  it "produces the correct output" do
149
149
  as_both_colored_and_uncolored do |color_enabled|
150
150
  snippet = <<~TEST.strip
151
- expected = {
151
+ actual = {
152
152
  name: "Marty McFly",
153
153
  shipping_address: SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
154
- line_1: "123 Main St.",
155
- city: "Hill Valley",
154
+ line_1: "456 Ponderosa Ct.",
155
+ city: "Oakland",
156
156
  state: "CA",
157
- zip: "90382",
157
+ zip: "91234",
158
158
  )
159
159
  }
160
- actual = {
160
+ expected = {
161
161
  name: "Marty McFly",
162
162
  shipping_address: SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
163
- line_1: "456 Ponderosa Ct.",
164
- city: "Oakland",
163
+ line_1: "123 Main St.",
164
+ city: "Hill Valley",
165
165
  state: "CA",
166
- zip: "91234",
166
+ zip: "90382",
167
167
  )
168
168
  }
169
169
  expect(actual).to eq(expected)
@@ -216,6 +216,13 @@ shared_examples_for "integration with ActiveRecord" do
216
216
  it "produces the correct output" do
217
217
  as_both_colored_and_uncolored do |color_enabled|
218
218
  snippet = <<~TEST.strip
219
+ actual = {
220
+ name: "Marty McFly",
221
+ shipping_address: SuperDiff::Test::Models::ActiveRecord::Person.new(
222
+ name: "Elliot",
223
+ age: 31,
224
+ )
225
+ }
219
226
  expected = {
220
227
  name: "Marty McFly",
221
228
  shipping_address: SuperDiff::Test::Models::ActiveRecord::ShippingAddress.new(
@@ -225,13 +232,6 @@ shared_examples_for "integration with ActiveRecord" do
225
232
  zip: "90382",
226
233
  )
227
234
  }
228
- actual = {
229
- name: "Marty McFly",
230
- shipping_address: SuperDiff::Test::Models::ActiveRecord::Person.new(
231
- name: "Elliot",
232
- age: 31,
233
- )
234
- }
235
235
  expect(actual).to eq(expected)
236
236
  TEST
237
237
  program = make_program(snippet, color_enabled: color_enabled)
@@ -299,8 +299,8 @@ shared_examples_for "integration with ActiveRecord" do
299
299
  zip: "91234",
300
300
  )
301
301
  ]
302
- expected = [shipping_addresses.first]
303
302
  actual = SuperDiff::Test::Models::ActiveRecord::ShippingAddress.all
303
+ expected = [shipping_addresses.first]
304
304
  expect(actual).to eq(expected)
305
305
  TEST
306
306
  program = make_program(snippet, color_enabled: color_enabled)
@@ -362,6 +362,12 @@ shared_examples_for "integration with ActiveRecord" do
362
362
  age: 20
363
363
  )
364
364
 
365
+ actual = [
366
+ SuperDiff::Test::Models::ActiveRecord::Query.new(
367
+ results: SuperDiff::Test::Models::ActiveRecord::Person.all
368
+ )
369
+ ]
370
+
365
371
  expected = [
366
372
  an_object_having_attributes(
367
373
  results: [
@@ -370,12 +376,6 @@ shared_examples_for "integration with ActiveRecord" do
370
376
  )
371
377
  ]
372
378
 
373
- actual = [
374
- SuperDiff::Test::Models::ActiveRecord::Query.new(
375
- results: SuperDiff::Test::Models::ActiveRecord::Person.all
376
- )
377
- ]
378
-
379
379
  expect(actual).to match(expected)
380
380
  TEST
381
381
 
@@ -4,9 +4,9 @@ shared_examples_for "integration with ActiveSupport" do
4
4
  it "produces the correct failure message when used in the positive" do
5
5
  as_both_colored_and_uncolored do |color_enabled|
6
6
  snippet = <<~RUBY
7
- expected = Time.utc(2011, 12, 13, 14, 15, 16)
8
- actual = Time.utc(2011, 12, 13, 15, 15, 16).in_time_zone("Europe/Stockholm")
9
- expect(expected).to eq(actual)
7
+ actual = Time.utc(2011, 12, 13, 14, 15, 16)
8
+ expected = Time.utc(2011, 12, 13, 15, 15, 16).in_time_zone("Europe/Stockholm")
9
+ expect(actual).to eq(expected)
10
10
  RUBY
11
11
  program =
12
12
  make_rspec_rails_test_program(snippet, color_enabled: color_enabled)
@@ -14,7 +14,7 @@ shared_examples_for "integration with ActiveSupport" do
14
14
  expected_output =
15
15
  build_expected_output(
16
16
  color_enabled: color_enabled,
17
- snippet: "expect(expected).to eq(actual)",
17
+ snippet: "expect(actual).to eq(expected)",
18
18
  expectation:
19
19
  proc do
20
20
  line do
@@ -64,4 +64,125 @@ shared_examples_for "integration with ActiveSupport" do
64
64
  end
65
65
  end
66
66
  end
67
+
68
+ context "when comparing OrderedOptions and Hash instances",
69
+ active_record: true do
70
+ it "produces the correct failure message when used in the positive" do
71
+ as_both_colored_and_uncolored do |color_enabled|
72
+ snippet = <<~RUBY
73
+ actual = {beep: :bip}
74
+ expected = ::ActiveSupport::OrderedOptions[beep: :boop]
75
+ expect(actual).to eq(expected)
76
+ RUBY
77
+ program =
78
+ make_rspec_rails_test_program(snippet, color_enabled: color_enabled)
79
+
80
+ expected_output =
81
+ build_expected_output(
82
+ color_enabled: color_enabled,
83
+ snippet: "expect(actual).to eq(expected)",
84
+ expectation:
85
+ proc do
86
+ line do
87
+ plain "Expected "
88
+ actual "{ beep: :bip }"
89
+ plain " to eq "
90
+ expected "#<OrderedOptions { beep: :boop }>"
91
+ plain "."
92
+ end
93
+ end,
94
+ diff:
95
+ proc do
96
+ plain_line " {"
97
+ expected_line "- beep: :boop"
98
+ actual_line "+ beep: :bip"
99
+ plain_line " }"
100
+ end
101
+ )
102
+
103
+ expect(program).to produce_output_when_run(expected_output).in_color(
104
+ color_enabled
105
+ )
106
+ end
107
+ end
108
+ end
109
+
110
+ context "when comparing Date instance and date-like DateTime instance for same day",
111
+ active_record: true do
112
+ it "produces the correct failure message when used in the positive" do
113
+ as_both_colored_and_uncolored do |color_enabled|
114
+ snippet = <<~RUBY
115
+ actual = Date.new(2023, 10, 14)
116
+ expected = DateTime.new(2023, 10, 14, 18, 22, 26)
117
+ expect(actual).to eq(expected)
118
+ RUBY
119
+ program =
120
+ make_rspec_rails_test_program(snippet, color_enabled: color_enabled)
121
+
122
+ expected_output =
123
+ build_expected_output(
124
+ color_enabled: color_enabled,
125
+ snippet: "expect(actual).to eq(expected)",
126
+ expectation:
127
+ proc do
128
+ line do
129
+ plain "Expected "
130
+ actual "#<Date 2023-10-14>"
131
+ plain " to eq "
132
+ expected "#<DateTime 2023-10-14 18:22:26 +00:00 (+00:00)>"
133
+ plain "."
134
+ end
135
+ end
136
+ )
137
+
138
+ expect(program).to produce_output_when_run(expected_output).in_color(
139
+ color_enabled
140
+ )
141
+ end
142
+ end
143
+ end
144
+
145
+ context "when comparing Date instance and date-like DateTime instance for another day",
146
+ active_record: true do
147
+ it "produces the diff for date like objects comparison" do
148
+ as_both_colored_and_uncolored do |color_enabled|
149
+ snippet = <<~RUBY
150
+ actual = Date.new(2023, 10, 14)
151
+ expected = DateTime.new(2023, 10, 31, 18, 22, 26)
152
+ expect(actual).to eq(expected)
153
+ RUBY
154
+ program =
155
+ make_rspec_rails_test_program(snippet, color_enabled: color_enabled)
156
+
157
+ expected_output =
158
+ build_expected_output(
159
+ color_enabled: color_enabled,
160
+ snippet: "expect(actual).to eq(expected)",
161
+ expectation:
162
+ proc do
163
+ line do
164
+ plain "Expected "
165
+ actual "#<Date 2023-10-14>"
166
+ plain " to eq "
167
+ expected "#<DateTime 2023-10-31 18:22:26 +00:00 (+00:00)>"
168
+ plain "."
169
+ end
170
+ end,
171
+ diff:
172
+ proc do
173
+ plain_line " #<Date {"
174
+ plain_line " year: 2023,"
175
+ plain_line " month: 10,"
176
+ expected_line "- day: 31"
177
+ actual_line "+ day: 14"
178
+ plain_line " }>"
179
+ end
180
+ )
181
+
182
+ expect(program).to produce_output_when_run(expected_output).in_color(
183
+ color_enabled
184
+ )
185
+ end
186
+ end
187
+ end
67
188
  end