File: send.feature

package info (click to toggle)
ruby-contracts 0.17-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 624 kB
  • sloc: ruby: 3,805; makefile: 4; sh: 2
file content (147 lines) | stat: -rw-r--r-- 3,187 bytes parent folder | download | duplicates (4)
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
    """