/ / Vlastný porovnávač RSpec, ktorý zaberá blok - rubín, rspec

Vlastné RSpec Matcher, ktorý berie blok - ruby, rspec

Ako je možné vytvoriť nasledujúce porovnávač RSpec?

foo.bars.should incude_at_least_one {|bar| bar.id == 42 }

Dajte mi vedieť, či vymýšľam koleso, ale tiež som zvedavý, ako vytvoriť vlastný porovnávač, ktorý zaberie blok. Niektorí z vstavaných zápasníkov to robia, takže je to možné.

RSpec::Matchers.define :incude_at_least_one do |expected|
match do |actual|
actual.each do |item|
return true if yield(item)
end
false
end
end

Tiež som sa snažil prejsť &block na oboch úrovniach. Chýba mi niečo jednoduchého.

odpovede:

1 pre odpoveď č. 1

Začal som s kódom od Neila Slatera a nechal som to fungovať:

class IncludeAtLeastOne
def initialize(&block)
@block = block
end

def matches?(actual)
@actual = actual
@actual.any? {|item| @block.call(item) }
end

def failure_message_for_should
"expected #{@actual.inspect} to include at least one matching item, but it did not"
end

def failure_message_for_should_not
"expected #{@actual.inspect} not to include at least one, but it did"
end
end

def include_at_least_one(&block)
IncludeAtLeastOne.new &block
end

0 pre odpoveď č. 2

Diskutovalo sa o pridaní takéhoto porovnávača do rspec. Nie som si istá vašou blokovou otázkou, ale tento test by ste mohli predstaviť v nie tak elegantnom vzhľade:

foo.bars.any?{|bar| bar.id == 42}.should be_true

Pravdepodobne jednoduchšie ako vytvorenie vlastného porovnávača a mali by byť čitateľné, ak je váš test niečo podobné it "should include at least one foo matching the id"


0 pre odpoveď č. 3

RSpec DSL to neurobí, ale môžete urobiť niečo také:

class IncludeAtLeastOne
def matches?(target)
@target = target
@target.any? do |item|
yield( item )
end
end

def failure_message_for_should
"expected #{@target.inspect} to include at least one thing"
end

def failure_message_for_should_not
"expected #{@target.inspect} not to include at least one"
end
end

def include_at_least_one
IncludeAtLeastOne.new
end

describe "foos" do
it "should contain something interesting" do
[1,2,3].should include_at_least_one { |x| x == 1 }
end
end