Skip to content

Commit 7eb25ec

Browse files
committed
Support be_* matcher (and its variants)
1 parent 96d2ba3 commit 7eb25ec

File tree

12 files changed

+1311
-59
lines changed

12 files changed

+1311
-59
lines changed

lib/super_diff/rspec/augmented_matcher.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module AugmentedMatcher
44
# Update to use expected_for_description instead of @expected
55
# TODO: Test
66
def description
7-
failure_message_builder.matcher_description
7+
failure_message_template_builder.matcher_description
88
end
99

1010
# Colorize the 'actual' value
@@ -42,7 +42,7 @@ def failure_message_template_builder
4242
failure_message_template_builder_class.new(
4343
actual: actual_for_failure_message,
4444
expected: expected_for_failure_message,
45-
description_as_phrase: description_as_phrase,
45+
expected_action: expected_action,
4646
)
4747
end
4848

@@ -52,7 +52,7 @@ def failure_message_template_builder_class
5252

5353
private
5454

55-
def description_as_phrase
55+
def expected_action
5656
::RSpec::Matchers::EnglishPhrasing.split_words(self.class.matcher_name)
5757
end
5858

lib/super_diff/rspec/failure_message_builders.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ module SuperDiff
22
module RSpec
33
module FailureMessageBuilders
44
autoload :Base, "super_diff/rspec/failure_message_builders/base"
5+
autoload(
6+
:BePredicate,
7+
"super_diff/rspec/failure_message_builders/be_predicate",
8+
)
59
autoload(
610
:ContainExactly,
711
"super_diff/rspec/failure_message_builders/contain_exactly",

lib/super_diff/rspec/failure_message_builders/base.rb

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ module SuperDiff
22
module RSpec
33
module FailureMessageBuilders
44
class Base
5-
def initialize(actual:, expected:, description_as_phrase:)
5+
def initialize(actual:, expected:, expected_action:)
66
@actual = actual
77
@expected = expected
8-
@description_as_phrase = description_as_phrase
8+
@expected_action = expected_action
99

10+
@negated = nil
1011
@template = FailureMessageTemplate.new
1112
end
1213

@@ -18,12 +19,20 @@ def call(negated:)
1819
end
1920

2021
def matcher_description
21-
Csi.decolorize(expected_section.to_s(as_single_line: true))
22+
template = FailureMessageTemplate.new do |t|
23+
t.add_text expected_action
24+
add_expected_value_to(t)
25+
end
26+
27+
Csi.decolorize(template.to_s(as_single_line: true))
2228
end
2329

2430
protected
2531

26-
def add_extra
32+
def add_extra_after_expected
33+
end
34+
35+
def add_extra_after_error
2736
end
2837

2938
def actual_color
@@ -36,7 +45,7 @@ def expected_color
3645

3746
private
3847

39-
attr_reader :expected, :actual, :description_as_phrase, :template
48+
attr_reader :expected, :actual, :expected_action, :template
4049

4150
def negated?
4251
@negated
@@ -46,8 +55,9 @@ def fill_template
4655
add_actual_section
4756
template.add_break
4857
template.insert expected_section
49-
add_extra
58+
add_extra_after_expected
5059
template.add_text_in_singleline_mode "."
60+
add_extra_after_error
5161
end
5262

5363
def add_actual_section
@@ -71,23 +81,19 @@ def expected_section
7181
FailureMessageTemplate.new do |t|
7282
t.add_text_in_singleline_mode expected_phrase
7383
t.add_text_in_multiline_mode do
74-
if phrase_width
75-
expected_phrase.to_s.rjust(phrase_width)
76-
else
77-
expected_phrase
78-
end
84+
expected_phrase.to_s.rjust(phrase_width)
7985
end
80-
t.add_text " "
8186
add_expected_value_to(t)
8287
end
8388
end
8489

85-
def expected_phrase
86-
"#{to_or_not_to} #{description_as_phrase}"
90+
def add_expected_value_to(template)
91+
template.add_text " "
92+
template.add_text_in_color(expected_color, expected)
8793
end
8894

89-
def add_expected_value_to(template)
90-
template.add_text_in_color(expected_color) { expected }
95+
def expected_phrase
96+
"#{to_or_not_to} #{expected_action}"
9197
end
9298

9399
def to_or_not_to
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
module SuperDiff
2+
module RSpec
3+
module FailureMessageBuilders
4+
class BePredicate < Base
5+
def initialize(
6+
predicate_accessible:,
7+
private_predicate:,
8+
expected_predicate_method_name:,
9+
**rest
10+
)
11+
super(**rest)
12+
@predicate_accessible = predicate_accessible
13+
@private_predicate = private_predicate
14+
@expected_predicate_method_name = expected_predicate_method_name
15+
end
16+
17+
def matcher_description
18+
template = FailureMessageTemplate.new do |t|
19+
t.add_text "return true for"
20+
add_expected_value_to(t)
21+
end
22+
23+
Csi.decolorize(template.to_s(as_single_line: true))
24+
end
25+
26+
protected
27+
28+
def expected_action
29+
if predicate_accessible?
30+
"return true for"
31+
elsif private_predicate?
32+
"have a public method"
33+
else
34+
"respond to"
35+
end
36+
end
37+
38+
def actual_color
39+
:yellow
40+
end
41+
42+
def add_actual_value
43+
template.add_text_in_color(actual_color) do
44+
description_of(actual)
45+
end
46+
end
47+
48+
def expected_color
49+
:magenta
50+
end
51+
52+
def add_expected_value_to(template)
53+
template.add_text " "
54+
template.add_text_in_color(expected_color, "`#{expected}?`")
55+
template.add_text " or "
56+
template.add_text_in_color(expected_color, "`#{expected}s?`")
57+
end
58+
59+
def add_extra_after_error
60+
if expected_predicate_method_name == :true?
61+
template.add_text "\n\n"
62+
template.add_text "(Perhaps you want to use "
63+
template.add_text_in_color(:blue, "`be(true)`")
64+
template.add_text " or "
65+
template.add_text_in_color(:blue, "`be_truthy`")
66+
template.add_text " instead?)"
67+
elsif expected_predicate_method_name == :false?
68+
template.add_text "\n\n"
69+
template.add_text "(Perhaps you want to use "
70+
template.add_text_in_color(:blue, "`be(false)`")
71+
template.add_text " or "
72+
template.add_text_in_color(:blue, "`be_falsey`")
73+
template.add_text " instead?)"
74+
end
75+
end
76+
77+
private
78+
79+
attr_reader :expected_predicate_method_name
80+
81+
def predicate_accessible?
82+
@predicate_accessible
83+
end
84+
85+
def private_predicate?
86+
@private_predicate
87+
end
88+
end
89+
end
90+
end
91+
end

lib/super_diff/rspec/failure_message_builders/contain_exactly.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class ContainExactly < Base
55
protected
66

77
def add_expected_value_to(template)
8+
template.add_text " "
89
template.add_list_in_color(expected_color, expected)
910
end
1011
end

lib/super_diff/rspec/failure_message_builders/respond_to.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ def initialize(
1919
protected
2020

2121
def add_expected_value_to(template)
22+
template.add_text " "
2223
template.add_list_in_color(expected_color, expected)
2324
end
2425

25-
def add_extra
26+
def add_extra_after_expected
2627
if expected_arity
2728
add_arity_clause
2829
end

lib/super_diff/rspec/failure_message_template.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,17 @@ def insert(*args, &block)
4343
add_token(Insertion, *args, &block)
4444
end
4545

46-
def length
47-
tokens.sum(&:length)
46+
def length_of_first_paragraph
47+
Csi.decolorize(to_string_in_singleline_mode).
48+
split(/\n\n/).
49+
first.
50+
length
4851
end
4952

5053
def to_s(as_single_line: nil)
51-
if length > MAX_LINE_LENGTH || as_single_line == false
54+
if length_of_first_paragraph > MAX_LINE_LENGTH || as_single_line == false
5255
to_string_in_multiline_mode
53-
elsif length <= MAX_LINE_LENGTH || as_single_line == true
56+
elsif length_of_first_paragraph <= MAX_LINE_LENGTH || as_single_line == true
5457
to_string_in_singleline_mode
5558
end
5659
end

0 commit comments

Comments
 (0)