ruby - 如何匹配包含忽略数组元素顺序的数组的哈希?

标签 ruby rspec2

我有两个包含数组的散列。就我而言,数组元素的顺序并不重要。有没有一种简单的方法可以在 RSpec2 中匹配这样的哈希值?

{ a: [1, 2] }.should == { a: [2, 1] } # how to make it pass?

附言

有一个数组匹配器,忽略顺序。

[1, 2].should =~ [2, 1] # Is there a similar matcher for hashes?

解决方案

该解决方案适合我。最初由 tokland 建议,已修复。

RSpec::Matchers.define :match_hash do |expected|
  match do |actual|
    matches_hash?(expected, actual) 
  end
end

def matches_hash?(expected, actual) 
  matches_array?(expected.keys, actual.keys) &&
    actual.all? { |k, xs| matches_array?(expected[k], xs) }
end   

def matches_array?(expected, actual)
  return expected == actual unless expected.is_a?(Array) && actual.is_a?(Array)
  RSpec::Matchers::BuiltIn::MatchArray.new(expected).matches? actual
end

使用匹配器:

{a: [1, 2]}.should match_hash({a: [2, 1]})

最佳答案

我会写一个自定义匹配器:

RSpec::Matchers.define :have_equal_sets_as_values do |expected|
  match do |actual|
    same_elements?(actual.keys, expected.keys) && 
      actual.all? { |k, xs| same_elements?(xs, expected[k]) }
  end

  def same_elements?(xs, ys)
    RSpec::Matchers::BuiltIn::MatchArray.new(xs).matches?(ys)
  end
end

describe "some test" do
  it { {a: [1, 2]}.should have_equal_sets_as_values({a: [2, 1]}) }  
end

# 1 example, 0 failures

关于ruby - 如何匹配包含忽略数组元素顺序的数组的哈希?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11366441/

相关文章:

ruby-on-rails - RSpec 测试未通过 : Expected response to be a <3XX: redirect>,,但为 <200:OK>

ruby - 修改 cucumber 步骤定义以提供更有用的输出

ruby-on-rails - 使用 get 和 delete 运行 Rspec 测试时获取错误数量的参数(2 个为 0)

ruby - 在 RSpec 2 中使用 OR 的相等性

ruby-on-rails-3 - 如何设置 RSpec 时区?

Ruby:扩展/包含模块的模块

Ruby/Rails 方法在 x 个字符或单词后插入字符串中的内容

ruby-on-rails - Rspec stub 操作变量

html - 从数组中选择表单

ruby-on-rails - Stripe API key 缺少 Rails