entitlements-app 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,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