1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
Feature: Send
Takes a variable number of method names as symbols. Given an argument, all of
those methods are called on the argument one by one. If they all return true,
the contract passes.
```ruby
Contract C::Send[:valid?, :has_items?] => C::ArrayOf[Item]
```
This contract will pass only if:
`arg.valid? == true && arg.has_items? == true`,
where `arg` is the first argument.
Background:
Given a file named "item.rb" with:
"""ruby
Item = Struct.new(:name, :cost)
Item::DEFAULT = Item["default", 0]
"""
Given a file named "send_usage.rb" with:
"""ruby
require "contracts"
C = Contracts
require "./item"
class FetchItemCommand
include Contracts::Core
Contract C::Send[:valid?, :has_items?] => C::ArrayOf[Item]
def call(subject)
([Item::DEFAULT] + subject.items).uniq
end
end
"""
Scenario: All methods return `true`
Given a file named "box.rb" with:
"""ruby
class Box
def valid?
true
end
def has_items?
true
end
def items
[Item["cat", 599.99]]
end
end
require "./send_usage"
p FetchItemCommand.new.call(Box.new)
"""
When I run `ruby box.rb`
Then output should contain:
"""
[#<struct Item name="default", cost=0>, #<struct Item name="cat", cost=599.99>]
"""
Scenario: When second method returns `false`
Given a file named "cat.rb" with:
"""ruby
class Cat
def valid?
true
end
def has_items?
false
end
end
require "./send_usage"
p FetchItemCommand.new.call(Cat.new)
"""
When I run `ruby cat.rb`
Then output should contain:
"""
: Contract violation for argument 1 of 1: (ParamContractError)
Expected: (a value that returns true for all of [:valid?, :has_items?]),
"""
And output should contain:
"""
Actual: #<Cat
"""
Scenario: When first method returns `false`
Given a file named "invalid.rb" with:
"""ruby
class Invalid
def valid?
false
end
def has_items?
true
end
def items
[]
end
end
require "./send_usage"
p FetchItemCommand.new.call(Invalid.new)
"""
When I run `ruby invalid.rb`
Then output should contain:
"""
: Contract violation for argument 1 of 1: (ParamContractError)
Expected: (a value that returns true for all of [:valid?, :has_items?]),
"""
And output should contain:
"""
Actual: #<Invalid
"""
Scenario: When all methods return `false`
Given a file named "nothing.rb" with:
"""ruby
class Nothing
def valid?
false
end
def has_items?
false
end
end
require "./send_usage"
p FetchItemCommand.new.call(Nothing.new)
"""
When I run `ruby nothing.rb`
Then output should contain:
"""
: Contract violation for argument 1 of 1: (ParamContractError)
Expected: (a value that returns true for all of [:valid?, :has_items?]),
"""
And output should contain:
"""
Actual: #<Nothing
"""
|