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,281 @@
1
+ require "contracts/attrs"
2
+ require "contracts/builtin_contracts"
3
+ require "contracts/decorators"
4
+ require "contracts/errors"
5
+ require "contracts/formatters"
6
+ require "contracts/invariants"
7
+ require "contracts/method_reference"
8
+ require "contracts/support"
9
+ require "contracts/engine"
10
+ require "contracts/method_handler"
11
+ require "contracts/validators"
12
+ require "contracts/call_with"
13
+ require "contracts/core"
14
+
15
+ module Contracts
16
+ def self.included(base)
17
+ base.send(:include, Core)
18
+ end
19
+
20
+ def self.extended(base)
21
+ base.send(:extend, Core)
22
+ end
23
+ end
24
+
25
+ # This is the main Contract class. When you write a new contract, you'll
26
+ # write it as:
27
+ #
28
+ # Contract [contract names] => return_value
29
+ #
30
+ # This class also provides useful callbacks and a validation method.
31
+ #
32
+ # For #make_validator and related logic see file
33
+ # lib/contracts/validators.rb
34
+ # For #call_with and related logic see file
35
+ # lib/contracts/call_with.rb
36
+ class Contract < Contracts::Decorator
37
+ extend Contracts::Validators
38
+ include Contracts::CallWith
39
+
40
+ # Default implementation of failure_callback. Provided as a block to be able
41
+ # to monkey patch #failure_callback only temporary and then switch it back.
42
+ # First important usage - for specs.
43
+ DEFAULT_FAILURE_CALLBACK = proc do |data|
44
+ if data[:return_value]
45
+ # this failed on the return contract
46
+ fail ReturnContractError.new(failure_msg(data), data)
47
+ else
48
+ # this failed for a param contract
49
+ fail data[:contracts].failure_exception.new(failure_msg(data), data)
50
+ end
51
+ end
52
+
53
+ attr_reader :args_contracts, :ret_contract, :klass, :method
54
+ def initialize(klass, method, *contracts)
55
+ unless contracts.last.is_a?(Hash)
56
+ unless contracts.one?
57
+ fail %{
58
+ It looks like your contract for #{method.name} doesn't have a return
59
+ value. A contract should be written as `Contract arg1, arg2 =>
60
+ return_value`.
61
+ }.strip
62
+ end
63
+ contracts = [nil => contracts[-1]]
64
+ end
65
+
66
+ # internally we just convert that return value syntax back to an array
67
+ @args_contracts = contracts[0, contracts.size - 1] + contracts[-1].keys
68
+
69
+ @ret_contract = contracts[-1].values[0]
70
+
71
+ @args_validators = args_contracts.map do |contract|
72
+ Contract.make_validator(contract)
73
+ end
74
+
75
+ @args_contract_index = args_contracts.index do |contract|
76
+ contract.is_a? Contracts::Args
77
+ end
78
+
79
+ @ret_validator = Contract.make_validator(ret_contract)
80
+
81
+ @pattern_match = false
82
+
83
+ # == @has_proc_contract
84
+ last_contract = args_contracts.last
85
+ is_a_proc = last_contract.is_a?(Class) && (last_contract <= Proc || last_contract <= Method)
86
+ maybe_a_proc = last_contract.is_a?(Contracts::Maybe) && last_contract.include_proc?
87
+
88
+ @has_proc_contract = is_a_proc || maybe_a_proc || last_contract.is_a?(Contracts::Func)
89
+
90
+ # ====
91
+
92
+ # == @has_options_contract
93
+ last_contract = args_contracts.last
94
+ penultimate_contract = args_contracts[-2]
95
+ @has_options_contract = if @has_proc_contract
96
+ penultimate_contract.is_a?(Hash) || penultimate_contract.is_a?(Contracts::Builtin::KeywordArgs)
97
+ else
98
+ last_contract.is_a?(Hash) || last_contract.is_a?(Contracts::Builtin::KeywordArgs)
99
+ end
100
+ # ===
101
+
102
+ @klass, @method = klass, method
103
+ end
104
+
105
+ def pretty_contract c
106
+ c.is_a?(Class) ? c.name : c.class.name
107
+ end
108
+
109
+ def to_s
110
+ args = args_contracts.map { |c| pretty_contract(c) }.join(", ")
111
+ ret = pretty_contract(ret_contract)
112
+ ("#{args} => #{ret}").gsub("Contracts::Builtin::", "")
113
+ end
114
+
115
+ # Given a hash, prints out a failure message.
116
+ # This function is used by the default #failure_callback method
117
+ # and uses the hash passed into the failure_callback method.
118
+ def self.failure_msg(data)
119
+ indent_amount = 8
120
+ method_name = Contracts::Support.method_name(data[:method])
121
+
122
+ # Header
123
+ header = if data[:return_value]
124
+ "Contract violation for return value:"
125
+ else
126
+ "Contract violation for argument #{data[:arg_pos]} of #{data[:total_args]}:"
127
+ end
128
+
129
+ # Expected
130
+ expected_prefix = "Expected: "
131
+ expected_value = Contracts::Support.indent_string(
132
+ Contracts::Formatters::Expected.new(data[:contract]).contract.pretty_inspect,
133
+ expected_prefix.length
134
+ ).strip
135
+ expected_line = expected_prefix + expected_value + ","
136
+
137
+ # Actual
138
+ actual_prefix = "Actual: "
139
+ actual_value = Contracts::Support.indent_string(
140
+ data[:arg].pretty_inspect,
141
+ actual_prefix.length
142
+ ).strip
143
+ actual_line = actual_prefix + actual_value
144
+
145
+ # Value guarded in
146
+ value_prefix = "Value guarded in: "
147
+ value_value = "#{data[:class]}::#{method_name}"
148
+ value_line = value_prefix + value_value
149
+
150
+ # Contract
151
+ contract_prefix = "With Contract: "
152
+ contract_value = data[:contracts].to_s
153
+ contract_line = contract_prefix + contract_value
154
+
155
+ # Position
156
+ position_prefix = "At: "
157
+ position_value = Contracts::Support.method_position(data[:method])
158
+ position_line = position_prefix + position_value
159
+
160
+ header +
161
+ "\n" +
162
+ Contracts::Support.indent_string(
163
+ [expected_line,
164
+ actual_line,
165
+ value_line,
166
+ contract_line,
167
+ position_line].join("\n"),
168
+ indent_amount
169
+ )
170
+ end
171
+
172
+ # Callback for when a contract fails. By default it raises
173
+ # an error and prints detailed info about the contract that
174
+ # failed. You can also monkeypatch this callback to do whatever
175
+ # you want...log the error, send you an email, print an error
176
+ # message, etc.
177
+ #
178
+ # Example of monkeypatching:
179
+ #
180
+ # def Contract.failure_callback(data)
181
+ # puts "You had an error!"
182
+ # puts failure_msg(data)
183
+ # exit
184
+ # end
185
+ def self.failure_callback(data, use_pattern_matching = true)
186
+ if data[:contracts].pattern_match? && use_pattern_matching
187
+ return DEFAULT_FAILURE_CALLBACK.call(data)
188
+ end
189
+
190
+ fetch_failure_callback.call(data)
191
+ end
192
+
193
+ # Used to override failure_callback without monkeypatching.
194
+ #
195
+ # Takes: block parameter, that should accept one argument - data.
196
+ #
197
+ # Example usage:
198
+ #
199
+ # Contract.override_failure_callback do |data|
200
+ # puts "You had an error"
201
+ # puts failure_msg(data)
202
+ # exit
203
+ # end
204
+ def self.override_failure_callback(&blk)
205
+ @failure_callback = blk
206
+ end
207
+
208
+ # Used to restore default failure callback
209
+ def self.restore_failure_callback
210
+ @failure_callback = DEFAULT_FAILURE_CALLBACK
211
+ end
212
+
213
+ def self.fetch_failure_callback
214
+ @failure_callback ||= DEFAULT_FAILURE_CALLBACK
215
+ end
216
+
217
+ # Used to verify if an argument satisfies a contract.
218
+ #
219
+ # Takes: an argument and a contract.
220
+ #
221
+ # Returns: a tuple: [Boolean, metadata]. The boolean indicates
222
+ # whether the contract was valid or not. If it wasn't, metadata
223
+ # contains some useful information about the failure.
224
+ def self.valid?(arg, contract)
225
+ make_validator(contract)[arg]
226
+ end
227
+
228
+ def [](*args, &blk)
229
+ call(*args, &blk)
230
+ end
231
+
232
+ def call(*args, &blk)
233
+ call_with(nil, *args, &blk)
234
+ end
235
+
236
+ # if we specified a proc in the contract but didn't pass one in,
237
+ # it's possible we are going to pass in a block instead. So lets
238
+ # append a nil to the list of args just so it doesn't fail.
239
+
240
+ # a better way to handle this might be to take this into account
241
+ # before throwing a "mismatched # of args" error.
242
+ # returns true if it appended nil
243
+ def maybe_append_block! args, blk
244
+ return false unless @has_proc_contract && !blk &&
245
+ (@args_contract_index || args.size < args_contracts.size)
246
+ args << nil
247
+ true
248
+ end
249
+
250
+ # Same thing for when we have named params but didn't pass any in.
251
+ # returns true if it appended nil
252
+ def maybe_append_options! args, blk
253
+ return false unless @has_options_contract
254
+ if @has_proc_contract && (args_contracts[-2].is_a?(Hash) || args_contracts[-2].is_a?(Contracts::Builtin::KeywordArgs)) && !args[-2].is_a?(Hash)
255
+ args.insert(-2, {})
256
+ elsif (args_contracts[-1].is_a?(Hash) || args_contracts[-1].is_a?(Contracts::Builtin::KeywordArgs)) && !args[-1].is_a?(Hash)
257
+ args << {}
258
+ end
259
+ true
260
+ end
261
+
262
+ # Used to determine type of failure exception this contract should raise in case of failure
263
+ def failure_exception
264
+ if pattern_match?
265
+ PatternMatchingError
266
+ else
267
+ ParamContractError
268
+ end
269
+ end
270
+
271
+ # @private
272
+ # Used internally to mark contract as pattern matching contract
273
+ def pattern_match!
274
+ @pattern_match = true
275
+ end
276
+
277
+ # Used to determine if contract is a pattern matching contract
278
+ def pattern_match?
279
+ @pattern_match == true
280
+ end
281
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+
3
+ relish push contracts/contracts-ruby
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+
3
+ relish push contracts-staging/contracts-ruby
@@ -0,0 +1,5 @@
1
+ if RUBY_VERSION.to_f == 2.1
2
+ puts "running rubocop..."
3
+ puts `bundle exec rubocop #{ARGV.join(" ")} -D`
4
+ exit $?.exitstatus
5
+ end
@@ -0,0 +1,119 @@
1
+ RSpec.describe "Contracts:" do
2
+ describe "Attrs:" do
3
+ class Person
4
+ include Contracts::Core
5
+ include Contracts::Attrs
6
+ include Contracts::Builtin
7
+
8
+ def initialize(name)
9
+ @name_r = name
10
+ @name_w = name
11
+ @name_rw = name
12
+
13
+ @name_r_2 = name
14
+ @name_w_2 = name
15
+ @name_rw_2 = name
16
+ end
17
+
18
+ attr_reader_with_contract :name_r, :name_r_2, String
19
+ attr_writer_with_contract :name_w, :name_w_2, String
20
+ attr_accessor_with_contract :name_rw, :name_rw_2, String
21
+ end
22
+
23
+ context "attr_reader_with_contract" do
24
+ it "getting valid type" do
25
+ expect(Person.new("bob").name_r)
26
+ .to(eq("bob"))
27
+ end
28
+
29
+ it "getting invalid type" do
30
+ expect { Person.new(1.3).name_r }
31
+ .to(raise_error(ReturnContractError))
32
+ end
33
+
34
+ it "getting valid type for second val" do
35
+ expect(Person.new("bob").name_r_2)
36
+ .to(eq("bob"))
37
+ end
38
+
39
+ it "getting invalid type for second val" do
40
+ expect { Person.new(1.3).name_r_2 }
41
+ .to(raise_error(ReturnContractError))
42
+ end
43
+
44
+ it "setting" do
45
+ expect { Person.new("bob").name_r = "alice" }
46
+ .to(raise_error(NoMethodError))
47
+ end
48
+ end
49
+
50
+ context "attr_writer_with_contract" do
51
+ it "getting" do
52
+ expect { Person.new("bob").name_w }
53
+ .to(raise_error(NoMethodError))
54
+ end
55
+
56
+ it "setting valid type" do
57
+ expect(Person.new("bob").name_w = "alice")
58
+ .to(eq("alice"))
59
+ end
60
+
61
+ it "setting invalid type" do
62
+ expect { Person.new("bob").name_w = 1.2 }
63
+ .to(raise_error(ParamContractError))
64
+ end
65
+
66
+ it "setting valid type for second val" do
67
+ expect(Person.new("bob").name_w_2 = "alice")
68
+ .to(eq("alice"))
69
+ end
70
+
71
+ it "setting invalid type for second val" do
72
+ expect { Person.new("bob").name_w_2 = 1.2 }
73
+ .to(raise_error(ParamContractError))
74
+ end
75
+ end
76
+
77
+ context "attr_accessor_with_contract" do
78
+ it "getting valid type" do
79
+ expect(Person.new("bob").name_rw)
80
+ .to(eq("bob"))
81
+ end
82
+
83
+ it "getting invalid type" do
84
+ expect { Person.new(1.2).name_rw }
85
+ .to(raise_error(ReturnContractError))
86
+ end
87
+
88
+ it "setting valid type" do
89
+ expect(Person.new("bob").name_rw = "alice")
90
+ .to(eq("alice"))
91
+ end
92
+
93
+ it "setting invalid type" do
94
+ expect { Person.new("bob").name_rw = 1.2 }
95
+ .to(raise_error(ParamContractError))
96
+ end
97
+
98
+ it "getting valid type for second val" do
99
+ expect(Person.new("bob").name_rw_2)
100
+ .to(eq("bob"))
101
+ end
102
+
103
+ it "getting invalid type for second val" do
104
+ expect { Person.new(1.2).name_rw_2 }
105
+ .to(raise_error(ReturnContractError))
106
+ end
107
+
108
+ it "setting valid type for second val" do
109
+ expect(Person.new("bob").name_rw_2 = "alice")
110
+ .to(eq("alice"))
111
+ end
112
+
113
+ it "setting invalid type for second val" do
114
+ expect { Person.new("bob").name_rw_2 = 1.2 }
115
+ .to(raise_error(ParamContractError))
116
+ end
117
+ end
118
+ end
119
+ end