super_diff 0.3.0 → 0.4.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/lib/super_diff/active_record.rb +2 -0
  4. data/lib/super_diff/active_record/monkey_patches.rb +9 -0
  5. data/lib/super_diff/csi.rb +4 -0
  6. data/lib/super_diff/equality_matchers/default.rb +1 -1
  7. data/lib/super_diff/operation_sequences/base.rb +14 -0
  8. data/lib/super_diff/rspec.rb +9 -9
  9. data/lib/super_diff/rspec/differ.rb +6 -6
  10. data/lib/super_diff/rspec/differs.rb +9 -3
  11. data/lib/super_diff/rspec/differs/collection_containing_exactly.rb +1 -1
  12. data/lib/super_diff/rspec/differs/{partial_hash.rb → collection_including.rb} +4 -3
  13. data/lib/super_diff/rspec/differs/{partial_array.rb → hash_including.rb} +4 -3
  14. data/lib/super_diff/rspec/differs/{partial_object.rb → object_having_attributes.rb} +3 -3
  15. data/lib/super_diff/rspec/matcher_text_builders.rb +4 -0
  16. data/lib/super_diff/rspec/matcher_text_builders/be_predicate.rb +26 -7
  17. data/lib/super_diff/rspec/matcher_text_builders/have_predicate.rb +61 -0
  18. data/lib/super_diff/rspec/matcher_text_builders/raise_error.rb +13 -1
  19. data/lib/super_diff/rspec/monkey_patches.rb +218 -111
  20. data/lib/super_diff/rspec/object_inspection/inspectors.rb +6 -6
  21. data/lib/super_diff/rspec/object_inspection/inspectors/{partial_array.rb → collection_including.rb} +2 -2
  22. data/lib/super_diff/rspec/object_inspection/inspectors/{partial_hash.rb → hash_including.rb} +1 -1
  23. data/lib/super_diff/rspec/object_inspection/inspectors/object_having_attributes.rb +22 -0
  24. data/lib/super_diff/rspec/object_inspection/map_extension.rb +7 -7
  25. data/lib/super_diff/rspec/operational_sequencers.rb +6 -6
  26. data/lib/super_diff/rspec/operational_sequencers/collection_containing_exactly.rb +1 -1
  27. data/lib/super_diff/rspec/operational_sequencers/{partial_array.rb → collection_including.rb} +3 -2
  28. data/lib/super_diff/rspec/operational_sequencers/{partial_hash.rb → hash_including.rb} +3 -2
  29. data/lib/super_diff/rspec/operational_sequencers/{partial_object.rb → object_having_attributes.rb} +2 -4
  30. data/lib/super_diff/version.rb +1 -1
  31. data/spec/integration/rails/active_record_spec.rb +1 -1
  32. data/spec/integration/rails/hash_with_indifferent_access_spec.rb +1 -1
  33. data/spec/integration/rspec/be_predicate_matcher_spec.rb +111 -59
  34. data/spec/integration/rspec/eq_matcher_spec.rb +1 -1
  35. data/spec/integration/rspec/have_predicate_matcher_spec.rb +484 -0
  36. data/spec/integration/rspec/match_array_matcher_spec.rb +372 -0
  37. data/spec/integration/rspec/match_matcher_spec.rb +8 -8
  38. data/spec/integration/rspec/raise_error_matcher_spec.rb +605 -226
  39. data/spec/integration/rspec/third_party_matcher_spec.rb +241 -0
  40. data/spec/integration/rspec/unhandled_errors_spec.rb +56 -81
  41. data/spec/spec_helper.rb +18 -7
  42. data/spec/support/integration/helpers.rb +10 -2
  43. data/spec/support/integration/matchers.rb +143 -0
  44. data/spec/support/models/active_record/query.rb +15 -0
  45. data/spec/support/object_id.rb +26 -0
  46. data/spec/support/ruby_versions.rb +4 -0
  47. data/spec/support/shared_examples/active_record.rb +71 -0
  48. data/spec/unit/equality_matcher_spec.rb +8 -8
  49. data/spec/unit/object_inspection_spec.rb +17 -17
  50. data/spec/unit/rspec/matchers/have_predicate_spec.rb +21 -0
  51. data/spec/unit/rspec/matchers/match_array_spec.rb +11 -0
  52. data/super_diff.gemspec +0 -1
  53. metadata +30 -34
  54. data/lib/super_diff/rspec/object_inspection/inspectors/partial_object.rb +0 -21
  55. data/spec/examples.txt +0 -350
@@ -7,16 +7,16 @@ module SuperDiff
7
7
  "super_diff/rspec/object_inspection/inspectors/collection_containing_exactly",
8
8
  )
9
9
  autoload(
10
- :PartialArray,
11
- "super_diff/rspec/object_inspection/inspectors/partial_array",
10
+ :CollectionIncluding,
11
+ "super_diff/rspec/object_inspection/inspectors/collection_including",
12
12
  )
13
13
  autoload(
14
- :PartialHash,
15
- "super_diff/rspec/object_inspection/inspectors/partial_hash",
14
+ :HashIncluding,
15
+ "super_diff/rspec/object_inspection/inspectors/hash_including",
16
16
  )
17
17
  autoload(
18
- :PartialObject,
19
- "super_diff/rspec/object_inspection/inspectors/partial_object",
18
+ :ObjectHavingAttributes,
19
+ "super_diff/rspec/object_inspection/inspectors/object_having_attributes",
20
20
  )
21
21
  end
22
22
  end
@@ -2,9 +2,9 @@ module SuperDiff
2
2
  module RSpec
3
3
  module ObjectInspection
4
4
  module Inspectors
5
- PartialArray = SuperDiff::ObjectInspection::InspectionTree.new do
5
+ CollectionIncluding = SuperDiff::ObjectInspection::InspectionTree.new do
6
6
  def self.applies_to?(object)
7
- SuperDiff::RSpec.partial_array?(object)
7
+ SuperDiff::RSpec.a_collection_including?(object)
8
8
  end
9
9
 
10
10
  add_text "#<a collection including ("
@@ -2,7 +2,7 @@ module SuperDiff
2
2
  module RSpec
3
3
  module ObjectInspection
4
4
  module Inspectors
5
- PartialHash = SuperDiff::ObjectInspection::InspectionTree.new do
5
+ HashIncluding = SuperDiff::ObjectInspection::InspectionTree.new do
6
6
  add_text "#<a hash including ("
7
7
 
8
8
  nested do |aliased_matcher|
@@ -0,0 +1,22 @@
1
+ module SuperDiff
2
+ module RSpec
3
+ module ObjectInspection
4
+ module Inspectors
5
+ ObjectHavingAttributes =
6
+ SuperDiff::ObjectInspection::InspectionTree.new do
7
+ add_text "#<an object having attributes ("
8
+
9
+ nested do |aliased_matcher|
10
+ insert_hash_inspection_of(
11
+ aliased_matcher.expected,
12
+ initial_break: nil,
13
+ )
14
+ end
15
+
16
+ add_break
17
+ add_text ")>"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -3,13 +3,13 @@ module SuperDiff
3
3
  module ObjectInspection
4
4
  module MapExtension
5
5
  def call(object)
6
- if SuperDiff::RSpec.partial_hash?(object)
7
- Inspectors::PartialHash
8
- elsif SuperDiff::RSpec.partial_array?(object)
9
- Inspectors::PartialArray
10
- elsif SuperDiff::RSpec.partial_object?(object)
11
- Inspectors::PartialObject
12
- elsif SuperDiff::RSpec.collection_containing_exactly?(object)
6
+ if SuperDiff::RSpec.a_hash_including_something?(object)
7
+ Inspectors::HashIncluding
8
+ elsif SuperDiff::RSpec.a_collection_including_something?(object)
9
+ Inspectors::CollectionIncluding
10
+ elsif SuperDiff::RSpec.an_object_having_some_attributes?(object)
11
+ Inspectors::ObjectHavingAttributes
12
+ elsif SuperDiff::RSpec.a_collection_containing_exactly_something?(object)
13
13
  Inspectors::CollectionContainingExactly
14
14
  elsif object.is_a?(::RSpec::Mocks::Double)
15
15
  SuperDiff::ObjectInspection::Inspectors::Primitive
@@ -6,16 +6,16 @@ module SuperDiff
6
6
  "super_diff/rspec/operational_sequencers/collection_containing_exactly",
7
7
  )
8
8
  autoload(
9
- :PartialArray,
10
- "super_diff/rspec/operational_sequencers/partial_array",
9
+ :CollectionIncluding,
10
+ "super_diff/rspec/operational_sequencers/collection_including",
11
11
  )
12
12
  autoload(
13
- :PartialHash,
14
- "super_diff/rspec/operational_sequencers/partial_hash",
13
+ :HashIncluding,
14
+ "super_diff/rspec/operational_sequencers/hash_including",
15
15
  )
16
16
  autoload(
17
- :PartialObject,
18
- "super_diff/rspec/operational_sequencers/partial_object",
17
+ :ObjectHavingAttributes,
18
+ "super_diff/rspec/operational_sequencers/object_having_attributes",
19
19
  )
20
20
  end
21
21
  end
@@ -3,7 +3,7 @@ module SuperDiff
3
3
  module OperationalSequencers
4
4
  class CollectionContainingExactly < SuperDiff::OperationalSequencers::Base
5
5
  def self.applies_to?(expected, actual)
6
- SuperDiff::RSpec.collection_containing_exactly?(expected) &&
6
+ SuperDiff::RSpec.a_collection_containing_exactly_something?(expected) &&
7
7
  actual.is_a?(::Array)
8
8
  end
9
9
 
@@ -1,9 +1,10 @@
1
1
  module SuperDiff
2
2
  module RSpec
3
3
  module OperationalSequencers
4
- class PartialArray < SuperDiff::OperationalSequencers::Array
4
+ class CollectionIncluding < SuperDiff::OperationalSequencers::Array
5
5
  def self.applies_to?(expected, actual)
6
- SuperDiff::RSpec.partial_array?(expected) && actual.is_a?(::Array)
6
+ SuperDiff::RSpec.a_collection_including_something?(expected) &&
7
+ actual.is_a?(::Array)
7
8
  end
8
9
 
9
10
  def initialize(expected:, actual:, **rest)
@@ -1,9 +1,10 @@
1
1
  module SuperDiff
2
2
  module RSpec
3
3
  module OperationalSequencers
4
- class PartialHash < SuperDiff::OperationalSequencers::Hash
4
+ class HashIncluding < SuperDiff::OperationalSequencers::Hash
5
5
  def self.applies_to?(expected, actual)
6
- SuperDiff::RSpec.partial_hash?(expected) && actual.is_a?(::Hash)
6
+ SuperDiff::RSpec.a_hash_including_something?(expected) &&
7
+ actual.is_a?(::Hash)
7
8
  end
8
9
 
9
10
  def initialize(expected:, **rest)
@@ -1,15 +1,14 @@
1
1
  module SuperDiff
2
2
  module RSpec
3
3
  module OperationalSequencers
4
- class PartialObject < SuperDiff::OperationalSequencers::DefaultObject
4
+ class ObjectHavingAttributes < SuperDiff::OperationalSequencers::DefaultObject
5
5
  def self.applies_to?(expected, _actual)
6
- SuperDiff::RSpec.partial_object?(expected)
6
+ SuperDiff::RSpec.an_object_having_some_attributes?(expected)
7
7
  end
8
8
 
9
9
  protected
10
10
 
11
11
  def build_operation_sequencer
12
- # TODO: Test this
13
12
  if actual.respond_to?(:attributes_for_super_diff)
14
13
  OperationSequences::CustomObject.new([], value_class: actual.class)
15
14
  else
@@ -18,7 +17,6 @@ module SuperDiff
18
17
  end
19
18
 
20
19
  def attribute_names
21
- # TODO: Test this
22
20
  if actual.respond_to?(:attributes_for_super_diff)
23
21
  actual.attributes_for_super_diff.keys | expected.expected.keys
24
22
  else
@@ -1,3 +1,3 @@
1
1
  module SuperDiff
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe "Integration with Rails's ActiveRecord class", type: :integration do
3
+ RSpec.describe "Integration with Rails's ActiveRecord class", type: :integration, active_record: true do
4
4
  context "when using 'super_diff/rspec-rails'" do
5
5
  include_context "integration with ActiveRecord"
6
6
 
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe "Integration with Rails's HashWithIndifferentAccess", type: :integration do
3
+ RSpec.describe "Integration with Rails's HashWithIndifferentAccess", type: :integration, active_record: true do
4
4
  context "when using 'super_diff/rspec-rails'" do
5
5
  include_context "integration with HashWithIndifferentAccess"
6
6
 
@@ -1,6 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
- RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
3
+ RSpec.describe "Integration with RSpec's #be_<predicate> matcher", type: :integration do
4
4
  # rubocop:disable Metrics/BlockLength
5
5
  ["be", "be_a", "be_an"].each do |prefix|
6
6
  # rubocop:enable Metrics/BlockLength
@@ -23,9 +23,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
23
23
  plain "Expected "
24
24
  beta %|:foo|
25
25
  plain " to respond to "
26
- alpha %|`strong?`|
26
+ alpha %|strong?|
27
27
  plain " or "
28
- alpha %|`strongs?`|
28
+ alpha %|strongs?|
29
29
  plain "."
30
30
  end
31
31
  },
@@ -42,7 +42,7 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
42
42
  it "produces the correct failure message" do
43
43
  as_both_colored_and_uncolored do |color_enabled|
44
44
  snippet = <<~TEST.strip
45
- hash = { foo: "bar", baz: "qux", blargh: "foz", fizz: "buzz" }
45
+ hash = { foo: "bar", baz: "qux", blargh: "foz", fizz: "buzz", aaaaaa: "bbbbbb" }
46
46
  expect(hash).to #{prefix}_strong
47
47
  TEST
48
48
  program = make_plain_test_program(
@@ -57,14 +57,14 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
57
57
  expectation: proc {
58
58
  line do
59
59
  plain " Expected "
60
- beta %|{ foo: "bar", baz: "qux", blargh: "foz", fizz: "buzz" }|
60
+ beta %|{ foo: "bar", baz: "qux", blargh: "foz", fizz: "buzz", aaaaaa: "bbbbbb" }|
61
61
  end
62
62
 
63
63
  line do
64
64
  plain "to respond to "
65
- alpha %|`strong?`|
65
+ alpha %|strong?|
66
66
  plain " or "
67
- alpha %|`strongs?`|
67
+ alpha %|strongs?|
68
68
  end
69
69
  },
70
70
  )
@@ -102,9 +102,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
102
102
  plain "Expected "
103
103
  beta %|#<Foo>|
104
104
  plain " to have a public method "
105
- alpha %|`strong?`|
105
+ alpha %|strong?|
106
106
  plain " or "
107
- alpha %|`strongs?`|
107
+ alpha %|strongs?|
108
108
  plain "."
109
109
  end
110
110
  },
@@ -147,9 +147,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
147
147
 
148
148
  line do
149
149
  plain "to have a public method "
150
- alpha %|`strong?`|
150
+ alpha %|strong?|
151
151
  plain " or "
152
- alpha %|`strongs?`|
152
+ alpha %|strongs?|
153
153
  end
154
154
  },
155
155
  )
@@ -190,9 +190,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
190
190
  plain "Expected "
191
191
  beta %|#<Foo>|
192
192
  plain " to return a truthy result for "
193
- alpha %|`true?`|
193
+ alpha %|true?|
194
194
  plain " or "
195
- alpha %|`trues?`|
195
+ alpha %|trues?|
196
196
  plain "."
197
197
  end
198
198
 
@@ -200,9 +200,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
200
200
 
201
201
  line do
202
202
  plain "(Perhaps you want to use "
203
- blue "`be(true)`"
203
+ blue "be(true)"
204
204
  plain " or "
205
- blue "`be_truthy`"
205
+ blue "be_truthy"
206
206
  plain " instead?)"
207
207
  end
208
208
  },
@@ -250,18 +250,18 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
250
250
 
251
251
  line do
252
252
  plain "to return a truthy result for "
253
- alpha %|`true?`|
253
+ alpha %|true?|
254
254
  plain " or "
255
- alpha %|`trues?`|
255
+ alpha %|trues?|
256
256
  end
257
257
 
258
258
  newline
259
259
 
260
260
  line do
261
261
  plain "(Perhaps you want to use "
262
- blue "`be(true)`"
262
+ blue "be(true)"
263
263
  plain " or "
264
- blue "`be_truthy`"
264
+ blue "be_truthy"
265
265
  plain " instead?)"
266
266
  end
267
267
  },
@@ -300,9 +300,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
300
300
  plain "Expected "
301
301
  beta %|#<X>|
302
302
  plain " to return a truthy result for "
303
- alpha %|`false?`|
303
+ alpha %|false?|
304
304
  plain " or "
305
- alpha %|`falses?`|
305
+ alpha %|falses?|
306
306
  plain "."
307
307
  end
308
308
  },
@@ -341,9 +341,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
341
341
  plain "Expected "
342
342
  beta %|#<X>|
343
343
  plain " to return a truthy result for "
344
- alpha %|`y?`|
344
+ alpha %|y?|
345
345
  plain " or "
346
- alpha %|`ys?`|
346
+ alpha %|ys?|
347
347
  plain "."
348
348
  end
349
349
  },
@@ -392,9 +392,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
392
392
 
393
393
  line do
394
394
  plain "to return a truthy result for "
395
- alpha %|`y?`|
395
+ alpha %|y?|
396
396
  plain " or "
397
- alpha %|`ys?`|
397
+ alpha %|ys?|
398
398
  end
399
399
  },
400
400
  )
@@ -432,9 +432,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
432
432
  plain "Expected "
433
433
  beta %|#<X>|
434
434
  plain " to return a truthy result for "
435
- alpha %|`y?`|
435
+ alpha %|y?|
436
436
  plain " or "
437
- alpha %|`ys?`|
437
+ alpha %|ys?|
438
438
  plain "."
439
439
  end
440
440
  },
@@ -483,9 +483,9 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
483
483
 
484
484
  line do
485
485
  plain "to return a truthy result for "
486
- alpha %|`y?`|
486
+ alpha %|y?|
487
487
  plain " or "
488
- alpha %|`ys?`|
488
+ alpha %|ys?|
489
489
  end
490
490
  },
491
491
  )
@@ -502,40 +502,92 @@ RSpec.describe "Integration with RSpec's #be_* matcher", type: :integration do
502
502
  end
503
503
 
504
504
  context "and returns true" do
505
- it "produces the correct failure message when used in the negative" do
506
- as_both_colored_and_uncolored do |color_enabled|
507
- snippet = <<~TEST.strip
508
- class Foo
509
- def strong?; true; end
510
- end
505
+ context "when the inspected version of the actual value is short" do
506
+ it "produces the correct failure message when used in the negative" do
507
+ as_both_colored_and_uncolored do |color_enabled|
508
+ snippet = <<~TEST.strip
509
+ class Foo
510
+ def strong?; true; end
511
+ end
511
512
 
512
- expect(Foo.new).not_to #{prefix}_strong
513
- TEST
514
- program = make_plain_test_program(
515
- snippet,
516
- color_enabled: color_enabled,
517
- )
513
+ expect(Foo.new).not_to #{prefix}_strong
514
+ TEST
515
+ program = make_plain_test_program(
516
+ snippet,
517
+ color_enabled: color_enabled,
518
+ )
518
519
 
519
- expected_output = build_expected_output(
520
- color_enabled: color_enabled,
521
- snippet: %|expect(Foo.new).not_to #{prefix}_strong|,
522
- expectation: proc {
523
- line do
524
- plain "Expected "
525
- beta %|#<Foo>|
526
- plain " not to return a truthy result for "
527
- alpha %|`strong?`|
528
- plain " or "
529
- alpha %|`strongs?`|
530
- plain "."
520
+ expected_output = build_expected_output(
521
+ color_enabled: color_enabled,
522
+ snippet: %|expect(Foo.new).not_to #{prefix}_strong|,
523
+ expectation: proc {
524
+ line do
525
+ plain "Expected "
526
+ beta %|#<Foo>|
527
+ plain " not to return a truthy result for "
528
+ alpha %|strong?|
529
+ plain " or "
530
+ alpha %|strongs?|
531
+ plain "."
532
+ end
533
+ },
534
+ )
535
+
536
+ expect(program).
537
+ to produce_output_when_run(expected_output).
538
+ in_color(color_enabled).
539
+ removing_object_ids
540
+ end
541
+ end
542
+ end
543
+
544
+ context "when the inspected version of the actual value is long" do
545
+ it "produces the correct failure message when used in the negative" do
546
+ as_both_colored_and_uncolored do |color_enabled|
547
+ snippet = <<~TEST.strip
548
+ hash = {
549
+ foo: "bar",
550
+ baz: "qux",
551
+ blargh: "foz",
552
+ fizz: "buzz",
553
+ aaaaaa: "bbbbbb"
554
+ }
555
+
556
+ class << hash
557
+ def ys?; true; end
531
558
  end
532
- },
533
- )
534
559
 
535
- expect(program).
536
- to produce_output_when_run(expected_output).
537
- in_color(color_enabled).
538
- removing_object_ids
560
+ expect(hash).not_to #{prefix}_y
561
+ TEST
562
+ program = make_plain_test_program(
563
+ snippet,
564
+ color_enabled: color_enabled,
565
+ )
566
+
567
+ expected_output = build_expected_output(
568
+ color_enabled: color_enabled,
569
+ snippet: %|expect(hash).not_to #{prefix}_y|,
570
+ newline_before_expectation: true,
571
+ expectation: proc {
572
+ line do
573
+ plain " Expected "
574
+ beta %|{ foo: "bar", baz: "qux", blargh: "foz", fizz: "buzz", aaaaaa: "bbbbbb" }|
575
+ end
576
+
577
+ line do
578
+ plain "not to return a truthy result for "
579
+ alpha %|y?|
580
+ plain " or "
581
+ alpha %|ys?|
582
+ end
583
+ },
584
+ )
585
+
586
+ expect(program).
587
+ to produce_output_when_run(expected_output).
588
+ in_color(color_enabled).
589
+ removing_object_ids
590
+ end
539
591
  end
540
592
  end
541
593
  end