2015-09-09 10 views
5

私は空白/改行を無視しRSpecのでカスタム照合を、持っている、とだけ内容と一致した次の場合、しかしRSpecのカスタムdiffableマッチャー

body = " some data \n more data" 
    body.should be_matching_content("some data\nmore wrong data") 

RSpec::Matchers.define :be_matching_content do |expected| 
    match do |actual| 
    actual.gsub(/\s/,'').should == expected.gsub(/\s/,'') 
    end 

    diffable 
end 

私はこのようにそれを使用することができますテストは失敗します(上記のように)、diff出力は良くないように見えます:

-some data 
    -more wrong data 
    + some data 
    + more data 

diffable出力を設定することは可能ですか?最初の行some dataは正しいですが、2番目のmore wrong dataは間違っています。 2番目の行を失敗の根本的な原因として取得することは非常に便利です。

答えて

8

を印刷します:

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 

は次のようになります。

あなたも diffコマンドにシステムコールにこの全体のマッチャーを再実装、あなたがしたい場合に異なるカスタム使用することができます
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 -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

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) 

のように働くだろう

これは、私はあなたがRSpecの中でデフォルトdiffable動作を無効にし、独自の実装に置き換える必要があると考えてい

extra 
-some # red in terminal 
+more # green in terminal 
content 
\ No newline at end of file 
4

diffを生成するときに使用される方法expectedactualを無効にすることができます。この例では、インスタンス変数として期待値と実際の値を格納し、インスタンス変数を返すメソッドを定義:

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, 
+1

注これは、唯一のバージョン3.4から始まるRSpecのドキュメントに記載されています。また、ドキュメントによれば、インスタンス変数名として '@ actual'を使用する場合、' attr_reader'は必要ありません。 –

関連する問題