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