entitlements-app 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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)