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,457 @@
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
+ end
380
+
381
+ describe "Optional:" do
382
+ it "can't be used outside of KeywordArgs" do
383
+ expect do
384
+ BareOptionalContractUsed.new.something(3, 5)
385
+ end.to raise_error(ArgumentError, Contracts::Optional::UNABLE_TO_USE_OUTSIDE_OF_OPT_HASH)
386
+ end
387
+ end
388
+
389
+ describe "HashOf:" do
390
+ it "doesn't allow to specify multiple key-value pairs with pretty syntax" do
391
+ expect do
392
+ Class.new do
393
+ include Contracts::Core
394
+
395
+ Contract Contracts::HashOf[Symbol => String, Contracts::Num => Contracts::Num] => nil
396
+ def something(hash)
397
+ # ...
398
+ end
399
+ end
400
+ end.to raise_error(ArgumentError, "You should provide only one key-value pair to HashOf contract")
401
+ end
402
+
403
+ context "given a fulfilled contract" do
404
+ it { expect(@o.gives_max_value({ :panda => 1, :bamboo => 2 })).to eq(2) }
405
+ it { expect(@o.pretty_gives_max_value({ :panda => 1, :bamboo => 2 })).to eq(2) }
406
+ end
407
+
408
+ context "given an unfulfilled contract" do
409
+ it { fails { @o.gives_max_value({ :panda => "1", :bamboo => "2" }) } }
410
+ it { fails { @o.gives_max_value(nil) } }
411
+ it { fails { @o.gives_max_value(1) } }
412
+ it { fails { @o.pretty_gives_max_value({ :panda => "1", :bamboo => "2" }) } }
413
+ end
414
+
415
+ describe "#to_s" do
416
+ context "given Symbol => String" do
417
+ it { expect(Contracts::HashOf[Symbol, String].to_s).to eq("Hash<Symbol, String>") }
418
+ end
419
+
420
+ context "given String => Num" do
421
+ it { expect(Contracts::HashOf[String, Contracts::Num].to_s).to eq("Hash<String, Contracts::Builtin::Num>") }
422
+ end
423
+ end
424
+ end
425
+
426
+ describe "StrictHash:" do
427
+ context "when given an exact correct input" do
428
+ it "does not raise an error" do
429
+ passes { @o.strict_person({ :name => "calvin", :age => 10 }) }
430
+ end
431
+ end
432
+
433
+ context "when given an input with correct keys but wrong types" do
434
+ it "raises an error" do
435
+ fails { @o.strict_person({ :name => "calvin", :age => "10" }) }
436
+ end
437
+ end
438
+
439
+ context "when given an input with missing keys" do
440
+ it "raises an error" do
441
+ fails { @o.strict_person({ :name => "calvin" }) }
442
+ end
443
+ end
444
+
445
+ context "when given an input with extra keys" do
446
+ it "raises an error" do
447
+ fails { @o.strict_person({ :name => "calvin", :age => 10, :soft => true }) }
448
+ end
449
+ end
450
+
451
+ context "when given not a hash" do
452
+ it "raises an error" do
453
+ fails { @o.strict_person(1337) }
454
+ end
455
+ end
456
+ end
457
+ end