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,461 @@
1
+ RSpec.describe "Contracts:" do
2
+ before :all do
3
+ @o = GenericExample.new
4
+ end
5
+
6
+ def fails(&some)
7
+ expect { some.call }.to raise_error(ContractError)
8
+ end
9
+
10
+ def passes(&some)
11
+ expect { some.call }.to_not raise_error
12
+ end
13
+
14
+ describe "DescendantOf:" do
15
+ it "should pass for Array" do
16
+ passes { @o.enumerable_descendant_test(Array) }
17
+ end
18
+
19
+ it "should pass for a hash" do
20
+ passes { @o.enumerable_descendant_test(Hash) }
21
+ end
22
+
23
+ it "should fail for a number class" do
24
+ fails { @o.enumerable_descendant_test(Integer) }
25
+ end
26
+
27
+ it "should fail for a non-class" do
28
+ fails { @o.enumerable_descendant_test(1) }
29
+ end
30
+ end
31
+
32
+ describe "Num:" do
33
+ it "should pass for Fixnums" do
34
+ passes { @o.double(2) }
35
+ end
36
+
37
+ it "should pass for Floats" do
38
+ passes { @o.double(2.2) }
39
+ end
40
+
41
+ it "should fail for nil and other data types" do
42
+ fails { @o.double(nil) }
43
+ fails { @o.double(:x) }
44
+ fails { @o.double("x") }
45
+ fails { @o.double(/x/) }
46
+ end
47
+ end
48
+
49
+ describe "Pos:" do
50
+ it "should pass for positive numbers" do
51
+ passes { @o.pos_test(1) }
52
+ passes { @o.pos_test(1.6) }
53
+ end
54
+
55
+ it "should fail for 0" do
56
+ fails { @o.pos_test(0) }
57
+ end
58
+
59
+ it "should fail for negative numbers" do
60
+ fails { @o.pos_test(-1) }
61
+ fails { @o.pos_test(-1.6) }
62
+ end
63
+
64
+ it "should fail for nil and other data types" do
65
+ fails { @o.pos_test(nil) }
66
+ fails { @o.pos_test(:x) }
67
+ fails { @o.pos_test("x") }
68
+ fails { @o.pos_test(/x/) }
69
+ end
70
+ end
71
+
72
+ describe "Neg:" do
73
+ it "should pass for negative numbers" do
74
+ passes { @o.neg_test(-1) }
75
+ passes { @o.neg_test(-1.6) }
76
+ end
77
+
78
+ it "should fail for 0" do
79
+ fails { @o.neg_test(0) }
80
+ end
81
+
82
+ it "should fail for positive numbers" do
83
+ fails { @o.neg_test(1) }
84
+ fails { @o.neg_test(1.6) }
85
+ end
86
+
87
+ it "should fail for nil and other data types" do
88
+ fails { @o.neg_test(nil) }
89
+ fails { @o.neg_test(:x) }
90
+ fails { @o.neg_test("x") }
91
+ fails { @o.neg_test(/x/) }
92
+ end
93
+ end
94
+
95
+ describe "Nat:" do
96
+ it "should pass for 0" do
97
+ passes { @o.nat_test(0) }
98
+ end
99
+
100
+ it "should pass for positive whole numbers" do
101
+ passes { @o.nat_test(1) }
102
+ end
103
+
104
+ it "should fail for positive non-whole numbers" do
105
+ fails { @o.nat_test(1.5) }
106
+ end
107
+
108
+ it "should fail for negative numbers" do
109
+ fails { @o.nat_test(-1) }
110
+ fails { @o.nat_test(-1.6) }
111
+ end
112
+
113
+ it "should fail for nil and other data types" do
114
+ fails { @o.nat_test(nil) }
115
+ fails { @o.nat_test(:x) }
116
+ fails { @o.nat_test("x") }
117
+ fails { @o.nat_test(/x/) }
118
+ end
119
+ end
120
+
121
+ describe "Any:" do
122
+ it "should pass for numbers" do
123
+ passes { @o.show(1) }
124
+ end
125
+ it "should pass for strings" do
126
+ passes { @o.show("bad") }
127
+ end
128
+ it "should pass for procs" do
129
+ passes { @o.show(lambda {}) }
130
+ end
131
+ it "should pass for nil" do
132
+ passes { @o.show(nil) }
133
+ end
134
+ end
135
+
136
+ describe "None:" do
137
+ it "should fail for numbers" do
138
+ fails { @o.fail_all(1) }
139
+ end
140
+ it "should fail for strings" do
141
+ fails { @o.fail_all("bad") }
142
+ end
143
+ it "should fail for procs" do
144
+ fails { @o.fail_all(lambda {}) }
145
+ end
146
+ it "should fail for nil" do
147
+ fails { @o.fail_all(nil) }
148
+ end
149
+ end
150
+
151
+ describe "Or:" do
152
+ it "should pass for nums" do
153
+ passes { @o.num_or_string(1) }
154
+ end
155
+
156
+ it "should pass for strings" do
157
+ passes { @o.num_or_string("bad") }
158
+ end
159
+
160
+ it "should fail for nil" do
161
+ fails { @o.num_or_string(nil) }
162
+ end
163
+ end
164
+
165
+ describe "Xor:" do
166
+ it "should pass for an object with a method :good" do
167
+ passes { @o.xor_test(A.new) }
168
+ end
169
+
170
+ it "should pass for an object with a method :bad" do
171
+ passes { @o.xor_test(B.new) }
172
+ end
173
+
174
+ it "should fail for an object with neither method" do
175
+ fails { @o.xor_test(1) }
176
+ end
177
+
178
+ it "should fail for an object with both methods :good and :bad" do
179
+ fails { @o.xor_test(F.new) }
180
+ end
181
+ end
182
+
183
+ describe "And:" do
184
+ it "should pass for an object of class A that has a method :good" do
185
+ passes { @o.and_test(A.new) }
186
+ end
187
+
188
+ it "should fail for an object that has a method :good but isn't of class A" do
189
+ fails { @o.and_test(F.new) }
190
+ end
191
+ end
192
+
193
+ describe "Enum:" do
194
+ it "should pass for an object that is included" do
195
+ passes { @o.enum_test(:a) }
196
+ end
197
+
198
+ it "should fail for an object that is not included" do
199
+ fails { @o.enum_test(:z) }
200
+ end
201
+ end
202
+
203
+ describe "RespondTo:" do
204
+ it "should pass for an object that responds to :good" do
205
+ passes { @o.responds_test(A.new) }
206
+ end
207
+
208
+ it "should fail for an object that doesn't respond to :good" do
209
+ fails { @o.responds_test(B.new) }
210
+ end
211
+ end
212
+
213
+ describe "Send:" do
214
+ it "should pass for an object that returns true for method :good" do
215
+ passes { @o.send_test(A.new) }
216
+ end
217
+
218
+ it "should fail for an object that returns false for method :good" do
219
+ fails { @o.send_test(F.new) }
220
+ end
221
+ end
222
+
223
+ describe "Exactly:" do
224
+ it "should pass for an object that is exactly a Parent" do
225
+ passes { @o.exactly_test(Parent.new) }
226
+ end
227
+
228
+ it "should fail for an object that inherits from Parent" do
229
+ fails { @o.exactly_test(Child.new) }
230
+ end
231
+
232
+ it "should fail for an object that is not related to Parent at all" do
233
+ fails { @o.exactly_test(A.new) }
234
+ end
235
+ end
236
+
237
+ describe "Eq:" do
238
+ it "should pass for a class" do
239
+ passes { @o.eq_class_test(Foo) }
240
+ end
241
+
242
+ it "should pass for a module" do
243
+ passes { @o.eq_module_test(Bar) }
244
+ end
245
+
246
+ it "should pass for other values" do
247
+ passes { @o.eq_value_test(Baz) }
248
+ end
249
+
250
+ it "should fail when not equal" do
251
+ fails { @o.eq_class_test(Bar) }
252
+ end
253
+
254
+ it "should fail when given instance of class" do
255
+ fails { @o.eq_class_test(Foo.new) }
256
+ end
257
+ end
258
+
259
+ describe "Not:" do
260
+ it "should pass for an argument that isn't nil" do
261
+ passes { @o.not_nil(1) }
262
+ end
263
+
264
+ it "should fail for nil" do
265
+ fails { @o.not_nil(nil) }
266
+ end
267
+ end
268
+
269
+ describe "ArrayOf:" do
270
+ it "should pass for an array of nums" do
271
+ passes { @o.product([1, 2, 3]) }
272
+ end
273
+
274
+ it "should fail for an array with one non-num" do
275
+ fails { @o.product([1, 2, 3, "bad"]) }
276
+ end
277
+
278
+ it "should fail for a non-array" do
279
+ fails { @o.product(1) }
280
+ end
281
+ end
282
+
283
+ describe "RangeOf:" do
284
+ require "date"
285
+ it "should pass for a range of nums" do
286
+ passes { @o.first_in_range_num(3..10) }
287
+ end
288
+
289
+ it "should pass for a range of dates" do
290
+ d1 = Date.today
291
+ d2 = d1 + 18
292
+ passes { @o.first_in_range_date(d1..d2) }
293
+ end
294
+
295
+ it "should fail for a non-range" do
296
+ fails { @o.first_in_range_num("foo") }
297
+ fails { @o.first_in_range_num(:foo) }
298
+ fails { @o.first_in_range_num(5) }
299
+ fails { @o.first_in_range_num(nil) }
300
+ end
301
+
302
+ it "should fail for a range with incorrect data type" do
303
+ fails { @o.first_in_range_num("a".."z") }
304
+ end
305
+
306
+ it "should fail for a badly-defined range" do
307
+ # For some reason, Ruby 2.0.0 allows (date .. number) as a range.
308
+ # Perhaps other Ruby versions do too.
309
+ # Note that (date .. string) gives ArgumentError.
310
+ # This test guards against ranges with inconsistent data types.
311
+ begin
312
+ d1 = Date.today
313
+ fails { @o.first_in_range_date(d1..10) }
314
+ fails { @o.first_in_range_num(d1..10) }
315
+ rescue ArgumentError
316
+ # If Ruby doesn't like the range, we ignore the test.
317
+ :nop
318
+ end
319
+ end
320
+ end
321
+
322
+ describe "SetOf:" do
323
+ it "should pass for a set of nums" do
324
+ passes { @o.product_from_set(Set.new([1, 2, 3])) }
325
+ end
326
+
327
+ it "should fail for an array with one non-num" do
328
+ fails { @o.product_from_set(Set.new([1, 2, 3, "bad"])) }
329
+ end
330
+
331
+ it "should fail for a non-array" do
332
+ fails { @o.product_from_set(1) }
333
+ end
334
+ end
335
+
336
+ describe "Bool:" do
337
+ it "should pass for an argument that is a boolean" do
338
+ passes { @o.bool_test(true) }
339
+ passes { @o.bool_test(false) }
340
+ end
341
+
342
+ it "should fail for nil" do
343
+ fails { @o.bool_test(nil) }
344
+ end
345
+ end
346
+
347
+ describe "Maybe:" do
348
+ it "should pass for nums" do
349
+ expect(@o.maybe_double(1)).to eq(2)
350
+ end
351
+
352
+ it "should pass for nils" do
353
+ expect(@o.maybe_double(nil)).to eq(nil)
354
+ end
355
+
356
+ it "should fail for strings" do
357
+ fails { @o.maybe_double("foo") }
358
+ end
359
+ end
360
+
361
+ describe "KeywordArgs:" do
362
+ it "should pass for exact correct input" do
363
+ passes { @o.person_keywordargs(:name => "calvin", :age => 10) }
364
+ end
365
+
366
+ it "should fail if some keys don't have contracts" do
367
+ fails { @o.person_keywordargs(:name => "calvin", :age => 10, :foo => "bar") }
368
+ end
369
+
370
+ it "should fail if a key with a contract on it isn't provided" do
371
+ fails { @o.person_keywordargs(:name => "calvin") }
372
+ end
373
+
374
+ it "should fail for incorrect input" do
375
+ fails { @o.person_keywordargs(:name => 50, :age => 10) }
376
+ fails { @o.hash_keywordargs(:hash => nil) }
377
+ fails { @o.hash_keywordargs(:hash => 1) }
378
+ end
379
+
380
+ it "should pass if a method is overloaded with non-KeywordArgs" do
381
+ passes { @o.person_keywordargs("name", 10) }
382
+ end
383
+ end
384
+
385
+ describe "Optional:" do
386
+ it "can't be used outside of KeywordArgs" do
387
+ expect do
388
+ BareOptionalContractUsed.new.something(3, 5)
389
+ end.to raise_error(ArgumentError, Contracts::Optional::UNABLE_TO_USE_OUTSIDE_OF_OPT_HASH)
390
+ end
391
+ end
392
+
393
+ describe "HashOf:" do
394
+ it "doesn't allow to specify multiple key-value pairs with pretty syntax" do
395
+ expect do
396
+ Class.new do
397
+ include Contracts::Core
398
+
399
+ Contract Contracts::HashOf[Symbol => String, Contracts::Num => Contracts::Num] => nil
400
+ def something(hash)
401
+ # ...
402
+ end
403
+ end
404
+ end.to raise_error(ArgumentError, "You should provide only one key-value pair to HashOf contract")
405
+ end
406
+
407
+ context "given a fulfilled contract" do
408
+ it { expect(@o.gives_max_value(:panda => 1, :bamboo => 2)).to eq(2) }
409
+ it { expect(@o.pretty_gives_max_value(:panda => 1, :bamboo => 2)).to eq(2) }
410
+ end
411
+
412
+ context "given an unfulfilled contract" do
413
+ it { fails { @o.gives_max_value(:panda => "1", :bamboo => "2") } }
414
+ it { fails { @o.gives_max_value(nil) } }
415
+ it { fails { @o.gives_max_value(1) } }
416
+ it { fails { @o.pretty_gives_max_value(:panda => "1", :bamboo => "2") } }
417
+ end
418
+
419
+ describe "#to_s" do
420
+ context "given Symbol => String" do
421
+ it { expect(Contracts::HashOf[Symbol, String].to_s).to eq("Hash<Symbol, String>") }
422
+ end
423
+
424
+ context "given String => Num" do
425
+ it { expect(Contracts::HashOf[String, Contracts::Num].to_s).to eq("Hash<String, Contracts::Builtin::Num>") }
426
+ end
427
+ end
428
+ end
429
+
430
+ describe "StrictHash:" do
431
+ context "when given an exact correct input" do
432
+ it "does not raise an error" do
433
+ passes { @o.strict_person(:name => "calvin", :age => 10) }
434
+ end
435
+ end
436
+
437
+ context "when given an input with correct keys but wrong types" do
438
+ it "raises an error" do
439
+ fails { @o.strict_person(:name => "calvin", :age => "10") }
440
+ end
441
+ end
442
+
443
+ context "when given an input with missing keys" do
444
+ it "raises an error" do
445
+ fails { @o.strict_person(:name => "calvin") }
446
+ end
447
+ end
448
+
449
+ context "when given an input with extra keys" do
450
+ it "raises an error" do
451
+ fails { @o.strict_person(:name => "calvin", :age => 10, :soft => true) }
452
+ end
453
+ end
454
+
455
+ context "when given not a hash" do
456
+ it "raises an error" do
457
+ fails { @o.strict_person(1337) }
458
+ end
459
+ end
460
+ end
461
+ end