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,730 @@
1
+ require "date"
2
+
3
+ C = Contracts
4
+
5
+ class A
6
+ include Contracts::Core
7
+
8
+ Contract C::Num => C::Num
9
+ def self.a_class_method x
10
+ x + 1
11
+ end
12
+
13
+ def good
14
+ true
15
+ end
16
+
17
+ Contract C::Num => C::Num
18
+ def triple x
19
+ x * 3
20
+ end
21
+
22
+ Contract C::Num => C::Num
23
+ def instance_and_class_method x
24
+ x * 2
25
+ end
26
+
27
+ Contract String => String
28
+ def self.instance_and_class_method x
29
+ x * 2
30
+ end
31
+ end
32
+
33
+ class B
34
+ include Contracts::Core
35
+
36
+ def bad
37
+ false
38
+ end
39
+
40
+ Contract String => String
41
+ def triple x
42
+ x * 3
43
+ end
44
+ end
45
+
46
+ class F
47
+ include Contracts::Core
48
+
49
+ def good
50
+ false
51
+ end
52
+
53
+ def bad
54
+ true
55
+ end
56
+ end
57
+
58
+ class EmptyCont
59
+ def self.to_s
60
+ ""
61
+ end
62
+ end
63
+
64
+ class GenericExample
65
+ include Contracts::Core
66
+
67
+ Contract C::Num => C::Num
68
+ def self.a_class_method x
69
+ x + 1
70
+ end
71
+
72
+ Contract C::Num => nil
73
+ def bad_double(x)
74
+ x * 2
75
+ end
76
+
77
+ Contract C::Num => C::Num
78
+ def double(x)
79
+ x * 2
80
+ end
81
+
82
+ Contract 123, nil => nil
83
+ def constanty(num, nul)
84
+ 0
85
+ end
86
+
87
+ Contract String => nil
88
+ def hello(name)
89
+ end
90
+
91
+ Contract lambda { |x| x.is_a? Numeric } => C::Num
92
+ def square(x)
93
+ x ** 2
94
+ end
95
+
96
+ Contract [C::Num, C::Num, C::Num] => C::Num
97
+ def sum_three(vals)
98
+ vals.inject(0) do |acc, x|
99
+ acc + x
100
+ end
101
+ end
102
+
103
+ Contract ({ :name => String, :age => Fixnum }) => nil
104
+ def person(data)
105
+ end
106
+
107
+ Contract C::StrictHash[{ :name => String, :age => Fixnum }] => nil
108
+ def strict_person(data)
109
+ end
110
+
111
+ Contract ({ :rigged => C::Or[TrueClass, FalseClass] }) => nil
112
+ def hash_complex_contracts(data)
113
+ end
114
+
115
+ Contract ({ :rigged => C::Bool,
116
+ :contents => { :kind => C::Or[String, Symbol],
117
+ :total => C::Num }
118
+ }) => nil
119
+ def nested_hash_complex_contracts(data)
120
+ end
121
+
122
+ Contract C::KeywordArgs[:name => String, :age => Fixnum] => nil
123
+ def person_keywordargs(data)
124
+ end
125
+
126
+ # Testing overloaded method
127
+ Contract String, Fixnum => nil
128
+ def person_keywordargs(name, age)
129
+ end
130
+
131
+ Contract C::KeywordArgs[:hash => C::HashOf[Symbol, C::Num]] => nil
132
+ def hash_keywordargs(data)
133
+ end
134
+
135
+ Contract (/foo/) => nil
136
+ def should_contain_foo(s)
137
+ end
138
+
139
+ Contract ({ :host => /foo/ }) => nil
140
+ def hash_containing_foo(s)
141
+ end
142
+
143
+ Contract C::ArrayOf[/foo/] => nil
144
+ def array_containing_foo(s)
145
+ end
146
+
147
+ Contract [C::Or[TrueClass, FalseClass]] => nil
148
+ def array_complex_contracts(data)
149
+ end
150
+
151
+ Contract [C::Bool, [C::Or[String, Symbol]]] => nil
152
+ def nested_array_complex_contracts(data)
153
+ end
154
+
155
+ Contract [
156
+ C::Or[String, Symbol],
157
+ C::Or[String, Symbol],
158
+ C::Or[String, Symbol],
159
+ C::Or[String, Symbol],
160
+ C::Or[String, Symbol],
161
+ C::Or[String, Symbol],
162
+ C::Or[String, Symbol]
163
+ ] => nil
164
+ def long_array_param_contracts(data)
165
+ end
166
+
167
+ Contract C::None => [
168
+ C::Or[String, Symbol],
169
+ C::Or[String, Symbol],
170
+ C::Or[String, Symbol],
171
+ C::Or[String, Symbol],
172
+ C::Or[String, Symbol],
173
+ C::Or[String, Symbol],
174
+ C::Or[String, Symbol]
175
+ ]
176
+ def long_array_return_contracts
177
+ end
178
+
179
+ Contract Proc => C::Any
180
+ def do_call(&block)
181
+ block.call
182
+ end
183
+
184
+ Contract C::Args[C::Num], C::Maybe[Proc] => C::Any
185
+ def maybe_call(*vals, &block)
186
+ block.call if block
187
+ vals
188
+ end
189
+
190
+ Contract C::Args[C::Num] => C::Num
191
+ def sum(*vals)
192
+ vals.inject(0) do |acc, val|
193
+ acc + val
194
+ end
195
+ end
196
+
197
+ Contract C::Args[C::Num], Proc => C::Num
198
+ def with_partial_sums(*vals, &blk)
199
+ sum = vals.inject(0) do |acc, val|
200
+ blk[acc]
201
+ acc + val
202
+ end
203
+ blk[sum]
204
+ end
205
+
206
+ Contract C::Args[C::Num], C::Func[C::Num => C::Num] => C::Num
207
+ def with_partial_sums_contracted(*vals, &blk)
208
+ sum = vals.inject(0) do |acc, val|
209
+ blk[acc]
210
+ acc + val
211
+ end
212
+ blk[sum]
213
+ end
214
+
215
+ # Important to use different arg types or it falsely passes
216
+ Contract C::Num, C::Args[String] => C::ArrayOf[String]
217
+ def arg_then_splat(n, *vals)
218
+ vals.map { |v| v * n }
219
+ end
220
+
221
+ Contract C::Num, Proc => nil
222
+ def double_with_proc(x, &blk)
223
+ blk.call(x * 2)
224
+ nil
225
+ end
226
+
227
+ Contract C::Pos => nil
228
+ def pos_test(x)
229
+ end
230
+
231
+ Contract C::Neg => nil
232
+ def neg_test(x)
233
+ end
234
+
235
+ Contract C::Nat => nil
236
+ def nat_test(x)
237
+ end
238
+
239
+ Contract C::Any => nil
240
+ def show(x)
241
+ end
242
+
243
+ Contract C::None => nil
244
+ def fail_all(x)
245
+ end
246
+
247
+ Contract C::Or[C::Num, String] => nil
248
+ def num_or_string(x)
249
+ end
250
+
251
+ Contract C::Xor[C::RespondTo[:good], C::RespondTo[:bad]] => nil
252
+ def xor_test(x)
253
+ end
254
+
255
+ Contract C::And[A, C::RespondTo[:good]] => nil
256
+ def and_test(x)
257
+ end
258
+
259
+ Contract C::Enum[:a, :b, :c] => nil
260
+ def enum_test(x)
261
+ end
262
+
263
+ Contract C::RespondTo[:good] => nil
264
+ def responds_test(x)
265
+ end
266
+
267
+ Contract C::Send[:good] => nil
268
+ def send_test(x)
269
+ end
270
+
271
+ Contract C::Not[nil] => nil
272
+ def not_nil(x)
273
+ end
274
+
275
+ Contract C::ArrayOf[C::Num] => C::Num
276
+ def product(vals)
277
+ vals.inject(1) do |acc, x|
278
+ acc * x
279
+ end
280
+ end
281
+
282
+ Contract C::SetOf[C::Num] => C::Num
283
+ def product_from_set(vals)
284
+ vals.inject(1) do |acc, x|
285
+ acc * x
286
+ end
287
+ end
288
+
289
+ Contract C::RangeOf[C::Num] => C::Num
290
+ def first_in_range_num(r)
291
+ r.first
292
+ end
293
+
294
+ Contract C::RangeOf[Date] => Date
295
+ def first_in_range_date(r)
296
+ r.first
297
+ end
298
+
299
+ Contract C::DescendantOf[Enumerable] => nil
300
+ def enumerable_descendant_test(enum)
301
+ end
302
+
303
+ Contract C::Bool => nil
304
+ def bool_test(x)
305
+ end
306
+
307
+ Contract C::Num
308
+ def no_args
309
+ 1
310
+ end
311
+
312
+ # This function has a contract which says it has no args,
313
+ # but the function does have args.
314
+ Contract nil => C::Num
315
+ def old_style_no_args
316
+ 2
317
+ end
318
+
319
+ Contract C::ArrayOf[C::Num], C::Func[C::Num => C::Num] => C::ArrayOf[C::Num]
320
+ def map(arr, func)
321
+ ret = []
322
+ arr.each do |x|
323
+ ret << func[x]
324
+ end
325
+ ret
326
+ end
327
+
328
+ Contract C::ArrayOf[C::Any], Proc => C::ArrayOf[C::Any]
329
+ def tutorial_map(arr, func)
330
+ ret = []
331
+ arr.each do |x|
332
+ ret << func[x]
333
+ end
334
+ ret
335
+ end
336
+
337
+ # Need to test Func with weak contracts for other args
338
+ # and changing type from input to output otherwise it falsely passes!
339
+ Contract Array, C::Func[String => C::Num] => Array
340
+ def map_plain(arr, func)
341
+ arr.map do |x|
342
+ func[x]
343
+ end
344
+ end
345
+
346
+ Contract C::None => C::Func[String => C::Num]
347
+ def lambda_with_wrong_return
348
+ lambda { |x| x }
349
+ end
350
+
351
+ Contract C::None => C::Func[String => C::Num]
352
+ def lambda_with_correct_return
353
+ lambda { |x| x.length }
354
+ end
355
+
356
+ Contract C::Num => C::Num
357
+ def default_args(x = 1)
358
+ 2
359
+ end
360
+
361
+ Contract C::Maybe[C::Num] => C::Maybe[C::Num]
362
+ def maybe_double x
363
+ if x.nil?
364
+ nil
365
+ else
366
+ x * 2
367
+ end
368
+ end
369
+
370
+ Contract C::HashOf[Symbol, C::Num] => C::Num
371
+ def gives_max_value(hash)
372
+ hash.values.max
373
+ end
374
+
375
+ Contract C::HashOf[Symbol => C::Num] => C::Num
376
+ def pretty_gives_max_value(hash)
377
+ hash.values.max
378
+ end
379
+
380
+ Contract EmptyCont => C::Any
381
+ def using_empty_contract(a)
382
+ a
383
+ end
384
+
385
+ Contract (1..10) => nil
386
+ def method_with_range_contract(x)
387
+ end
388
+
389
+ Contract String
390
+ def a_private_method
391
+ "works"
392
+ end
393
+ private :a_private_method
394
+
395
+ Contract String
396
+ def a_protected_method
397
+ "works"
398
+ end
399
+ protected :a_protected_method
400
+
401
+ private
402
+
403
+ Contract String
404
+ def a_really_private_method
405
+ "works for sure"
406
+ end
407
+
408
+ protected
409
+
410
+ Contract String
411
+ def a_really_protected_method
412
+ "works for sure"
413
+ end
414
+ end
415
+
416
+ # for testing inheritance
417
+ class Parent
418
+ include Contracts::Core
419
+
420
+ Contract C::Num => C::Num
421
+ def double x
422
+ x * 2
423
+ end
424
+ end
425
+
426
+ class Child < Parent
427
+ end
428
+
429
+ class GenericExample
430
+ Contract Parent => Parent
431
+ def id_ a
432
+ a
433
+ end
434
+
435
+ Contract C::Exactly[Parent] => nil
436
+ def exactly_test(x)
437
+ end
438
+ end
439
+
440
+ # for testing equality
441
+ class Foo
442
+ end
443
+ module Bar
444
+ end
445
+ Baz = 1
446
+
447
+ class GenericExample
448
+ Contract C::Eq[Foo] => C::Any
449
+ def eq_class_test(x)
450
+ end
451
+
452
+ Contract C::Eq[Bar] => C::Any
453
+ def eq_module_test(x)
454
+ end
455
+
456
+ Contract C::Eq[Baz] => C::Any
457
+ def eq_value_test(x)
458
+ end
459
+ end
460
+
461
+ # pattern matching example with possible deep contract violation
462
+ class PatternMatchingExample
463
+ include Contracts::Core
464
+
465
+ class Success
466
+ attr_accessor :request
467
+ def initialize request
468
+ @request = request
469
+ end
470
+
471
+ def ==(other)
472
+ request == other.request
473
+ end
474
+ end
475
+
476
+ class Failure
477
+ end
478
+
479
+ Response = C::Or[Success, Failure]
480
+
481
+ class StringWithHello
482
+ def self.valid?(string)
483
+ string.is_a?(String) && !!string.match(/hello/i)
484
+ end
485
+ end
486
+
487
+ Contract Success => Response
488
+ def process_request(status)
489
+ Success.new(decorated_request(status.request))
490
+ end
491
+
492
+ Contract Failure => Response
493
+ def process_request(status)
494
+ Failure.new
495
+ end
496
+
497
+ Contract StringWithHello => String
498
+ def decorated_request(request)
499
+ request + "!"
500
+ end
501
+
502
+ Contract C::Num, String => String
503
+ def do_stuff(number, string)
504
+ "foo"
505
+ end
506
+
507
+ Contract C::Num, String, C::Num => String
508
+ def do_stuff(number, string, other_number)
509
+ "bar"
510
+ end
511
+
512
+ Contract C::Num => C::Num
513
+ def double x
514
+ "bad"
515
+ end
516
+
517
+ Contract String => String
518
+ def double x
519
+ x * 2
520
+ end
521
+ end
522
+
523
+ # invariant example (silliest implementation ever)
524
+ class MyBirthday
525
+ include Contracts::Core
526
+ include Contracts::Invariants
527
+
528
+ invariant(:day) { 1 <= day && day <= 31 }
529
+ invariant(:month) { 1 <= month && month <= 12 }
530
+
531
+ attr_accessor :day, :month
532
+ def initialize(day, month)
533
+ @day = day
534
+ @month = month
535
+ end
536
+
537
+ Contract C::None => Fixnum
538
+ def silly_next_day!
539
+ self.day += 1
540
+ end
541
+
542
+ Contract C::None => Fixnum
543
+ def silly_next_month!
544
+ self.month += 1
545
+ end
546
+
547
+ Contract C::None => Fixnum
548
+ def clever_next_day!
549
+ return clever_next_month! if day == 31
550
+ self.day += 1
551
+ end
552
+
553
+ Contract C::None => Fixnum
554
+ def clever_next_month!
555
+ return next_year! if month == 12
556
+ self.month += 1
557
+ self.day = 1
558
+ end
559
+
560
+ Contract C::None => Fixnum
561
+ def next_year!
562
+ self.month = 1
563
+ self.day = 1
564
+ end
565
+ end
566
+
567
+ class SingletonClassExample
568
+ # This turned out to be required line here to make singleton classes
569
+ # work properly under all platforms. Not sure if it worth trying to
570
+ # do something with it.
571
+ include Contracts::Core
572
+
573
+ class << self
574
+ Contract String => String
575
+ def hoge(str)
576
+ "super#{str}"
577
+ end
578
+
579
+ Contract C::Num, C::Num => C::Num
580
+ def add(a, b)
581
+ a + b
582
+ end
583
+ end
584
+ end
585
+
586
+ with_enabled_no_contracts do
587
+ class NoContractsSimpleExample
588
+ include Contracts::Core
589
+
590
+ Contract String => nil
591
+ def some_method(x)
592
+ nil
593
+ end
594
+ end
595
+
596
+ class NoContractsInvariantsExample
597
+ include Contracts::Core
598
+ include Contracts::Invariants
599
+
600
+ attr_accessor :day
601
+
602
+ invariant(:day_rule) { 1 <= day && day <= 7 }
603
+
604
+ Contract C::None => nil
605
+ def next_day
606
+ self.day += 1
607
+ end
608
+ end
609
+
610
+ class NoContractsPatternMatchingExample
611
+ include Contracts::Core
612
+
613
+ Contract 200, String => String
614
+ def on_response(status, body)
615
+ body + "!"
616
+ end
617
+
618
+ Contract Fixnum, String => String
619
+ def on_response(status, body)
620
+ "error #{status}: #{body}"
621
+ end
622
+ end
623
+ end
624
+
625
+ module ModuleExample
626
+ include Contracts::Core
627
+
628
+ Contract C::Num, C::Num => C::Num
629
+ def plus(a, b)
630
+ a + b
631
+ end
632
+
633
+ Contract String => String
634
+ def self.hoge(str)
635
+ "super#{str}"
636
+ end
637
+
638
+ class << self
639
+ Contract String => nil
640
+ def eat(food)
641
+ # yummy
642
+ nil
643
+ end
644
+ end
645
+ end
646
+
647
+ class KlassWithModuleExample
648
+ include ModuleExample
649
+ end
650
+
651
+ class SingletonInheritanceExample
652
+ include Contracts::Core
653
+
654
+ Contract C::Any => C::Any
655
+ def self.a_contracted_self
656
+ self
657
+ end
658
+ end
659
+
660
+ class SingletonInheritanceExampleSubclass < SingletonInheritanceExample
661
+ class << self
662
+ Contract Integer => Integer
663
+ def num(int)
664
+ int
665
+ end
666
+ end
667
+ end
668
+
669
+ class BareOptionalContractUsed
670
+ include Contracts::Core
671
+
672
+ Contract C::Num, C::Optional[C::Num] => nil
673
+ def something(a, b)
674
+ nil
675
+ end
676
+ end
677
+
678
+ module ModuleContractExample
679
+ include Contracts::Core
680
+
681
+ module AModule
682
+ end
683
+
684
+ module AnotherModule
685
+ end
686
+
687
+ module InheritedModule
688
+ include AModule
689
+ end
690
+
691
+ class AClassWithModule
692
+ include AModule
693
+ end
694
+
695
+ class AClassWithoutModule
696
+ end
697
+
698
+ class AClassWithAnotherModule
699
+ include AnotherModule
700
+ end
701
+
702
+ class AClassWithInheritedModule
703
+ include InheritedModule
704
+ end
705
+
706
+ class AClassWithBothModules
707
+ include AModule
708
+ include AnotherModule
709
+ end
710
+
711
+ Contract AModule => Symbol
712
+ def self.hello(thing)
713
+ :world
714
+ end
715
+ end
716
+
717
+ module ModuleWithContracts
718
+ def self.included(base)
719
+ base.extend ClassMethods
720
+ end
721
+
722
+ module ClassMethods
723
+ include Contracts::Core
724
+
725
+ Contract C::None => String
726
+ def foo
727
+ "bar"
728
+ end
729
+ end
730
+ end
@@ -0,0 +1,17 @@
1
+ module Contracts
2
+ RSpec.describe Invariants do
3
+ def new_subject
4
+ MyBirthday.new(31, 12)
5
+ end
6
+
7
+ it "works when all invariants are holding" do
8
+ expect { new_subject.clever_next_day! }.not_to raise_error
9
+ expect { new_subject.clever_next_month! }.not_to raise_error
10
+ end
11
+
12
+ it "raises invariant violation error when any of invariants are not holding" do
13
+ expect { new_subject.silly_next_day! }.to raise_error(InvariantError, /day condition to be true/)
14
+ expect { new_subject.silly_next_month! }.to raise_error(InvariantError, /month condition to be true/)
15
+ end
16
+ end
17
+ end