hierarchical_config 0.11 → 0.13.2
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.
- checksums.yaml +5 -5
- data/.github/workflows/release.yml +41 -0
- data/.github/workflows/ruby.yml +55 -0
- data/.gitignore +2 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +68 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +15 -2
- data/Gemfile.2.4 +19 -0
- data/Gemfile.2.4.lock +117 -0
- data/Gemfile.lock +126 -25
- data/README.md +0 -2
- data/bin/console +3 -3
- data/bin/tapioca +29 -0
- data/hierarchical_config.gemspec +14 -13
- data/lib/hierarchical_config/version.rb +3 -1
- data/lib/hierarchical_config.rb +195 -98
- data/release-please-config.json +14 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/annotations/activesupport.rbi +128 -0
- data/sorbet/rbi/annotations/rainbow.rbi +269 -0
- data/sorbet/rbi/gems/activesupport@7.0.4.2.rbi +16155 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +584 -0
- data/sorbet/rbi/gems/binding_of_caller@1.0.0.rbi +55 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +3426 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.2.2.rbi +11545 -0
- data/sorbet/rbi/gems/debug_inspector@1.1.0.rbi +23 -0
- data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +1083 -0
- data/sorbet/rbi/gems/i18n@1.12.0.rbi +2296 -0
- data/sorbet/rbi/gems/interception@0.5.rbi +138 -0
- data/sorbet/rbi/gems/json@2.6.3.rbi +1541 -0
- data/sorbet/rbi/gems/method_source@1.0.0.rbi +272 -0
- data/sorbet/rbi/gems/minitest@5.17.0.rbi +1457 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +158 -0
- data/sorbet/rbi/gems/parallel@1.22.1.rbi +277 -0
- data/sorbet/rbi/gems/parser@3.2.1.0.rbi +7252 -0
- data/sorbet/rbi/gems/pry-rescue@1.5.2.rbi +186 -0
- data/sorbet/rbi/gems/pry-stack_explorer@0.6.1.rbi +295 -0
- data/sorbet/rbi/gems/pry@0.14.2.rbi +10081 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +402 -0
- data/sorbet/rbi/gems/rake@13.0.6.rbi +3018 -0
- data/sorbet/rbi/gems/rbi@0.0.16.rbi +3008 -0
- data/sorbet/rbi/gems/regexp_parser@2.7.0.rbi +3580 -0
- data/sorbet/rbi/gems/rexml@3.2.5.rbi +4717 -0
- data/sorbet/rbi/gems/rspec-core@3.12.1.rbi +10845 -0
- data/sorbet/rbi/gems/rspec-expectations@3.12.2.rbi +8100 -0
- data/sorbet/rbi/gems/rspec-mocks@3.12.3.rbi +5299 -0
- data/sorbet/rbi/gems/rspec-support@3.12.0.rbi +1611 -0
- data/sorbet/rbi/gems/rspec@3.12.0.rbi +82 -0
- data/sorbet/rbi/gems/rubocop-ast@1.27.0.rbi +6998 -0
- data/sorbet/rbi/gems/rubocop-performance@1.16.0.rbi +3004 -0
- data/sorbet/rbi/gems/rubocop@1.46.0.rbi +54549 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +1239 -0
- data/sorbet/rbi/gems/spoom@1.1.15.rbi +2383 -0
- data/sorbet/rbi/gems/tapioca@0.11.1.rbi +3255 -0
- data/sorbet/rbi/gems/thor@1.2.1.rbi +3956 -0
- data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5917 -0
- data/sorbet/rbi/gems/unicode-display_width@2.4.2.rbi +65 -0
- data/sorbet/rbi/gems/unparser@0.6.7.rbi +4524 -0
- data/sorbet/rbi/gems/webrick@1.7.0.rbi +2555 -0
- data/sorbet/rbi/gems/yard-sorbet@0.8.0.rbi +441 -0
- data/sorbet/rbi/gems/yard@0.9.28.rbi +17841 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +4 -0
- metadata +75 -47
- data/.travis.yml +0 -6
data/lib/hierarchical_config.rb
CHANGED
@@ -1,84 +1,204 @@
|
|
1
|
-
|
1
|
+
# typed: strict
|
2
|
+
|
2
3
|
require 'yaml'
|
3
4
|
require 'erb'
|
4
5
|
require 'set'
|
6
|
+
require 'sorbet-runtime'
|
7
|
+
require 'active_support'
|
8
|
+
require 'active_support/core_ext/hash/keys'
|
5
9
|
|
6
|
-
require
|
10
|
+
require 'hierarchical_config/version'
|
7
11
|
|
8
12
|
module HierarchicalConfig
|
9
13
|
REQUIRED = :REQUIRED
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
T.unsafe(YAML).add_domain_type(nil, 'REQUIRED'){REQUIRED}
|
15
|
+
|
16
|
+
ClassOrModule = T.type_alias{T.any(Class, Module)}
|
17
|
+
|
18
|
+
module ConfigStruct
|
19
|
+
extend T::Sig
|
20
|
+
include Kernel
|
21
|
+
|
22
|
+
sig{returns(T::Hash[Symbol, T.untyped])}
|
23
|
+
def to_hash
|
24
|
+
Hash[self.class.props.keys.map{|key| [key, item_to_hash(send(key))]}] # rubocop:disable Style/HashConversion
|
25
|
+
end
|
26
|
+
|
27
|
+
sig do
|
28
|
+
type_parameters(:A, :B).
|
29
|
+
params(
|
30
|
+
blk: T.nilable(
|
31
|
+
T.proc.params(name: Symbol, value: T.untyped).
|
32
|
+
returns([T.type_parameter(:A), T.type_parameter(:B)]),
|
33
|
+
),
|
34
|
+
).
|
35
|
+
returns(
|
36
|
+
T.any(
|
37
|
+
T::Hash[T.type_parameter(:A), T.type_parameter(:B)],
|
38
|
+
T::Hash[Symbol, T.untyped],
|
39
|
+
),
|
40
|
+
)
|
41
|
+
end
|
42
|
+
def to_h(&blk)
|
43
|
+
hash = self.class.props.keys.map{|key| [key, send(key)]}
|
44
|
+
if blk
|
45
|
+
# copied from https://github.com/marcandre/backports/blob/36572870cbdc0cda30e5bab81af8ba390a6cf7c7/lib/backports/2.6.0/hash/to_h.rb#L3C39-L3C39
|
46
|
+
# to implement to_h with block for ruby < 2.6.0
|
47
|
+
if {n: true}.to_h{[:ok, true]}[:n]
|
48
|
+
T.unsafe(hash).map(&blk).to_h
|
49
|
+
else
|
50
|
+
hash.to_h(&blk)
|
22
51
|
end
|
23
|
-
modifiable[new_ostruct_member(mname)] = args[0]
|
24
|
-
elsif mname =~ /\?$/
|
25
|
-
!!send(mname.gsub("?",""))
|
26
|
-
elsif len == 0 && @table.key?( mid )
|
27
|
-
@table[mid]
|
28
52
|
else
|
29
|
-
|
53
|
+
hash.to_h
|
30
54
|
end
|
31
55
|
end
|
32
56
|
|
33
|
-
|
34
|
-
|
57
|
+
sig{params(key: T.any(String, Symbol)).returns(T.untyped)}
|
58
|
+
def [](key)
|
59
|
+
send(key)
|
35
60
|
end
|
36
61
|
|
37
|
-
|
62
|
+
private
|
38
63
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
64
|
+
sig{params(item: BasicObject).returns(T.any(BasicObject, T::Hash[T.untyped, T.untyped]))}
|
65
|
+
def item_to_hash(item)
|
66
|
+
case item
|
67
|
+
when ConfigStruct
|
68
|
+
item.to_hash
|
69
|
+
when Array
|
70
|
+
item.map{|i| item_to_hash(i)}
|
71
|
+
else
|
72
|
+
item
|
44
73
|
end
|
45
74
|
end
|
75
|
+
end
|
46
76
|
|
47
|
-
|
77
|
+
@@root_index = T.let(0, Integer) # rubocop:disable Style/ClassVars
|
78
|
+
|
79
|
+
class << self
|
80
|
+
extend T::Sig
|
48
81
|
|
49
|
-
|
82
|
+
sig{params(value: T.untyped, path: String).returns(T::Array[String])}
|
83
|
+
def detect_errors(value, path)
|
84
|
+
errors = T.let([], T::Array[String])
|
50
85
|
case value
|
86
|
+
when Hash
|
87
|
+
value.each do |key, item|
|
88
|
+
errors += detect_errors(item, "#{path}.#{key}")
|
89
|
+
end
|
90
|
+
when Array
|
91
|
+
value.each_with_index do |item, index|
|
92
|
+
errors += detect_errors(item, "#{path}[#{index}]")
|
93
|
+
end
|
94
|
+
when REQUIRED
|
95
|
+
errors << "#{path} is REQUIRED"
|
96
|
+
end
|
97
|
+
errors
|
98
|
+
end
|
99
|
+
|
100
|
+
sig{params(current_item: Object, name: String, parent_class: ClassOrModule).returns(T.any(Class, T::Types::Base))}
|
101
|
+
def build_types(current_item, name, parent_class)
|
102
|
+
case current_item
|
103
|
+
when Hash
|
104
|
+
new_type_name = inflect_typename(name)
|
105
|
+
|
106
|
+
return Hash if current_item.keys.to_a.any?{|k| k =~ /^[0-9]/ || k =~ /[- ]/}
|
107
|
+
|
108
|
+
new_type =
|
109
|
+
if parent_class.const_defined?(new_type_name, false)
|
110
|
+
parent_class.const_get(new_type_name, false)
|
111
|
+
else
|
112
|
+
parent_class.const_set(new_type_name, Class.new(T::Struct).tap{|c| c.include ConfigStruct})
|
113
|
+
end
|
114
|
+
|
115
|
+
current_item.each do |key, value|
|
116
|
+
next if new_type.props.key?(key.to_sym)
|
117
|
+
|
118
|
+
new_type.const key.to_sym, build_types(value, key, new_type)
|
119
|
+
new_type.send(:define_method, "#{key}?") do
|
120
|
+
!!send(key)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
new_type
|
51
125
|
when Array
|
52
|
-
|
53
|
-
|
54
|
-
|
126
|
+
types = current_item.each_with_index.map do |item, index|
|
127
|
+
build_types(item, "#{name}_#{index}", parent_class)
|
128
|
+
end
|
129
|
+
case types.size
|
130
|
+
when 0
|
131
|
+
T.untyped
|
132
|
+
when 1
|
133
|
+
T::Array[types.first]
|
134
|
+
else
|
135
|
+
T::Array[T.unsafe(T).any(*types)]
|
136
|
+
end
|
55
137
|
else
|
56
|
-
|
138
|
+
current_item.class
|
57
139
|
end
|
58
140
|
end
|
59
|
-
end
|
60
141
|
|
61
|
-
|
62
|
-
def
|
142
|
+
sig{params(current_item: Object, name: String, parent_class: ClassOrModule).returns(T.untyped)}
|
143
|
+
def build_config(current_item, name, parent_class)
|
144
|
+
case current_item
|
145
|
+
when Hash
|
146
|
+
return current_item.symbolize_keys if current_item.keys.to_a.any?{|k| k =~ /^[0-9]/ || k =~ /[- ]/}
|
147
|
+
|
148
|
+
current_type = parent_class.const_get(inflect_typename(name))
|
149
|
+
current_type.new(Hash[current_item.map{|key, value| [key.to_sym, build_config(value, key, current_type)]}]) # rubocop:disable Style/HashConversion
|
150
|
+
when Array
|
151
|
+
current_item.each_with_index.map do |item, index|
|
152
|
+
build_config(item, "#{name}_#{index}", parent_class)
|
153
|
+
end.freeze
|
154
|
+
else
|
155
|
+
current_item.freeze
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
sig{returns(Class)}
|
160
|
+
def build_new_root
|
161
|
+
@@root_index += 1 # rubocop:disable Style/ClassVars
|
162
|
+
const_set("ConfigRoot#{@@root_index}", Class.new)
|
163
|
+
end
|
164
|
+
|
165
|
+
sig do
|
166
|
+
params(
|
167
|
+
name: String,
|
168
|
+
dir: String,
|
169
|
+
environment: String,
|
170
|
+
preprocess_with: T.nilable(Symbol),
|
171
|
+
root_class: ClassOrModule,
|
172
|
+
).returns(T::Struct)
|
173
|
+
end
|
174
|
+
def load_config(name, dir, environment, preprocess_with = :erb, root_class = build_new_root)
|
63
175
|
primary_config_file = "#{dir}/#{name}.yml"
|
64
176
|
overrides_config_file = "#{dir}/#{name}-overrides.yml"
|
65
177
|
|
66
|
-
config_hash = load_hash_for_env(
|
178
|
+
config_hash = load_hash_for_env(primary_config_file, environment, preprocess_with)
|
67
179
|
|
68
|
-
if File.
|
69
|
-
overrides_config_hash = load_hash_for_env(
|
70
|
-
config_hash = deep_merge(
|
180
|
+
if File.exist?(overrides_config_file)
|
181
|
+
overrides_config_hash = load_hash_for_env(overrides_config_file, environment, preprocess_with)
|
182
|
+
config_hash = deep_merge(config_hash, overrides_config_hash)
|
71
183
|
end
|
72
184
|
|
73
|
-
|
185
|
+
errors = detect_errors(config_hash, name)
|
186
|
+
raise errors.map{|error| "#{error} for #{environment}"}.inspect unless errors.empty?
|
74
187
|
|
75
|
-
|
188
|
+
build_types(config_hash, name, root_class)
|
76
189
|
|
77
|
-
config_hash
|
190
|
+
build_config(config_hash, name, root_class)
|
78
191
|
end
|
79
192
|
|
80
|
-
|
81
|
-
|
193
|
+
sig do
|
194
|
+
params(
|
195
|
+
file: String,
|
196
|
+
environment: String,
|
197
|
+
preprocess_with: T.nilable(Symbol),
|
198
|
+
).returns(T::Hash[String, BasicObject])
|
199
|
+
end
|
200
|
+
def load_hash_for_env(file, environment, preprocess_with)
|
201
|
+
file_contents = File.read(file)
|
82
202
|
yaml_contents = case preprocess_with
|
83
203
|
when :erb
|
84
204
|
ERB.new(file_contents).result
|
@@ -87,103 +207,80 @@ module HierarchicalConfig
|
|
87
207
|
else
|
88
208
|
raise "Unknown preprocessor <#{preprocess_with}>"
|
89
209
|
end
|
90
|
-
yaml_config = YAML
|
210
|
+
yaml_config = YAML.safe_load(yaml_contents)
|
91
211
|
|
92
212
|
ordered_stanza_labels = []
|
93
213
|
ordered_stanza_labels << 'defaults' if yaml_config.key? 'defaults'
|
94
|
-
ordered_stanza_labels += yaml_config.keys.grep(/^defaults\[.*#{environment}/).sort_by{
|
214
|
+
ordered_stanza_labels += yaml_config.keys.grep(/^defaults\[.*#{environment}/).sort_by{|a| a.count(',')}
|
95
215
|
ordered_stanza_labels << environment if yaml_config.key? environment
|
96
216
|
|
97
217
|
config = deep_merge_hashes_in_keys(ordered_stanza_labels, yaml_config)
|
98
218
|
|
99
219
|
env_config_labels = []
|
100
220
|
env_config_labels << 'env_vars' if yaml_config.key? 'env_vars'
|
101
|
-
env_config_labels += yaml_config.keys.grep(/^env_vars\[.*#{environment}/).sort_by{
|
221
|
+
env_config_labels += yaml_config.keys.grep(/^env_vars\[.*#{environment}/).sort_by{|a| a.count(',')}
|
102
222
|
|
103
223
|
env_config = deep_merge_hashes_in_keys(env_config_labels, yaml_config)
|
104
224
|
env_config = fill_in_env_vars(env_config)
|
105
225
|
|
106
226
|
deep_merge(config, env_config)
|
107
|
-
|
108
227
|
rescue StandardError => e
|
109
228
|
raise <<-ERROR
|
110
229
|
Error loading config from file #{file}.
|
111
|
-
#{
|
112
|
-
#{
|
230
|
+
#{$ERROR_INFO.inspect}
|
231
|
+
#{$ERROR_POSITION}
|
232
|
+
#{e}
|
113
233
|
ERROR
|
114
234
|
end
|
115
235
|
|
116
236
|
private
|
117
237
|
|
238
|
+
sig do
|
239
|
+
params(keys: T::Array[String],
|
240
|
+
root_hash: T::Hash[String,
|
241
|
+
T::Hash[String, T.untyped]]).returns(T::Hash[T.untyped, T.untyped])
|
242
|
+
end
|
118
243
|
def deep_merge_hashes_in_keys(keys, root_hash)
|
119
244
|
keys.inject({}) do |acc, label|
|
120
|
-
deep_merge(
|
245
|
+
deep_merge(acc, T.must(root_hash[label]))
|
121
246
|
end
|
122
247
|
end
|
123
248
|
|
249
|
+
sig{params(hash: T::Hash[T.untyped, T.untyped]).returns(T::Hash[T.untyped, T.untyped])}
|
124
250
|
def fill_in_env_vars(hash)
|
125
251
|
r = {}
|
126
|
-
hash.each do |key,value|
|
252
|
+
hash.each do |key, value|
|
127
253
|
if value.is_a? Hash
|
128
254
|
leaf_hash = fill_in_env_vars(value)
|
129
|
-
r[key]=leaf_hash unless leaf_hash.keys.empty?
|
255
|
+
r[key] = leaf_hash unless leaf_hash.keys.empty?
|
130
256
|
elsif !value.nil? && ENV.key?(value)
|
131
|
-
r[key]=ENV
|
257
|
+
r[key] = ENV.fetch(value, nil)
|
132
258
|
end
|
133
259
|
end
|
134
260
|
r
|
135
261
|
end
|
136
262
|
|
137
263
|
# merges two hashes with nested hashes if present
|
138
|
-
|
264
|
+
sig do
|
265
|
+
params(hash1: T::Hash[T.untyped, T.untyped],
|
266
|
+
hash2: T::Hash[T.untyped, T.untyped]).returns(T::Hash[T.untyped, T.untyped])
|
267
|
+
end
|
268
|
+
def deep_merge(hash1, hash2)
|
139
269
|
hash1 = hash1.dup
|
140
|
-
(
|
141
|
-
if hash1.key?(
|
142
|
-
hash1[key].is_a?(
|
143
|
-
|
144
|
-
elsif hash2.key?(
|
270
|
+
(hash1.keys + hash2.keys).each do |key|
|
271
|
+
if hash1.key?(key) && hash2.key?(key) &&
|
272
|
+
hash1[key].is_a?(Hash) && hash2[key].is_a?(Hash)
|
273
|
+
hash1[key] = deep_merge(hash1[key], hash2[key])
|
274
|
+
elsif hash2.key?(key)
|
145
275
|
hash1[key] = hash2[key]
|
146
276
|
end
|
147
277
|
end
|
148
278
|
hash1
|
149
279
|
end
|
150
280
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
# * recursively sets open structs for deep hashes
|
155
|
-
# * recursively freezes config objects
|
156
|
-
def lock_down_and_ostructify!( _hash, path, environment)
|
157
|
-
hash = Hash[_hash.map{|k,v|[k.to_s, v]}] #stringify keys
|
158
|
-
errors = []
|
159
|
-
hash.each do | key, value |
|
160
|
-
hash[key], child_errors = lock_down_and_ostructify_item!(value, path + '.' + key, environment)
|
161
|
-
errors += child_errors
|
162
|
-
end
|
163
|
-
return OpenStruct.new(hash).freeze, errors
|
164
|
-
end
|
165
|
-
|
166
|
-
def lock_down_and_ostructify_item!(value, path, environment)
|
167
|
-
errors = []
|
168
|
-
return_value = case value
|
169
|
-
when Hash
|
170
|
-
child_hash, child_errors = lock_down_and_ostructify!( value, path, environment )
|
171
|
-
errors += child_errors
|
172
|
-
child_hash
|
173
|
-
when Array
|
174
|
-
value.each_with_index.map do |item, index|
|
175
|
-
child_item, child_errors = lock_down_and_ostructify_item!( item, "#{path}[#{index}]", environment )
|
176
|
-
errors += child_errors
|
177
|
-
child_item
|
178
|
-
end.freeze
|
179
|
-
when REQUIRED
|
180
|
-
errors << "#{path} is REQUIRED for #{environment}"
|
181
|
-
nil
|
182
|
-
else
|
183
|
-
value.freeze
|
184
|
-
end
|
185
|
-
|
186
|
-
return return_value, errors
|
281
|
+
sig{params(name: String).returns(String)}
|
282
|
+
def inflect_typename(name)
|
283
|
+
ActiveSupport::Inflector.camelize(name)
|
187
284
|
end
|
188
285
|
end
|
189
286
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"packages": {
|
3
|
+
".": {
|
4
|
+
"changelog-path": "CHANGELOG.md",
|
5
|
+
"release-type": "ruby",
|
6
|
+
"bump-minor-pre-major": true,
|
7
|
+
"bump-patch-for-minor-pre-major": true,
|
8
|
+
"draft": false,
|
9
|
+
"prerelease": false,
|
10
|
+
"version-file": "lib/hierarchical_config/version.rb"
|
11
|
+
}
|
12
|
+
},
|
13
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
|
14
|
+
}
|
data/sorbet/config
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
# DO NOT EDIT MANUALLY
|
4
|
+
# This file was pulled from a central RBI files repository.
|
5
|
+
# Please run `bin/tapioca annotations` to update it.
|
6
|
+
|
7
|
+
module ActiveSupport::Testing::Declarative
|
8
|
+
sig { params(name: String, block: T.proc.bind(T.untyped).void).void }
|
9
|
+
def test(name, &block); end
|
10
|
+
end
|
11
|
+
|
12
|
+
class ActiveSupport::EnvironmentInquirer
|
13
|
+
sig { returns(T::Boolean) }
|
14
|
+
def development?; end
|
15
|
+
|
16
|
+
sig { returns(T::Boolean) }
|
17
|
+
def production?; end
|
18
|
+
|
19
|
+
sig { returns(T::Boolean) }
|
20
|
+
def test?; end
|
21
|
+
|
22
|
+
# @method_missing: delegated to String through ActiveSupport::StringInquirer
|
23
|
+
sig { returns(T::Boolean) }
|
24
|
+
def staging?; end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ActiveSupport::Testing::SetupAndTeardown::ClassMethods
|
28
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.untyped).void)).void }
|
29
|
+
def setup(*args, &block); end
|
30
|
+
|
31
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.untyped).void)).void }
|
32
|
+
def teardown(*args, &block); end
|
33
|
+
end
|
34
|
+
|
35
|
+
class ActiveSupport::TestCase
|
36
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.attached_class).void)).void }
|
37
|
+
def self.setup(*args, &block); end
|
38
|
+
|
39
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.bind(T.attached_class).void)).void }
|
40
|
+
def self.teardown(*args, &block); end
|
41
|
+
|
42
|
+
sig { params(name: String, block: T.proc.bind(T.attached_class).void).void }
|
43
|
+
def self.test(name, &block); end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Object
|
47
|
+
sig { returns(T::Boolean) }
|
48
|
+
def blank?; end
|
49
|
+
|
50
|
+
sig { returns(T::Boolean) }
|
51
|
+
def present?; end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Hash
|
55
|
+
sig { returns(T::Boolean) }
|
56
|
+
def extractable_options?; end
|
57
|
+
end
|
58
|
+
|
59
|
+
class Array
|
60
|
+
sig { params(position: Integer).returns(T.self_type) }
|
61
|
+
def from(position); end
|
62
|
+
|
63
|
+
sig { params(position: Integer).returns(T.self_type) }
|
64
|
+
def to(position); end
|
65
|
+
|
66
|
+
sig { params(elements: T.untyped).returns(T::Array[T.untyped]) }
|
67
|
+
def including(*elements); end
|
68
|
+
|
69
|
+
sig { params(elements: T.untyped).returns(T.self_type) }
|
70
|
+
def excluding(*elements); end
|
71
|
+
|
72
|
+
sig { params(elements: T.untyped).returns(T.self_type) }
|
73
|
+
def without(*elements); end
|
74
|
+
|
75
|
+
sig { returns(T.nilable(Elem)) }
|
76
|
+
def second; end
|
77
|
+
|
78
|
+
sig { returns(T.nilable(Elem)) }
|
79
|
+
def third; end
|
80
|
+
|
81
|
+
sig { returns(T.nilable(Elem)) }
|
82
|
+
def fourth; end
|
83
|
+
|
84
|
+
sig { returns(T.nilable(Elem)) }
|
85
|
+
def fifth; end
|
86
|
+
|
87
|
+
sig { returns(T.nilable(Elem)) }
|
88
|
+
def forty_two; end
|
89
|
+
|
90
|
+
sig { returns(T.nilable(Elem)) }
|
91
|
+
def third_to_last; end
|
92
|
+
|
93
|
+
sig { returns(T.nilable(Elem)) }
|
94
|
+
def second_to_last; end
|
95
|
+
|
96
|
+
sig { params(options: T::Hash[T.untyped, T.untyped]).returns(String) }
|
97
|
+
def to_sentence(options = {}); end
|
98
|
+
|
99
|
+
sig { params(format: Symbol).returns(String) }
|
100
|
+
def to_fs(format = :default); end
|
101
|
+
|
102
|
+
sig { params(format: Symbol).returns(String) }
|
103
|
+
def to_formatted_s(format = :default); end
|
104
|
+
|
105
|
+
sig { returns(String) }
|
106
|
+
def to_xml; end
|
107
|
+
|
108
|
+
sig { returns(T::Hash[T.untyped, T.untyped]) }
|
109
|
+
def extract_options!; end
|
110
|
+
|
111
|
+
sig { type_parameters(:FillType).params(number: Integer, fill_with: T.type_parameter(:FillType), block: T.nilable(T.proc.params(group: T::Array[T.any(Elem, T.type_parameter(:FillType))]).void)).returns(T::Array[T::Array[T.any(Elem, T.type_parameter(:FillType))]]) }
|
112
|
+
def in_groups(number, fill_with = T.unsafe(nil), &block); end
|
113
|
+
|
114
|
+
sig { type_parameters(:FillType).params(number: Integer, fill_with: T.type_parameter(:FillType), block: T.nilable(T.proc.params(group: T::Array[T.any(Elem, T.type_parameter(:FillType))]).void)).returns(T::Array[T::Array[T.any(Elem, T.type_parameter(:FillType))]]) }
|
115
|
+
def in_groups_of(number, fill_with = T.unsafe(nil), &block); end
|
116
|
+
|
117
|
+
sig { params(value: T.untyped, block: T.nilable(T.proc.params(element: Elem).returns(T.untyped))).returns(T::Array[T::Array[Elem]]) }
|
118
|
+
def split(value = nil, &block); end
|
119
|
+
|
120
|
+
sig { params(object: T.untyped).returns(T::Array[T.untyped]) }
|
121
|
+
def self.wrap(object); end
|
122
|
+
|
123
|
+
sig { returns(T.untyped) }
|
124
|
+
def extract!; end
|
125
|
+
|
126
|
+
sig { returns(ActiveSupport::ArrayInquirer) }
|
127
|
+
def inquiry; end
|
128
|
+
end
|