Skip to content

Commit ed3b72a

Browse files
committed
Delegate missing Rails::Initializable::Collection methods to inner array
Previously, Rails::Initializable::Collection extended Array, but now it doesn't. The inner structure has changed enough so that we need to implement addition methods, but we can keep every other subtractive method as-is.
1 parent 6230bd3 commit ed3b72a

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

railties/lib/rails/initializable.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require "tsort"
4+
require "active_support/core_ext/module/delegation"
45

56
module Rails
67
module Initializable
@@ -38,6 +39,8 @@ class Collection
3839
include Enumerable
3940
include TSort
4041

42+
delegate_missing_to :@collection
43+
4144
def initialize(initializers = nil)
4245
@order = Hash.new { |hash, key| hash[key] = Set.new }
4346
@resolve = Hash.new { |hash, key| hash[key] = Set.new }
@@ -73,13 +76,23 @@ def <<(initializer)
7376
@order[initializer.before] << initializer.name if initializer.before
7477
@order[initializer.name] << initializer.after if initializer.after
7578
@resolve[initializer.name] << initializer
79+
self
7680
end
7781

78-
def concat(initializers)
82+
def push(*initializers)
7983
initializers.each(&method(:<<))
8084
self
8185
end
8286

87+
alias_method(:append, :push)
88+
89+
def concat(*initializer_collections)
90+
initializer_collections.each do |initializers|
91+
initializers.each(&method(:<<))
92+
end
93+
self
94+
end
95+
8396
def has?(name)
8497
@resolve.key?(name)
8598
end

railties/test/initializable_test.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,4 +277,64 @@ class OverriddenInitializerTest < ActiveSupport::TestCase
277277
assert_equal [1, 2, 3, 4], $arr
278278
end
279279
end
280+
281+
class CollectionTest < ActiveSupport::TestCase
282+
test "delegates missing to collection array" do
283+
initializable = Class.new do
284+
include Rails::Initializable
285+
end
286+
287+
Array.public_instance_methods.each do |method_name|
288+
assert(
289+
initializable.initializers.respond_to?(method_name),
290+
"Expected Initializable::Collection to respond to #{method_name}, but does not.",
291+
)
292+
end
293+
end
294+
295+
test "concat" do
296+
one = collection(:a, :b)
297+
two = collection(:c, :d)
298+
initializers = one.initializers.concat(two.initializers)
299+
initializer_names = initializers.tsort_each.map(&:name)
300+
301+
assert_equal [:a, :b, :c, :d], initializer_names
302+
end
303+
304+
test "push" do
305+
one = collection(:a, :b, :c)
306+
two = collection(:d)
307+
initializers = one.initializers.push(two.initializers.first)
308+
initializer_names = initializers.tsort_each.map(&:name)
309+
310+
assert_equal [:a, :b, :c, :d], initializer_names
311+
end
312+
313+
test "append" do
314+
one = collection(:a)
315+
two = collection(:b, :c)
316+
initializers = one.initializers.append(two.initializers.first)
317+
initializer_names = initializers.tsort_each.map(&:name)
318+
319+
assert_equal [:a, :b], initializer_names
320+
end
321+
322+
test "<<" do
323+
one = collection(:a, :b)
324+
two = collection(:c)
325+
initializers = (one.initializers << two.initializers.first)
326+
initializer_names = initializers.tsort_each.map(&:name)
327+
328+
assert_equal [:a, :b, :c], initializer_names
329+
end
330+
331+
private
332+
333+
def collection(*names)
334+
Class.new do
335+
include Rails::Initializable
336+
names.each { |name| initializer(name) { } }
337+
end
338+
end
339+
end
280340
end

0 commit comments

Comments
 (0)