entitlements 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/bin/deploy-entitlements +10 -1
  4. data/lib/contracts-ruby2/CHANGELOG.markdown +115 -0
  5. data/lib/contracts-ruby2/Gemfile +17 -0
  6. data/lib/contracts-ruby2/LICENSE +23 -0
  7. data/lib/contracts-ruby2/README.md +108 -0
  8. data/lib/contracts-ruby2/Rakefile +8 -0
  9. data/lib/contracts-ruby2/TODO.markdown +6 -0
  10. data/lib/contracts-ruby2/TUTORIAL.md +773 -0
  11. data/lib/contracts-ruby2/benchmarks/bench.rb +67 -0
  12. data/lib/contracts-ruby2/benchmarks/hash.rb +69 -0
  13. data/lib/contracts-ruby2/benchmarks/invariants.rb +91 -0
  14. data/lib/contracts-ruby2/benchmarks/io.rb +62 -0
  15. data/lib/contracts-ruby2/benchmarks/wrap_test.rb +57 -0
  16. data/lib/contracts-ruby2/contracts.gemspec +17 -0
  17. data/lib/contracts-ruby2/cucumber.yml +1 -0
  18. data/lib/contracts-ruby2/dependabot.yml +20 -0
  19. data/lib/contracts-ruby2/features/README.md +17 -0
  20. data/lib/contracts-ruby2/features/basics/functype.feature +71 -0
  21. data/lib/contracts-ruby2/features/basics/pretty-print.feature +241 -0
  22. data/lib/contracts-ruby2/features/basics/simple_example.feature +210 -0
  23. data/lib/contracts-ruby2/features/builtin_contracts/README.md +22 -0
  24. data/lib/contracts-ruby2/features/builtin_contracts/and.feature +103 -0
  25. data/lib/contracts-ruby2/features/builtin_contracts/any.feature +44 -0
  26. data/lib/contracts-ruby2/features/builtin_contracts/args.feature +80 -0
  27. data/lib/contracts-ruby2/features/builtin_contracts/array_of.feature +1 -0
  28. data/lib/contracts-ruby2/features/builtin_contracts/bool.feature +64 -0
  29. data/lib/contracts-ruby2/features/builtin_contracts/enum.feature +1 -0
  30. data/lib/contracts-ruby2/features/builtin_contracts/eq.feature +1 -0
  31. data/lib/contracts-ruby2/features/builtin_contracts/exactly.feature +1 -0
  32. data/lib/contracts-ruby2/features/builtin_contracts/func.feature +1 -0
  33. data/lib/contracts-ruby2/features/builtin_contracts/hash_of.feature +1 -0
  34. data/lib/contracts-ruby2/features/builtin_contracts/int.feature +93 -0
  35. data/lib/contracts-ruby2/features/builtin_contracts/keyword_args.feature +1 -0
  36. data/lib/contracts-ruby2/features/builtin_contracts/maybe.feature +1 -0
  37. data/lib/contracts-ruby2/features/builtin_contracts/nat.feature +115 -0
  38. data/lib/contracts-ruby2/features/builtin_contracts/nat_pos.feature +119 -0
  39. data/lib/contracts-ruby2/features/builtin_contracts/neg.feature +115 -0
  40. data/lib/contracts-ruby2/features/builtin_contracts/none.feature +145 -0
  41. data/lib/contracts-ruby2/features/builtin_contracts/not.feature +1 -0
  42. data/lib/contracts-ruby2/features/builtin_contracts/num.feature +64 -0
  43. data/lib/contracts-ruby2/features/builtin_contracts/or.feature +83 -0
  44. data/lib/contracts-ruby2/features/builtin_contracts/pos.feature +116 -0
  45. data/lib/contracts-ruby2/features/builtin_contracts/range_of.feature +1 -0
  46. data/lib/contracts-ruby2/features/builtin_contracts/respond_to.feature +78 -0
  47. data/lib/contracts-ruby2/features/builtin_contracts/send.feature +147 -0
  48. data/lib/contracts-ruby2/features/builtin_contracts/set_of.feature +1 -0
  49. data/lib/contracts-ruby2/features/builtin_contracts/xor.feature +99 -0
  50. data/lib/contracts-ruby2/features/support/env.rb +6 -0
  51. data/lib/contracts-ruby2/lib/contracts/attrs.rb +24 -0
  52. data/lib/contracts-ruby2/lib/contracts/builtin_contracts.rb +542 -0
  53. data/lib/contracts-ruby2/lib/contracts/call_with.rb +108 -0
  54. data/lib/contracts-ruby2/lib/contracts/core.rb +52 -0
  55. data/lib/contracts-ruby2/lib/contracts/decorators.rb +47 -0
  56. data/lib/contracts-ruby2/lib/contracts/engine/base.rb +136 -0
  57. data/lib/contracts-ruby2/lib/contracts/engine/eigenclass.rb +50 -0
  58. data/lib/contracts-ruby2/lib/contracts/engine/target.rb +70 -0
  59. data/lib/contracts-ruby2/lib/contracts/engine.rb +26 -0
  60. data/lib/contracts-ruby2/lib/contracts/errors.rb +71 -0
  61. data/lib/contracts-ruby2/lib/contracts/formatters.rb +136 -0
  62. data/lib/contracts-ruby2/lib/contracts/invariants.rb +68 -0
  63. data/lib/contracts-ruby2/lib/contracts/method_handler.rb +187 -0
  64. data/lib/contracts-ruby2/lib/contracts/method_reference.rb +100 -0
  65. data/lib/contracts-ruby2/lib/contracts/support.rb +61 -0
  66. data/lib/contracts-ruby2/lib/contracts/validators.rb +139 -0
  67. data/lib/contracts-ruby2/lib/contracts/version.rb +3 -0
  68. data/lib/contracts-ruby2/lib/contracts.rb +281 -0
  69. data/lib/contracts-ruby2/script/docs-release +3 -0
  70. data/lib/contracts-ruby2/script/docs-staging +3 -0
  71. data/lib/contracts-ruby2/script/rubocop.rb +5 -0
  72. data/lib/contracts-ruby2/spec/attrs_spec.rb +119 -0
  73. data/lib/contracts-ruby2/spec/builtin_contracts_spec.rb +461 -0
  74. data/lib/contracts-ruby2/spec/contracts_spec.rb +770 -0
  75. data/lib/contracts-ruby2/spec/fixtures/fixtures.rb +730 -0
  76. data/lib/contracts-ruby2/spec/invariants_spec.rb +17 -0
  77. data/lib/contracts-ruby2/spec/methods_spec.rb +54 -0
  78. data/lib/contracts-ruby2/spec/module_spec.rb +18 -0
  79. data/lib/contracts-ruby2/spec/override_validators_spec.rb +162 -0
  80. data/lib/contracts-ruby2/spec/ruby_version_specific/contracts_spec_1.9.rb +24 -0
  81. data/lib/contracts-ruby2/spec/ruby_version_specific/contracts_spec_2.0.rb +55 -0
  82. data/lib/contracts-ruby2/spec/ruby_version_specific/contracts_spec_2.1.rb +63 -0
  83. data/lib/contracts-ruby2/spec/spec_helper.rb +102 -0
  84. data/lib/contracts-ruby2/spec/support.rb +10 -0
  85. data/lib/contracts-ruby2/spec/support_spec.rb +21 -0
  86. data/lib/contracts-ruby2/spec/validators_spec.rb +47 -0
  87. data/lib/contracts-ruby3/CHANGELOG.markdown +117 -0
  88. data/lib/contracts-ruby3/Gemfile +21 -0
  89. data/lib/contracts-ruby3/LICENSE +23 -0
  90. data/lib/contracts-ruby3/README.md +114 -0
  91. data/lib/contracts-ruby3/Rakefile +10 -0
  92. data/lib/contracts-ruby3/TODO.markdown +6 -0
  93. data/lib/contracts-ruby3/TUTORIAL.md +773 -0
  94. data/lib/contracts-ruby3/benchmarks/bench.rb +67 -0
  95. data/lib/contracts-ruby3/benchmarks/hash.rb +69 -0
  96. data/lib/contracts-ruby3/benchmarks/invariants.rb +91 -0
  97. data/lib/contracts-ruby3/benchmarks/io.rb +62 -0
  98. data/lib/contracts-ruby3/benchmarks/wrap_test.rb +57 -0
  99. data/lib/contracts-ruby3/contracts.gemspec +20 -0
  100. data/lib/contracts-ruby3/cucumber.yml +1 -0
  101. data/lib/contracts-ruby3/dependabot.yml +20 -0
  102. data/lib/contracts-ruby3/features/README.md +17 -0
  103. data/lib/contracts-ruby3/features/basics/functype.feature +71 -0
  104. data/lib/contracts-ruby3/features/basics/pretty-print.feature +241 -0
  105. data/lib/contracts-ruby3/features/basics/simple_example.feature +210 -0
  106. data/lib/contracts-ruby3/features/builtin_contracts/README.md +22 -0
  107. data/lib/contracts-ruby3/features/builtin_contracts/and.feature +103 -0
  108. data/lib/contracts-ruby3/features/builtin_contracts/any.feature +44 -0
  109. data/lib/contracts-ruby3/features/builtin_contracts/args.feature +80 -0
  110. data/lib/contracts-ruby3/features/builtin_contracts/array_of.feature +1 -0
  111. data/lib/contracts-ruby3/features/builtin_contracts/bool.feature +64 -0
  112. data/lib/contracts-ruby3/features/builtin_contracts/enum.feature +1 -0
  113. data/lib/contracts-ruby3/features/builtin_contracts/eq.feature +1 -0
  114. data/lib/contracts-ruby3/features/builtin_contracts/exactly.feature +1 -0
  115. data/lib/contracts-ruby3/features/builtin_contracts/func.feature +1 -0
  116. data/lib/contracts-ruby3/features/builtin_contracts/hash_of.feature +1 -0
  117. data/lib/contracts-ruby3/features/builtin_contracts/int.feature +93 -0
  118. data/lib/contracts-ruby3/features/builtin_contracts/keyword_args.feature +1 -0
  119. data/lib/contracts-ruby3/features/builtin_contracts/maybe.feature +1 -0
  120. data/lib/contracts-ruby3/features/builtin_contracts/nat.feature +115 -0
  121. data/lib/contracts-ruby3/features/builtin_contracts/nat_pos.feature +119 -0
  122. data/lib/contracts-ruby3/features/builtin_contracts/neg.feature +115 -0
  123. data/lib/contracts-ruby3/features/builtin_contracts/none.feature +145 -0
  124. data/lib/contracts-ruby3/features/builtin_contracts/not.feature +1 -0
  125. data/lib/contracts-ruby3/features/builtin_contracts/num.feature +64 -0
  126. data/lib/contracts-ruby3/features/builtin_contracts/or.feature +83 -0
  127. data/lib/contracts-ruby3/features/builtin_contracts/pos.feature +116 -0
  128. data/lib/contracts-ruby3/features/builtin_contracts/range_of.feature +1 -0
  129. data/lib/contracts-ruby3/features/builtin_contracts/respond_to.feature +78 -0
  130. data/lib/contracts-ruby3/features/builtin_contracts/send.feature +147 -0
  131. data/lib/contracts-ruby3/features/builtin_contracts/set_of.feature +1 -0
  132. data/lib/contracts-ruby3/features/builtin_contracts/xor.feature +99 -0
  133. data/lib/contracts-ruby3/features/support/env.rb +8 -0
  134. data/lib/contracts-ruby3/lib/contracts/attrs.rb +26 -0
  135. data/lib/contracts-ruby3/lib/contracts/builtin_contracts.rb +575 -0
  136. data/lib/contracts-ruby3/lib/contracts/call_with.rb +119 -0
  137. data/lib/contracts-ruby3/lib/contracts/core.rb +54 -0
  138. data/lib/contracts-ruby3/lib/contracts/decorators.rb +50 -0
  139. data/lib/contracts-ruby3/lib/contracts/engine/base.rb +137 -0
  140. data/lib/contracts-ruby3/lib/contracts/engine/eigenclass.rb +51 -0
  141. data/lib/contracts-ruby3/lib/contracts/engine/target.rb +72 -0
  142. data/lib/contracts-ruby3/lib/contracts/engine.rb +28 -0
  143. data/lib/contracts-ruby3/lib/contracts/errors.rb +74 -0
  144. data/lib/contracts-ruby3/lib/contracts/formatters.rb +140 -0
  145. data/lib/contracts-ruby3/lib/contracts/invariants.rb +72 -0
  146. data/lib/contracts-ruby3/lib/contracts/method_handler.rb +197 -0
  147. data/lib/contracts-ruby3/lib/contracts/method_reference.rb +102 -0
  148. data/lib/contracts-ruby3/lib/contracts/support.rb +63 -0
  149. data/lib/contracts-ruby3/lib/contracts/validators.rb +143 -0
  150. data/lib/contracts-ruby3/lib/contracts/version.rb +5 -0
  151. data/lib/contracts-ruby3/lib/contracts.rb +290 -0
  152. data/lib/contracts-ruby3/script/docs-release +3 -0
  153. data/lib/contracts-ruby3/script/docs-staging +3 -0
  154. data/lib/contracts-ruby3/script/rubocop.rb +5 -0
  155. data/lib/contracts-ruby3/spec/attrs_spec.rb +119 -0
  156. data/lib/contracts-ruby3/spec/builtin_contracts_spec.rb +457 -0
  157. data/lib/contracts-ruby3/spec/contracts_spec.rb +773 -0
  158. data/lib/contracts-ruby3/spec/fixtures/fixtures.rb +725 -0
  159. data/lib/contracts-ruby3/spec/invariants_spec.rb +17 -0
  160. data/lib/contracts-ruby3/spec/methods_spec.rb +54 -0
  161. data/lib/contracts-ruby3/spec/module_spec.rb +18 -0
  162. data/lib/contracts-ruby3/spec/override_validators_spec.rb +162 -0
  163. data/lib/contracts-ruby3/spec/ruby_version_specific/contracts_spec_1.9.rb +24 -0
  164. data/lib/contracts-ruby3/spec/ruby_version_specific/contracts_spec_2.0.rb +55 -0
  165. data/lib/contracts-ruby3/spec/ruby_version_specific/contracts_spec_2.1.rb +63 -0
  166. data/lib/contracts-ruby3/spec/spec_helper.rb +102 -0
  167. data/lib/contracts-ruby3/spec/support.rb +10 -0
  168. data/lib/contracts-ruby3/spec/support_spec.rb +21 -0
  169. data/lib/contracts-ruby3/spec/validators_spec.rb +47 -0
  170. data/lib/entitlements/data/groups/calculated/yaml.rb +7 -1
  171. data/lib/entitlements/data/people/yaml.rb +9 -1
  172. data/lib/entitlements/extras/ldap_group/rules/ldap_group.rb +5 -1
  173. data/lib/entitlements/extras/orgchart/person_methods.rb +7 -1
  174. data/lib/entitlements.rb +13 -2
  175. data/lib/ruby_version_check.rb +17 -0
  176. metadata +209 -14
@@ -0,0 +1,241 @@
1
+ Feature: Pretty printing Contract violations
2
+
3
+ Scenario: Big array argument being passed to big array method parameter
4
+ Given a file named "example.rb" with:
5
+ """ruby
6
+ require "contracts"
7
+ C = Contracts
8
+
9
+ class Example
10
+ include Contracts::Core
11
+
12
+ class << self
13
+ Contract [
14
+ C::Or[String, Symbol],
15
+ C::Or[String, Symbol],
16
+ C::Or[String, Symbol],
17
+ C::Or[String, Symbol],
18
+ C::Or[String, Symbol],
19
+ C::Or[String, Symbol],
20
+ C::Or[String, Symbol]
21
+ ] => nil
22
+ def run(data)
23
+ nil
24
+ end
25
+ end
26
+ end
27
+
28
+ puts Example.run([
29
+ ["foo", "foo"],
30
+ ["foo", "foo"],
31
+ ["foo", "foo"],
32
+ ["foo", "foo"],
33
+ ["foo", "foo"],
34
+ ["foo", "foo"],
35
+ ["foo", "foo"],
36
+ ["foo", "foo"],
37
+ ["foo", "foo"]
38
+ ])
39
+ """
40
+ When I run `ruby example.rb`
41
+ Then the output should contain:
42
+ """
43
+ : Contract violation for argument 1 of 1: (ParamContractError)
44
+ Expected: [(String or Symbol),
45
+ (String or Symbol),
46
+ (String or Symbol),
47
+ (String or Symbol),
48
+ (String or Symbol),
49
+ (String or Symbol),
50
+ (String or Symbol)],
51
+ Actual: [["foo", "foo"],
52
+ ["foo", "foo"],
53
+ ["foo", "foo"],
54
+ ["foo", "foo"],
55
+ ["foo", "foo"],
56
+ ["foo", "foo"],
57
+ ["foo", "foo"],
58
+ ["foo", "foo"],
59
+ ["foo", "foo"]]
60
+ Value guarded in: Example::run
61
+ With Contract: Array => NilClass
62
+ At: example.rb:17
63
+ """
64
+
65
+ Scenario: Big array value being returned from method expecting different big array type
66
+ Given a file named "example.rb" with:
67
+ """ruby
68
+ require "contracts"
69
+ C = Contracts
70
+
71
+ class Example
72
+ include Contracts::Core
73
+
74
+ class << self
75
+ Contract C::None => [
76
+ C::Or[String, Symbol],
77
+ C::Or[String, Symbol],
78
+ C::Or[String, Symbol],
79
+ C::Or[String, Symbol],
80
+ C::Or[String, Symbol],
81
+ C::Or[String, Symbol],
82
+ C::Or[String, Symbol]
83
+ ]
84
+ def run
85
+ [
86
+ ["foo", "foo"],
87
+ ["foo", "foo"],
88
+ ["foo", "foo"],
89
+ ["foo", "foo"],
90
+ ["foo", "foo"],
91
+ ["foo", "foo"],
92
+ ["foo", "foo"],
93
+ ["foo", "foo"],
94
+ ["foo", "foo"]
95
+ ]
96
+ end
97
+ end
98
+ end
99
+
100
+ puts Example.run
101
+ """
102
+ When I run `ruby example.rb`
103
+ Then the output should contain:
104
+ """
105
+ : Contract violation for return value: (ReturnContractError)
106
+ Expected: [(String or Symbol),
107
+ (String or Symbol),
108
+ (String or Symbol),
109
+ (String or Symbol),
110
+ (String or Symbol),
111
+ (String or Symbol),
112
+ (String or Symbol)],
113
+ Actual: [["foo", "foo"],
114
+ ["foo", "foo"],
115
+ ["foo", "foo"],
116
+ ["foo", "foo"],
117
+ ["foo", "foo"],
118
+ ["foo", "foo"],
119
+ ["foo", "foo"],
120
+ ["foo", "foo"],
121
+ ["foo", "foo"]]
122
+ Value guarded in: Example::run
123
+ With Contract: None => Array
124
+ At: example.rb:17
125
+ """
126
+
127
+ Scenario: Big hash argument being passed to big hash method parameter
128
+ Given a file named "example.rb" with:
129
+ """ruby
130
+ require "contracts"
131
+ C = Contracts
132
+
133
+ class Example
134
+ include Contracts::Core
135
+
136
+ class << self
137
+ Contract ({
138
+ a: C::Or[String, Symbol],
139
+ b: C::Or[String, Symbol],
140
+ c: C::Or[String, Symbol],
141
+ d: C::Or[String, Symbol],
142
+ e: C::Or[String, Symbol],
143
+ f: C::Or[String, Symbol],
144
+ g: C::Or[String, Symbol]
145
+ }) => nil
146
+ def run(data)
147
+ nil
148
+ end
149
+ end
150
+ end
151
+
152
+ puts Example.run({
153
+ a: ["foo", "foo"],
154
+ b: ["foo", "foo"],
155
+ c: ["foo", "foo"],
156
+ d: ["foo", "foo"],
157
+ e: ["foo", "foo"],
158
+ f: ["foo", "foo"],
159
+ g: ["foo", "foo"]
160
+ })
161
+ """
162
+ When I run `ruby example.rb`
163
+ Then the output should contain:
164
+ """
165
+ : Contract violation for argument 1 of 1: (ParamContractError)
166
+ Expected: {:a=>(String or Symbol),
167
+ :b=>(String or Symbol),
168
+ :c=>(String or Symbol),
169
+ :d=>(String or Symbol),
170
+ :e=>(String or Symbol),
171
+ :f=>(String or Symbol),
172
+ :g=>(String or Symbol)},
173
+ Actual: {:a=>["foo", "foo"],
174
+ :b=>["foo", "foo"],
175
+ :c=>["foo", "foo"],
176
+ :d=>["foo", "foo"],
177
+ :e=>["foo", "foo"],
178
+ :f=>["foo", "foo"],
179
+ :g=>["foo", "foo"]}
180
+ Value guarded in: Example::run
181
+ With Contract: Hash => NilClass
182
+ At: example.rb:17
183
+ """
184
+
185
+ Scenario: Big hash value being returned from method expecting different big hash type
186
+ Given a file named "example.rb" with:
187
+ """ruby
188
+ require "contracts"
189
+ C = Contracts
190
+
191
+ class Example
192
+ include Contracts::Core
193
+
194
+ class << self
195
+ Contract C::None => ({
196
+ a: C::Or[String, Symbol],
197
+ b: C::Or[String, Symbol],
198
+ c: C::Or[String, Symbol],
199
+ d: C::Or[String, Symbol],
200
+ e: C::Or[String, Symbol],
201
+ f: C::Or[String, Symbol],
202
+ g: C::Or[String, Symbol]
203
+ })
204
+ def run
205
+ {
206
+ a: ["foo", "foo"],
207
+ b: ["foo", "foo"],
208
+ c: ["foo", "foo"],
209
+ d: ["foo", "foo"],
210
+ e: ["foo", "foo"],
211
+ f: ["foo", "foo"],
212
+ g: ["foo", "foo"]
213
+ }
214
+ end
215
+ end
216
+ end
217
+
218
+ puts Example.run
219
+ """
220
+ When I run `ruby example.rb`
221
+ Then the output should contain:
222
+ """
223
+ : Contract violation for return value: (ReturnContractError)
224
+ Expected: {:a=>(String or Symbol),
225
+ :b=>(String or Symbol),
226
+ :c=>(String or Symbol),
227
+ :d=>(String or Symbol),
228
+ :e=>(String or Symbol),
229
+ :f=>(String or Symbol),
230
+ :g=>(String or Symbol)},
231
+ Actual: {:a=>["foo", "foo"],
232
+ :b=>["foo", "foo"],
233
+ :c=>["foo", "foo"],
234
+ :d=>["foo", "foo"],
235
+ :e=>["foo", "foo"],
236
+ :f=>["foo", "foo"],
237
+ :g=>["foo", "foo"]}
238
+ Value guarded in: Example::run
239
+ With Contract: None => Hash
240
+ At: example.rb:17
241
+ """
@@ -0,0 +1,210 @@
1
+ Feature: Simple examples and Contract violations
2
+
3
+ Contracts.ruby allows specification of contracts on per-method basis, where
4
+ method arguments and return value will be validated upon method call.
5
+
6
+ Example:
7
+
8
+ ```ruby
9
+ Contract C::Num, C::Num => C::Num
10
+ def add(a, b)
11
+ a + b
12
+ end
13
+ ```
14
+
15
+ Here `Contract arg_contracts... => return_contract` defines list of argument
16
+ contracts `args_contracts...` as `C::Num, C::Num` (i.e.: both arguments
17
+ should be numbers) and return value contract `return_contract` as `C::Num`
18
+ (i.e.: return value should be a number too).
19
+
20
+ `Contract arg_contracts... => return_contract` affects next defined instance,
21
+ class or singleton method, meaning that all of these work:
22
+
23
+ - [Instance method](#instance-method),
24
+
25
+ - [Class method](#class-method),
26
+
27
+ - [Singleton method](#singleton-method).
28
+
29
+ Whenever invalid argument is passed to a contracted method, corresponding
30
+ `ContractError` will be raised. That happens right after bad value got into
31
+ system protected by contracts and prevents error propagation: first
32
+ non-contracts library frame in exception's backtrace is a culprit for passing
33
+ an invalid argument - you do not need to verify 20-30 frames to find a
34
+ culprit! Example of such error: [instance method contract
35
+ violation](#instance-method-contract-violation).
36
+
37
+ Whenever invalid return value is returned from a contracted method,
38
+ corresponding `ContractError` will be raised. That happens right after method
39
+ returned this value and prevents error propagation: `At: your_filename.rb:17`
40
+ part of error message points directly to a culprit method. Example of such
41
+ error: [return value contract
42
+ violation](#singleton-method-return-value-contract-violation).
43
+
44
+ Contract violation error consists of such parts:
45
+ - Violation type:
46
+ - `Contract violation for argument X of Y: (ParamContractError)`,
47
+ - `Contract violation for return value (ReturnContractError)`.
48
+ - Expected contract, example: `Expected: Num`.
49
+ - Actual value, example: `Actual: "foo"`.
50
+ - Location of violated contract, example: `Value guarded in: Example::add`.
51
+ - Full contract, example: `With Contract: Num, Num => Num`.
52
+ - Source code location of contracted method, example: `At: lib/your_library/some_class.rb:17`.
53
+
54
+ Scenario: Instance method
55
+ Given a file named "instance_method.rb" with:
56
+ """ruby
57
+ require "contracts"
58
+ C = Contracts
59
+
60
+ class Example
61
+ include Contracts::Core
62
+
63
+ Contract C::Num, C::Num => C::Num
64
+ def add(a, b)
65
+ a + b
66
+ end
67
+ end
68
+
69
+ puts Example.new.add(2, 2)
70
+ """
71
+ When I run `ruby instance_method.rb`
72
+ Then the output should contain:
73
+ """
74
+ 4
75
+ """
76
+
77
+ Scenario: Instance method contract violation
78
+ Given a file named "instance_method_violation.rb" with:
79
+ """ruby
80
+ require "contracts"
81
+ C = Contracts
82
+
83
+ class Example
84
+ include Contracts::Core
85
+
86
+ Contract C::Num, C::Num => C::Num
87
+ def add(a, b)
88
+ a + b
89
+ end
90
+ end
91
+
92
+ puts Example.new.add(2, "foo")
93
+ """
94
+ When I run `ruby instance_method_violation.rb`
95
+ Then the output should contain:
96
+ """
97
+ : Contract violation for argument 2 of 2: (ParamContractError)
98
+ Expected: Num,
99
+ Actual: "foo"
100
+ Value guarded in: Example::add
101
+ With Contract: Num, Num => Num
102
+ At: instance_method_violation.rb:8
103
+ """
104
+
105
+ Scenario: Class method
106
+ Given a file named "class_method.rb" with:
107
+ """ruby
108
+ require "contracts"
109
+ C = Contracts
110
+
111
+ class Example
112
+ include Contracts::Core
113
+
114
+ Contract C::Num, C::Num => C::Num
115
+ def self.add(a, b)
116
+ a + b
117
+ end
118
+ end
119
+
120
+ puts Example.add(2, 2)
121
+ """
122
+ When I run `ruby class_method.rb`
123
+ Then the output should contain:
124
+ """
125
+ 4
126
+ """
127
+
128
+ Scenario: Class method contract violation
129
+ Given a file named "class_method_violation.rb" with:
130
+ """ruby
131
+ require "contracts"
132
+ C = Contracts
133
+
134
+ class Example
135
+ include Contracts::Core
136
+
137
+ Contract C::Num, C::Num => C::Num
138
+ def self.add(a, b)
139
+ a + b
140
+ end
141
+ end
142
+
143
+ puts Example.add(:foo, 2)
144
+ """
145
+ When I run `ruby class_method_violation.rb`
146
+ Then the output should contain:
147
+ """
148
+ : Contract violation for argument 1 of 2: (ParamContractError)
149
+ Expected: Num,
150
+ Actual: :foo
151
+ Value guarded in: Example::add
152
+ With Contract: Num, Num => Num
153
+ At: class_method_violation.rb:8
154
+ """
155
+
156
+ Scenario: Singleton method
157
+ Given a file named "singleton_method.rb" with:
158
+ """ruby
159
+ require "contracts"
160
+ C = Contracts
161
+
162
+ class Example
163
+ include Contracts::Core
164
+
165
+ class << self
166
+ Contract C::Num, C::Num => C::Num
167
+ def add(a, b)
168
+ a + b
169
+ end
170
+ end
171
+ end
172
+
173
+ puts Example.add(2, 2)
174
+ """
175
+ When I run `ruby singleton_method.rb`
176
+ Then the output should contain:
177
+ """
178
+ 4
179
+ """
180
+
181
+ Scenario: Singleton method return value contract violation
182
+ Given a file named "singleton_method_violation.rb" with:
183
+ """ruby
184
+ require "contracts"
185
+ C = Contracts
186
+
187
+ class Example
188
+ include Contracts::Core
189
+
190
+ class << self
191
+ Contract C::Num, C::Num => C::Num
192
+ def add(a, b)
193
+ # notice here non-number is returned
194
+ nil
195
+ end
196
+ end
197
+ end
198
+
199
+ puts Example.add(2, 2)
200
+ """
201
+ When I run `ruby singleton_method_violation.rb`
202
+ Then the output should contain:
203
+ """
204
+ : Contract violation for return value: (ReturnContractError)
205
+ Expected: Num,
206
+ Actual: nil
207
+ Value guarded in: Example::add
208
+ With Contract: Num, Num => Num
209
+ At: singleton_method_violation.rb:9
210
+ """
@@ -0,0 +1,22 @@
1
+ To use builtin contracts you can refer them with `Contracts::*`:
2
+
3
+ ```ruby
4
+ Contract Contracts::Num => Contracts::Maybe(Contracts::Num)
5
+ ```
6
+
7
+ It is recommended to use a short alias for `Contracts`, for example `C`:
8
+
9
+ ```ruby
10
+ C = Contracts
11
+
12
+ Contract C::Num => C::Maybe(C::Num)
13
+ ```
14
+
15
+ It is possible to `include Contracts` and refer them without namespace, but
16
+ this is deprecated and not recommended.
17
+
18
+ *NOTE: in the future it will be possible to do `include Contracts::Builtin`
19
+ instead.*
20
+
21
+ *NOTE: all contracts marked as (TODO) have their documentaion `.feature` file
22
+ as stub. Contributions to those are warmly welcome!*
@@ -0,0 +1,103 @@
1
+ Feature: And
2
+
3
+ Takes a variable number of contracts. The contract passes if all of the
4
+ contracts pass.
5
+
6
+ ```ruby
7
+ Contract C::And[Float, C::Neg] => String
8
+ ```
9
+
10
+ This example will validate first argument of a method and accept only
11
+ negative `Float`.
12
+
13
+ Background:
14
+ Given a file named "and_usage.rb" with:
15
+ """ruby
16
+ require "contracts"
17
+ C = Contracts
18
+
19
+ class Example
20
+ include Contracts::Core
21
+
22
+ Contract C::And[Float, C::Neg] => String
23
+ def fneg_string(number)
24
+ number.to_i.to_s
25
+ end
26
+ end
27
+ """
28
+
29
+ Scenario: Accepts negative float
30
+ Given a file named "accepts_negative_float.rb" with:
31
+ """ruby
32
+ require "./and_usage"
33
+ puts Example.new.fneg_string(-3.7)
34
+ """
35
+ When I run `ruby accepts_negative_float.rb`
36
+ Then output should contain:
37
+ """
38
+ -3
39
+ """
40
+
41
+ Scenario: Rejects positive float
42
+ Given a file named "rejects_positive_float.rb" with:
43
+ """ruby
44
+ require "./and_usage"
45
+ puts Example.new.fneg_string(7.5)
46
+ """
47
+ When I run `ruby rejects_positive_float.rb`
48
+ Then output should contain:
49
+ """
50
+ : Contract violation for argument 1 of 1: (ParamContractError)
51
+ Expected: (Float and Neg),
52
+ Actual: 7.5
53
+ Value guarded in: Example::fneg_string
54
+ With Contract: And => String
55
+ """
56
+
57
+ Scenario: Rejects negative integer
58
+ Given a file named "rejects_negative_integer.rb" with:
59
+ """ruby
60
+ require "./and_usage"
61
+ puts Example.new.fneg_string(-5)
62
+ """
63
+ When I run `ruby rejects_negative_integer.rb`
64
+ Then output should contain:
65
+ """
66
+ : Contract violation for argument 1 of 1: (ParamContractError)
67
+ Expected: (Float and Neg),
68
+ Actual: -5
69
+ Value guarded in: Example::fneg_string
70
+ With Contract: And => String
71
+ """
72
+
73
+ Scenario: Rejects positive integer
74
+ Given a file named "rejects_positive_integer.rb" with:
75
+ """ruby
76
+ require "./and_usage"
77
+ puts Example.new.fneg_string(5)
78
+ """
79
+ When I run `ruby rejects_positive_integer.rb`
80
+ Then output should contain:
81
+ """
82
+ : Contract violation for argument 1 of 1: (ParamContractError)
83
+ Expected: (Float and Neg),
84
+ Actual: 5
85
+ Value guarded in: Example::fneg_string
86
+ With Contract: And => String
87
+ """
88
+
89
+ Scenario: Rejects others
90
+ Given a file named "rejects_others.rb" with:
91
+ """ruby
92
+ require "./and_usage"
93
+ puts Example.new.fneg_string(:foo)
94
+ """
95
+ When I run `ruby rejects_others.rb`
96
+ Then output should contain:
97
+ """
98
+ : Contract violation for argument 1 of 1: (ParamContractError)
99
+ Expected: (Float and Neg),
100
+ Actual: :foo
101
+ Value guarded in: Example::fneg_string
102
+ With Contract: And => String
103
+ """
@@ -0,0 +1,44 @@
1
+ Feature: Any
2
+
3
+ Passes for any argument.
4
+
5
+ ```ruby
6
+ Contract C::Any => String
7
+ ```
8
+
9
+ Scenario: Accepts any argument
10
+ Given a file named "any_usage.rb" with:
11
+ """ruby
12
+ require "contracts"
13
+ C = Contracts
14
+
15
+ class Example
16
+ include Contracts::Core
17
+
18
+ Contract C::Any => String
19
+ def self.stringify(x)
20
+ x.inspect
21
+ end
22
+ end
23
+
24
+ puts Example.stringify(25)
25
+ puts Example.stringify(37.59)
26
+ puts Example.stringify("foo")
27
+ puts Example.stringify(:foo)
28
+ puts Example.stringify(nil)
29
+ puts Example.stringify(Object)
30
+ """
31
+ When I run `ruby any_usage.rb`
32
+ Then output should contain:
33
+ """
34
+ 25
35
+ 37.59
36
+ "foo"
37
+ :foo
38
+ nil
39
+ Object
40
+ """
41
+ And output should not contain:
42
+ """
43
+ Contract violation for
44
+ """
@@ -0,0 +1,80 @@
1
+ Feature: Args
2
+
3
+ Used for `*args` (variadic functions). Takes contract and uses it to validate
4
+ every element passed in through `*args`.
5
+
6
+ ```ruby
7
+ Contract C::Args[C::Num] => C::Bool
8
+ def example(*args)
9
+ ```
10
+
11
+ This example contract will validate all arguments passed through `*args` to
12
+ accept only numbers.
13
+
14
+ Background:
15
+ Given a file named "args_usage.rb" with:
16
+ """ruby
17
+ require "contracts"
18
+ C = Contracts
19
+
20
+ class Example
21
+ include Contracts::Core
22
+
23
+ Contract C::Args[C::Num] => C::Bool
24
+ def only_nums(*args)
25
+ args.inspect
26
+ end
27
+ end
28
+ """
29
+
30
+ Scenario: Accepts no arguments
31
+ Given a file named "accepts_no_arguments.rb" with:
32
+ """ruby
33
+ require "./args_usage"
34
+ puts Example.new.only_nums
35
+ """
36
+ When I run `ruby accepts_no_arguments.rb`
37
+ Then the output should contain:
38
+ """
39
+ []
40
+ """
41
+
42
+ Scenario: Accepts one valid argument
43
+ Given a file named "accepts_one_argument.rb" with:
44
+ """ruby
45
+ require "./args_usage"
46
+ puts Example.new.only_nums(42)
47
+ """
48
+ When I run `ruby accepts_one_argument.rb`
49
+ Then the output should contain:
50
+ """
51
+ [42]
52
+ """
53
+
54
+ Scenario: Accepts many valid arguments
55
+ Given a file named "accepts_many_arguments.rb" with:
56
+ """ruby
57
+ require "./args_usage"
58
+ puts Example.new.only_nums(42, 45, 17, 24)
59
+ """
60
+ When I run `ruby accepts_many_arguments.rb`
61
+ Then the output should contain:
62
+ """
63
+ [42, 45, 17, 24]
64
+ """
65
+
66
+ Scenario: Rejects invalid argument
67
+ Given a file named "rejects_invalid_argument.rb" with:
68
+ """ruby
69
+ require "./args_usage"
70
+ puts Example.new.only_nums(42, "foo", 17, 24)
71
+ """
72
+ When I run `ruby rejects_invalid_argument.rb`
73
+ Then the output should contain:
74
+ """
75
+ : Contract violation for argument 1 of 4: (ParamContractError)
76
+ Expected: (Args[Contracts::Builtin::Num]),
77
+ Actual: "foo"
78
+ Value guarded in: Example::only_nums
79
+ With Contract: Args => Bool
80
+ """
@@ -0,0 +1 @@
1
+ Feature: ArrayOf (TODO)