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