entitlements 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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