Rspec: array.should == another_array but without concern for order
Use match_array
, which takes another array as an argument, or contain_exactly
, which takes each element as a separate argument, and is sometimes useful for readability. (docs)
Examples:
expect([1, 2, 3]).to match_array [3, 2, 1]
or
expect([1, 2, 3]).to contain_exactly 3, 2, 1
Rspec - Check if an array have same elements than other, regardless of the order
Here was my wrong matcher (thanks @steenslag):
RSpec::Matchers.define :be_same_array_as do |expected_array|
match do |actual_array|
(actual_array | expected_array) - (actual_array & expected_array) == []
end
end
Other solutions:
use the builtin matcher, best solution
use
Set
:
Something like:
require 'set'
RSpec::Matchers.define :be_same_array_as do |expected_array|
match do |actual_array|
Set.new(actual_array) == Set.new(expected_array)
end
end
RSpec expect to receive method with array but order does not matter
You can pass any RSpec matcher to with
, and contain_exactly(1, 2, 3)
does exactly what you want, so you can pass that to with:
expect(calculation_service).to receive(:sum?).with(contain_exactly(1, 2, 3)) { 6 }
However, "with contain exactly 1, 2, 3" doesn't read very well (and the failure message will be similarly grammatically awkward), so RSpec 3 provides aliases that solve both problems. In this case, you can use a_collection_containing_exactly
:
expect(calculation_service).to receive(:sum?).with(
a_collection_containing_exactly(1, 2, 3)
) { 6 }
Stubbing array responses with rspec
How about creating a class which handles the needed interface:
class DBStub
def initialize(data_store)
@data_store = data_store
end
def [](arg1, arg2)
@data_store[arg1][arg2]
end
end
ws = DBStub.new(temp)
Check if two arrays have the same contents (in any order)
This doesn't require conversion to set:
a.sort == b.sort
Need to sort array based on another array of array
I assume you want to sort the elements in a
according to their position in b
and that the elements in b
are the strings 'A'
, 'B'
, etc and not constants.
Then I would do something like this:
a = [["A", 1075000], ["C", 1750000], ["D", 0], ["E", 0], ["B", 0]]
b = ['A','B','C','D','E']
a.sort { |x, y| b.index(x.first) <=> b.index(y.first) }
#=> [["A", 1075000], ["B", 0], ["C", 1750000], ["D", 0], ["E", 0]]
Depending on the size of b
it might make sense to use sort_by
instead of sort
. sort_by
catches the return value of the block and does not evaluate the block multiple times:
a.sort_by { |x| b.index(x) }
How do I replace repetitive elements in an array matching another array?
array_main.map { |e| array_second.include?( e ) ? 0 : e }
And if you drop that requirement about replacing with 0, you can simply write
array_main - array_second
How to match hashes that contain arrays ignoring order of array elements?
I'd write a custom matcher:
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
Are the elements of an array within the range of another array
array_a = [50,13,25,35,45]
array_b = [14,45]
array_a.max >= array_b.max && array_a.min <= array_b.min
# => true
Edit: Babai's solution is slightly faster and more elegant, I think.
Edit: So most efficient solution is:
array_a = [50,13,25,35,45]
array_b = [14,45]
min,max = array_a.minmax
array_b.all? {|num| num<=max && num>=min }
# => true
Related Topics
Setting Path for Whenever in Cron So It Can Find Ruby
Generating an Instagram- or Youtube-Like Unguessable String Id in Ruby/Activerecord
How to Format This International Phone Number in Rails
How to Create a Nokogiri Case Insensitive Xpath Selector
How to Read a File from Bottom to Top in Ruby
Xpath Expression for Regex-Like Matching
Why Doesn't "Rails S" Work from the App Directory
Rails Carrierwave Base64 Image Upload
Rails - Local Variables Versus Instance Variables
Force Browser to Download File Instead of Opening It
Which Ruby Version am I Really Running
How to Convert a Ruby Object to JSON
How to Implement Cookie Support in Ruby Net/Http