我在RSpec中有一个自定义匹配器,忽略空格/换行符,只匹配内容:
RSpec::Matchers.define :be_matching_content do |expected|
match do |actual|
actual.gsub(/\s/,'').should == expected.gsub(/\s/,'')
end
diffable
end
我可以这样使用它:
body = " some data \n more data"
body.should be_matching_content("some data\nmore wrong data")
但是,当测试失败时(如上所述),diff输出看起来不太好:
-some data
-more wrong data
+ some data
+ more data
是否可以配置diffable输出?第一行some data
是正确的,但第二行more wrong data
是错误的。仅将第二行作为失败的根本原因是非常有用的。
答案 0 :(得分:11)
我相信您应该在RSpec中禁用默认diffable
行为并替换您自己的实现:
RSpec::Matchers.define :be_matching_content do |expected|
match do |actual|
@stripped_actual = actual.gsub(/\s/,'')
@stripped_expected = expected.gsub(/\s/,'')
expect(@stripped_actual).to eq @stripped_expected
end
failure_message do |actual|
message = "expected that #{@stripped_actual} would match #{@stripped_expected}"
message += "\nDiff:" + differ.diff_as_string(@stripped_actual, @stripped_expected)
message
end
def differ
RSpec::Support::Differ.new(
:object_preparer => lambda { |object| RSpec::Matchers::Composable.surface_descriptions_in(object) },
:color => RSpec::Matchers.configuration.color?
)
end
end
RSpec.describe 'something'do
it 'should diff correctly' do
body = " some data \n more data"
expect(body).to be_matching_content("some data\nmore wrong data")
end
end
产生以下内容:
Failures:
1) something should diff correctly
Failure/Error: expect(body).to be_matching_content("some data\nmore wrong data")
expected that somedatamoredata would match somedatamorewrongdata
Diff:
@@ -1,2 +1,2 @@
-somedatamorewrongdata
+somedatamoredata
如果需要,可以使用自定义不同,甚至可以将整个匹配器重新实现为对diff
命令的系统调用,如下所示:
♥ diff -uw --label expected --label actual <(echo " some data \n more data") <(echo "some data\nmore wrong data")
--- expected
+++ actual
@@ -1,2 +1,2 @@
some data
- more data
+more wrong data
干杯!
答案 1 :(得分:4)
您可以覆盖生成差异时将使用的expected
和actual
方法。在此示例中,我们将期望值和实际值存储为实例变量,并定义返回实例变量的方法:
RSpec::Matchers.define :be_matching_content do |expected_raw|
match do |actual_raw|
@actual = actual_raw.gsub(/\s/,'')
@expected = expected_raw.gsub(/\s/,'')
expect(expected).to eq(@actual)
end
diffable
attr_reader :actual, :expected
end
另一个例子是匹配两种不同类型对象中的特定属性。 (在这种情况下,预期对象是Client
模型。)
RSpec::Matchers.define :have_attributes_of_v1_client do |expected_client|
match do |actual_object|
@expected = client_attributes(expected_client)
@actual = actual_object.attributes
expect(actual_object).to have_attributes(@expected)
end
diffable
attr_reader :actual, :expected
def failure_message
"expected attributes of a V1 Client view row, but they do not match"
end
def client_attributes(client)
{
"id" => client.id,
"client_type" => client.client_type.name,
"username" => client.username,
"active" => client.active?,
}
end
end
示例失败如下所示:
Failure/Error: is_expected.to have_attributes_of_v1_client(client_active_partner)
expected attributes of a V1 Client view row, but they do not match
Diff:
@@ -1,6 +1,6 @@
"active" => true,
-"client_type" => #<ClientType id: 2, name: "ContentPartner">,
+"client_type" => "ContentPartner",
"id" => 11,
答案 2 :(得分:1)
可以使用名为diffy的宝石。
但是它逐行遍历一个字符串并比较它们,所以不是删除所有空格,而是用换行符替换任意数量的空格并区分这些条目。
这是你可以做一些改善你的差异的例子。我并不是100%确定将其插入代码的位置。
def compare(str1, str2)
str1 = break_string(str1)
str2 = break_string(str2)
return true if str1 == str2
puts Diffy::Diff.new(str1, str2).to_s
return false
end
def break_string(str)
str.gsub(/\s+/,"\n")
end
可以设置diffy gem以产生适合终端的颜色输出。
使用此代码可以像这样工作
str1 = 'extra some content'
str2 = 'extra more content'
puts compare(str1, str2)
这会打印
extra
-some # red in terminal
+more # green in terminal
content
\ No newline at end of file