RSpec の contain_exactly マッチャ と match_array マッチャ
contain_exactly マッチャ
`contain_exactly` matcher - Built in matchers - RSpec Expectations - RSpec - Relish
以下のようにコレクションに対して、順序は問わないがすべてが含まれているかをチェックすることができる。
expect([1, 2, 3]).to contain_exactly(2, 3, 1) # pass expect([:a, :c, :b]).to contain_exactly(:a, :c) # fail
match_array マッチャ
ほぼ同じようなマッチャとして match_array というのもある。 これは引数に配列を取るので注意する。
expect([1, 2, 3]).to match_array [2, 3, 1] # pass expect([:a, :c, :b]).to match_array [:a, :c] # fail
ソースコードを読む
これらのマッチャの動作を理解するために、まずは contain_exactly
のソースコードを読んでみた。
def match(_expected, _actual) return false unless convert_actual_to_an_array match_when_sorted? || (extra_items.empty? && missing_items.empty?) end def match_when_sorted? values_match?(safe_sort(expected), safe_sort(actual)) end
引数を配列に変換して、ソートしたあとで、それぞれマッチするかをチェックしている。
一方 match_array
は以下のような感じ。
def match_array(items) contain_exactly(*items) end
contain_exactly
呼んでた。
ということで contain_exactly
と match_array
は引数に配列を取るかどうか以外は同じ挙動をすることがわかった。
まとめ
RSpec は奥が深い。