ree 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +21 -0
- data/README.md +474 -0
- data/Rakefile +8 -0
- data/bin/console +8 -0
- data/bin/setup +8 -0
- data/exe/ree +264 -0
- data/lib/ree/args.rb +34 -0
- data/lib/ree/bean_dsl.rb +24 -0
- data/lib/ree/cli/generate_package.rb +18 -0
- data/lib/ree/cli/generate_package_schema.rb +54 -0
- data/lib/ree/cli/generate_packages_schema.rb +17 -0
- data/lib/ree/cli/generate_template.rb +20 -0
- data/lib/ree/cli/init.rb +22 -0
- data/lib/ree/cli/spec_runner.rb +184 -0
- data/lib/ree/cli.rb +12 -0
- data/lib/ree/container.rb +67 -0
- data/lib/ree/contracts/arg_contracts/any.rb +15 -0
- data/lib/ree/contracts/arg_contracts/array_of.rb +52 -0
- data/lib/ree/contracts/arg_contracts/block.rb +15 -0
- data/lib/ree/contracts/arg_contracts/bool.rb +21 -0
- data/lib/ree/contracts/arg_contracts/eq.rb +28 -0
- data/lib/ree/contracts/arg_contracts/exactly.rb +28 -0
- data/lib/ree/contracts/arg_contracts/hash_of.rb +59 -0
- data/lib/ree/contracts/arg_contracts/ksplat.rb +141 -0
- data/lib/ree/contracts/arg_contracts/kwargs.rb +22 -0
- data/lib/ree/contracts/arg_contracts/nilor.rb +16 -0
- data/lib/ree/contracts/arg_contracts/none.rb +15 -0
- data/lib/ree/contracts/arg_contracts/optblock.rb +11 -0
- data/lib/ree/contracts/arg_contracts/or.rb +30 -0
- data/lib/ree/contracts/arg_contracts/range_of.rb +51 -0
- data/lib/ree/contracts/arg_contracts/set_of.rb +54 -0
- data/lib/ree/contracts/arg_contracts/splat.rb +297 -0
- data/lib/ree/contracts/arg_contracts/splat_of.rb +64 -0
- data/lib/ree/contracts/arg_contracts/squarable.rb +11 -0
- data/lib/ree/contracts/arg_contracts/subclass_of.rb +28 -0
- data/lib/ree/contracts/arg_contracts.rb +29 -0
- data/lib/ree/contracts/called_args_validator.rb +291 -0
- data/lib/ree/contracts/contract_definition.rb +142 -0
- data/lib/ree/contracts/contractable.rb +34 -0
- data/lib/ree/contracts/core.rb +17 -0
- data/lib/ree/contracts/engine.rb +71 -0
- data/lib/ree/contracts/engine_proxy.rb +13 -0
- data/lib/ree/contracts/errors/bad_contract_error.rb +4 -0
- data/lib/ree/contracts/errors/contract_error.rb +4 -0
- data/lib/ree/contracts/errors/error.rb +4 -0
- data/lib/ree/contracts/errors/return_contract_error.rb +4 -0
- data/lib/ree/contracts/method_decorator.rb +158 -0
- data/lib/ree/contracts/truncatable.rb +9 -0
- data/lib/ree/contracts/utils.rb +9 -0
- data/lib/ree/contracts/validators/array_validator.rb +51 -0
- data/lib/ree/contracts/validators/base_validator.rb +27 -0
- data/lib/ree/contracts/validators/class_validator.rb +17 -0
- data/lib/ree/contracts/validators/default_validator.rb +20 -0
- data/lib/ree/contracts/validators/hash_validator.rb +100 -0
- data/lib/ree/contracts/validators/proc_validator.rb +17 -0
- data/lib/ree/contracts/validators/range_validator.rb +17 -0
- data/lib/ree/contracts/validators/regexp_validator.rb +17 -0
- data/lib/ree/contracts/validators/valid_validator.rb +28 -0
- data/lib/ree/contracts/validators.rb +42 -0
- data/lib/ree/contracts.rb +45 -0
- data/lib/ree/core/link_validator.rb +42 -0
- data/lib/ree/core/object.rb +132 -0
- data/lib/ree/core/object_error.rb +9 -0
- data/lib/ree/core/object_link.rb +21 -0
- data/lib/ree/core/object_schema.rb +47 -0
- data/lib/ree/core/object_schema_builder.rb +110 -0
- data/lib/ree/core/package.rb +177 -0
- data/lib/ree/core/package_dep.rb +9 -0
- data/lib/ree/core/package_env_var.rb +12 -0
- data/lib/ree/core/package_loader.rb +95 -0
- data/lib/ree/core/package_schema.rb +27 -0
- data/lib/ree/core/package_schema_builder.rb +53 -0
- data/lib/ree/core/package_schema_loader.rb +170 -0
- data/lib/ree/core/packages_detector.rb +43 -0
- data/lib/ree/core/packages_schema.rb +19 -0
- data/lib/ree/core/packages_schema_builder.rb +50 -0
- data/lib/ree/core/packages_schema_loader.rb +95 -0
- data/lib/ree/core/packages_schema_locator.rb +27 -0
- data/lib/ree/core/packages_store.rb +32 -0
- data/lib/ree/core/path_helper.rb +104 -0
- data/lib/ree/dsl/build_package_dsl.rb +155 -0
- data/lib/ree/dsl/domain_error.rb +4 -0
- data/lib/ree/dsl/error_builder.rb +39 -0
- data/lib/ree/dsl/error_dsl.rb +27 -0
- data/lib/ree/dsl/import_dsl.rb +106 -0
- data/lib/ree/dsl/link_import_builder.rb +66 -0
- data/lib/ree/dsl/object_dsl.rb +319 -0
- data/lib/ree/dsl/object_hooks.rb +6 -0
- data/lib/ree/dsl/package_require.rb +44 -0
- data/lib/ree/error.rb +11 -0
- data/lib/ree/facades/packages_facade.rb +197 -0
- data/lib/ree/fn_dsl.rb +24 -0
- data/lib/ree/gen/init.rb +64 -0
- data/lib/ree/gen/package.rb +56 -0
- data/lib/ree/gen.rb +8 -0
- data/lib/ree/handlers/template_handler.rb +118 -0
- data/lib/ree/link_dsl.rb +175 -0
- data/lib/ree/object_compiler.rb +149 -0
- data/lib/ree/package_dsl.rb +34 -0
- data/lib/ree/rspec_link_dsl.rb +19 -0
- data/lib/ree/spec_runner/command_generator.rb +49 -0
- data/lib/ree/spec_runner/command_params.rb +9 -0
- data/lib/ree/spec_runner/runner.rb +200 -0
- data/lib/ree/spec_runner/spec_filename_matcher.rb +27 -0
- data/lib/ree/spec_runner/view.rb +30 -0
- data/lib/ree/spec_runner.rb +11 -0
- data/lib/ree/templates/init/.gitignore +1 -0
- data/lib/ree/templates/init/.irbrc +13 -0
- data/lib/ree/templates/init/.rspec +3 -0
- data/lib/ree/templates/init/.ruby-version +1 -0
- data/lib/ree/templates/init/Gemfile +7 -0
- data/lib/ree/templates/init/Packages.schema.json +1 -0
- data/lib/ree/templates/init/bin/console +5 -0
- data/lib/ree/templates/init/readme.md +2 -0
- data/lib/ree/templates/init/ree.setup.rb +21 -0
- data/lib/ree/templates/init/spec.init.rb +7 -0
- data/lib/ree/templates/package/.gitignore +0 -0
- data/lib/ree/templates/package/.rspec +2 -0
- data/lib/ree/templates/package/<%=package_subdir_name%>/<%=package_name%>/.gitkeep +0 -0
- data/lib/ree/templates/package/<%=package_subdir_name%>/<%=package_name%>.rb +15 -0
- data/lib/ree/templates/package/Package.schema.json +0 -0
- data/lib/ree/templates/package/bin/console +5 -0
- data/lib/ree/templates/package/spec/package_schema_spec.rb +14 -0
- data/lib/ree/templates/package/spec/spec_helper.rb +3 -0
- data/lib/ree/templates/template_detector.rb +35 -0
- data/lib/ree/templates/template_renderer.rb +55 -0
- data/lib/ree/utils/render_utils.rb +20 -0
- data/lib/ree/utils/string_utils.rb +29 -0
- data/lib/ree/version.rb +5 -0
- data/lib/ree.rb +279 -0
- data/sig/ree.rbs +4 -0
- metadata +199 -0
@@ -0,0 +1,297 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module Ree::Contracts
|
6
|
+
module ArgContracts
|
7
|
+
class Splat
|
8
|
+
include Ree::Contracts::Truncatable
|
9
|
+
|
10
|
+
def self.[](*contracts)
|
11
|
+
if contracts.empty?
|
12
|
+
raise BadContractError, 'Splat contract should accept at least one contract'
|
13
|
+
end
|
14
|
+
|
15
|
+
forbidden_class_contracts = Ree::Contracts::Validators::FORBIDDEN_CONTRACTS
|
16
|
+
forbidden = Set.new(forbidden_class_contracts.to_a - [ArgContracts::SplatOf])
|
17
|
+
|
18
|
+
contracts.each_with_index do |contract, index|
|
19
|
+
contract_name = if forbidden_class_contracts.include?(contract)
|
20
|
+
contract.to_s
|
21
|
+
elsif forbidden.include?(contract.class)
|
22
|
+
contract.class.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
if contract_name
|
26
|
+
raise BadContractError, "#{contract_name} contract is not allowed to use inside Splat contract"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
splat_of_count = contracts.count { _1.is_a?(ArgContracts::SplatOf) }
|
31
|
+
|
32
|
+
if splat_of_count != 1
|
33
|
+
raise BadContractError, "Splat contract should include one SplatOf contract"
|
34
|
+
end
|
35
|
+
|
36
|
+
new(contracts)
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(contracts)
|
40
|
+
@contracts = contracts
|
41
|
+
|
42
|
+
@first_splat_of = contracts.first.is_a?(ArgContracts::SplatOf) ? contracts.first : nil
|
43
|
+
@last_splat_of = contracts.size > 1 && contracts.last.is_a?(ArgContracts::SplatOf) ? contracts.last : nil
|
44
|
+
|
45
|
+
@middle_splat_of = if contracts.size > 2
|
46
|
+
list = contracts[1..-2]
|
47
|
+
idx = list.index { _1.is_a?(ArgContracts::SplatOf) }
|
48
|
+
list[idx] if idx
|
49
|
+
end
|
50
|
+
|
51
|
+
@middle_splat_of_index = @contracts.index { _1 == @middle_splat_of } if @middle_splat_of
|
52
|
+
@validators = contracts.map { Validators.fetch_for(_1) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def valid?(value)
|
56
|
+
return false if !value.is_a?(Array)
|
57
|
+
return false if @validators.size - 1 > value.size
|
58
|
+
|
59
|
+
if @first_splat_of
|
60
|
+
return valid_with_first?(@validators, value)
|
61
|
+
end
|
62
|
+
|
63
|
+
if @last_splat_of
|
64
|
+
return valid_with_last?(@validators, value)
|
65
|
+
end
|
66
|
+
|
67
|
+
if @middle_splat_of
|
68
|
+
# before splat part
|
69
|
+
left_contract_count = @middle_splat_of_index
|
70
|
+
right_contract_count = @validators.size - @middle_splat_of_index - 1
|
71
|
+
|
72
|
+
is_valid = value[0..left_contract_count - 1].each_with_index.all? do |value, idx|
|
73
|
+
@validators[idx].call(value)
|
74
|
+
end
|
75
|
+
|
76
|
+
return false if !is_valid
|
77
|
+
|
78
|
+
# splat part
|
79
|
+
splat_values = if left_contract_count + right_contract_count == value.size
|
80
|
+
[]
|
81
|
+
else
|
82
|
+
value[@middle_splat_of_index..value.size - right_contract_count - 1]
|
83
|
+
end
|
84
|
+
|
85
|
+
if !splat_values.empty?
|
86
|
+
return false if !@validators[@middle_splat_of_index].call(splat_values)
|
87
|
+
end
|
88
|
+
|
89
|
+
# after splat part
|
90
|
+
is_valid = value[value.size - right_contract_count..-1].each_with_index.all? do |value, idx|
|
91
|
+
@validators[@middle_splat_of_index + idx + 1].call(value)
|
92
|
+
end
|
93
|
+
|
94
|
+
return false if !is_valid
|
95
|
+
end
|
96
|
+
|
97
|
+
return true
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_s
|
101
|
+
"Splat[#{@validators.map(&:to_s).join(", ")}]"
|
102
|
+
end
|
103
|
+
|
104
|
+
def message(value, name, lvl = 1)
|
105
|
+
unless value.is_a?(Array)
|
106
|
+
return "expected #{to_s}, got #{value.class} => #{truncate(value.inspect)}"
|
107
|
+
end
|
108
|
+
|
109
|
+
errors = []
|
110
|
+
sps = " " * lvl
|
111
|
+
|
112
|
+
if @validators.size - 1 > value.size
|
113
|
+
return "expected at least #{@validators.size - 1} #{pluralize(@validators.size, 'value', 'values')} for #{to_s}, got #{value.size} #{pluralize(value.size, 'value', 'values')} => #{truncate(value.inspect)}"
|
114
|
+
end
|
115
|
+
|
116
|
+
if @first_splat_of
|
117
|
+
rest_validators = @validators[1..-1]
|
118
|
+
rest_validator_count = rest_validators.size
|
119
|
+
|
120
|
+
rest_values = if value.size >= @validators.size
|
121
|
+
value[(value.size - rest_validator_count)..-1]
|
122
|
+
else
|
123
|
+
value
|
124
|
+
end
|
125
|
+
|
126
|
+
if rest_validator_count > 0
|
127
|
+
rest_validators.each_with_index do |validator, idx|
|
128
|
+
val = rest_values[idx]
|
129
|
+
next if validator.call(val)
|
130
|
+
|
131
|
+
msg = validator.message(val, "#{name}[#{idx + 1}]", lvl + 1)
|
132
|
+
errors << "\n\t#{sps} - #{name}[#{idx + 1}]: #{msg}"
|
133
|
+
|
134
|
+
if errors.size > 3
|
135
|
+
errors << "\n\t#{sps} - ..."
|
136
|
+
break
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
if rest_values.size != value.size
|
142
|
+
validator = @validators.first
|
143
|
+
idx = value.size - rest_validator_count - 1
|
144
|
+
val = value[0..idx]
|
145
|
+
|
146
|
+
if !validator.call(val)
|
147
|
+
msg = validator.message(val, "#{name}[0..#{idx}]", lvl + 1)
|
148
|
+
errors << "\n\t#{sps} - #{name}[0..#{idx}]: #{msg}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
elsif @last_splat_of
|
152
|
+
rest_validators = @validators[0..-2]
|
153
|
+
rest_validator_count = rest_validators.size
|
154
|
+
|
155
|
+
rest_values = if value.size >= @validators.size
|
156
|
+
value[0..-2]
|
157
|
+
else
|
158
|
+
value
|
159
|
+
end
|
160
|
+
|
161
|
+
if rest_validator_count > 0
|
162
|
+
rest_validators.each_with_index do |validator, idx|
|
163
|
+
val = rest_values[idx]
|
164
|
+
next if validator.call(val)
|
165
|
+
|
166
|
+
msg = validator.message(val, "#{name}[#{idx}]", lvl + 1)
|
167
|
+
errors << "\n\t#{sps} - #{name}[#{idx}]: #{msg}"
|
168
|
+
|
169
|
+
if errors.size > 3
|
170
|
+
errors << "\n\t#{sps} - ..."
|
171
|
+
break
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
if rest_values.size != value.size
|
177
|
+
validator = @validators.last
|
178
|
+
idx = rest_validator_count
|
179
|
+
val = value[idx..-1]
|
180
|
+
|
181
|
+
if !validator.call(val)
|
182
|
+
msg = validator.message(val, "#{name}[#{idx}..#{value.size - 1}]", lvl + 1)
|
183
|
+
errors << "\n\t#{sps} - #{name}[#{idx}..#{value.size - 1}]: #{msg}"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
elsif @middle_splat_of
|
187
|
+
left_contract_count = @middle_splat_of_index
|
188
|
+
right_contract_count = @validators.size - @middle_splat_of_index - 1
|
189
|
+
|
190
|
+
value[0..left_contract_count - 1].each_with_index do |value, idx|
|
191
|
+
validator = @validators[idx]
|
192
|
+
next if validator.call(value)
|
193
|
+
|
194
|
+
msg = validator.message(value, "#{name}[#{idx}]", lvl + 1)
|
195
|
+
errors << "\n\t#{sps} - #{name}[#{idx}]: #{msg}"
|
196
|
+
|
197
|
+
if errors.size > 3
|
198
|
+
errors << "\n\t#{sps} - ..."
|
199
|
+
break
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
splat_values = if left_contract_count + right_contract_count == value.size
|
204
|
+
[]
|
205
|
+
else
|
206
|
+
value[@middle_splat_of_index..value.size - right_contract_count - 1]
|
207
|
+
end
|
208
|
+
|
209
|
+
if !splat_values.empty?
|
210
|
+
validator = @validators[@middle_splat_of_index]
|
211
|
+
|
212
|
+
if !validator.call(splat_values)
|
213
|
+
splat_name = "#{name}[#{@middle_splat_of_index}..#{value.size - right_contract_count - 1}]"
|
214
|
+
msg = validator.message(splat_values, "#{splat_name}", lvl + 1)
|
215
|
+
errors << "\n\t#{sps} - #{splat_name}: #{msg}"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
is_valid = value[value.size - right_contract_count..-1].each_with_index.all? do |value, idx|
|
220
|
+
@validators[@middle_splat_of_index + idx + 1].call(value)
|
221
|
+
end
|
222
|
+
|
223
|
+
pos = value.size - right_contract_count
|
224
|
+
|
225
|
+
value[pos..-1].each_with_index do |value, idx|
|
226
|
+
validator = @validators[@middle_splat_of_index + idx + 1]
|
227
|
+
next if validator.call(value)
|
228
|
+
|
229
|
+
msg = validator.message(value, "#{name}[#{pos + idx}]", lvl + 1)
|
230
|
+
errors << "\n\t#{sps} - #{name}[#{pos + idx}]: #{msg}"
|
231
|
+
|
232
|
+
if errors.size > 3
|
233
|
+
errors << "\n\t#{sps} - ..."
|
234
|
+
break
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
errors.join
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
def valid_with_first?(validators, values)
|
245
|
+
rest_validators = validators[1..-1]
|
246
|
+
rest_validator_count = rest_validators.size
|
247
|
+
|
248
|
+
rest_values = if values.size >= validators.size
|
249
|
+
values[(values.size - rest_validator_count)..-1]
|
250
|
+
else
|
251
|
+
values
|
252
|
+
end
|
253
|
+
|
254
|
+
has_error = false
|
255
|
+
|
256
|
+
if rest_validator_count > 0
|
257
|
+
has_error = rest_validators.each_with_index.any? do |validator, idx|
|
258
|
+
!validator.call(rest_values[idx])
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
return false if has_error
|
263
|
+
return true if rest_values.size == values.size
|
264
|
+
|
265
|
+
validators.first.call(values[0..(values.size - rest_validator_count - 1)])
|
266
|
+
end
|
267
|
+
|
268
|
+
def valid_with_last?(validators, values)
|
269
|
+
rest_validators = validators[0..-2]
|
270
|
+
rest_validator_count = rest_validators.size
|
271
|
+
|
272
|
+
rest_values = if values.size >= validators.size
|
273
|
+
values[0..-2]
|
274
|
+
else
|
275
|
+
values
|
276
|
+
end
|
277
|
+
|
278
|
+
has_error = false
|
279
|
+
|
280
|
+
if rest_validator_count > 0
|
281
|
+
has_error = rest_validators.each_with_index.any? do |validator, idx|
|
282
|
+
!validator.call(rest_values[idx])
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
return false if has_error
|
287
|
+
return true if rest_values.size == values.size
|
288
|
+
|
289
|
+
validators.last.call(values[rest_validator_count..-1])
|
290
|
+
end
|
291
|
+
|
292
|
+
def pluralize(num, single, plural)
|
293
|
+
num == 1 ? single : plural
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ree::Contracts
|
4
|
+
module ArgContracts
|
5
|
+
class SplatOf
|
6
|
+
include Ree::Contracts::Truncatable
|
7
|
+
|
8
|
+
attr_reader :validator
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def [](contract)
|
12
|
+
new(contract)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(contract)
|
17
|
+
forbidden_class_contracts = Ree::Contracts::Validators::FORBIDDEN_CONTRACTS
|
18
|
+
|
19
|
+
contract_name = if forbidden_class_contracts.include?(contract)
|
20
|
+
contract.to_s
|
21
|
+
elsif forbidden_class_contracts.include?(contract.class)
|
22
|
+
contract.class.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
if contract_name
|
26
|
+
raise BadContractError, "#{contract_name} contract is not allowed to use inside SplatOf contract"
|
27
|
+
end
|
28
|
+
|
29
|
+
@validator = Validators.fetch_for(contract)
|
30
|
+
end
|
31
|
+
|
32
|
+
def valid?(value)
|
33
|
+
value.is_a?(Array) && value.all?(&validator.method(:call))
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
"SplatOf[#{validator.to_s}]"
|
38
|
+
end
|
39
|
+
|
40
|
+
def message(value, name, lvl = 1)
|
41
|
+
unless value.is_a?(Array)
|
42
|
+
return "expected #{to_s}, got #{value.class} => #{truncate(value.inspect)}"
|
43
|
+
end
|
44
|
+
|
45
|
+
errors = []
|
46
|
+
sps = " " * lvl
|
47
|
+
|
48
|
+
value.each_with_index do |val, idx|
|
49
|
+
next if validator.call(val)
|
50
|
+
|
51
|
+
msg = validator.message(val, "#{name}[#{idx}]", lvl + 1)
|
52
|
+
errors << "\n\t#{sps} - #{name}[#{idx}]: #{msg}"
|
53
|
+
|
54
|
+
if errors.size > 3
|
55
|
+
errors << "\n\t#{sps} - ..."
|
56
|
+
break
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
errors.join
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ree::Contracts
|
4
|
+
module ArgContracts
|
5
|
+
class SubclassOf
|
6
|
+
extend Ree::Contracts::ArgContracts::Squarable
|
7
|
+
include Ree::Contracts::Truncatable
|
8
|
+
|
9
|
+
attr_reader :klass
|
10
|
+
|
11
|
+
def initialize(klass)
|
12
|
+
@klass = klass
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid?(value)
|
16
|
+
value.is_a?(Class) && value < klass
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"SubclassOf[#{klass.inspect}]"
|
21
|
+
end
|
22
|
+
|
23
|
+
def message(value, name, lvl = 1)
|
24
|
+
"expected #{truncate(self.to_s, 30)}, got #{truncate(value.inspect)}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ree::Contracts
|
4
|
+
module ArgContracts
|
5
|
+
autoload :Any, 'ree/contracts/arg_contracts/any'
|
6
|
+
autoload :ArrayOf, 'ree/contracts/arg_contracts/array_of'
|
7
|
+
autoload :Block, 'ree/contracts/arg_contracts/block'
|
8
|
+
autoload :Bool, 'ree/contracts/arg_contracts/bool'
|
9
|
+
autoload :Eq, 'ree/contracts/arg_contracts/eq'
|
10
|
+
autoload :Exactly, 'ree/contracts/arg_contracts/exactly'
|
11
|
+
autoload :HashOf, 'ree/contracts/arg_contracts/hash_of'
|
12
|
+
autoload :Ksplat, 'ree/contracts/arg_contracts/ksplat'
|
13
|
+
autoload :Kwargs, 'ree/contracts/arg_contracts/kwargs'
|
14
|
+
autoload :Nilor, 'ree/contracts/arg_contracts/nilor'
|
15
|
+
autoload :None, 'ree/contracts/arg_contracts/none'
|
16
|
+
autoload :Optblock, 'ree/contracts/arg_contracts/optblock'
|
17
|
+
autoload :Or, 'ree/contracts/arg_contracts/or'
|
18
|
+
autoload :RangeOf, 'ree/contracts/arg_contracts/range_of'
|
19
|
+
autoload :SetOf, 'ree/contracts/arg_contracts/set_of'
|
20
|
+
autoload :Splat, 'ree/contracts/arg_contracts/splat'
|
21
|
+
autoload :SplatOf, 'ree/contracts/arg_contracts/splat_of'
|
22
|
+
autoload :Squarable, 'ree/contracts/arg_contracts/squarable'
|
23
|
+
autoload :SubclassOf, 'ree/contracts/arg_contracts/subclass_of'
|
24
|
+
|
25
|
+
def self.opt_or_block?(contract)
|
26
|
+
contract == Block || contract == Optblock
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|