Skip to content

Commit

Permalink
ensure that recusive message rendering works
Browse files Browse the repository at this point in the history
  • Loading branch information
skatkov committed Nov 2, 2023
1 parent f87e730 commit 456c283
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 12 deletions.
6 changes: 3 additions & 3 deletions lib/pbbuilder/collection_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ def build_rendered_template(content, template, layout = nil)
end

def build_rendered_collection(templates, _spacer)
pb_root.set!(field, templates.map(&:body))
pb_parent.set!(field, templates.map(&:body))
end

def pb
@options[:locals].fetch(:pb)
end

def pb_root
@options[:locals].fetch(:pb_root)
def pb_parent
@options[:locals].fetch(:pb_parent)
end

def field
Expand Down
9 changes: 6 additions & 3 deletions lib/pbbuilder/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@ def set!(field, *args, **kwargs, &block)
collection = options[:collection] || []
partial = options[:partial]

# The way recursive rendering works is that CollectionRenderer needs to be aware of node its currently rendering and parent node,
# these is no need to know entire "stack" of nodes. CollectionRenderer would traverse to bottom node render that first and then go up in stack.

# CollectionRenderer uses locals[:pb] to render the partial as a protobuf message,
# but also needs locals[:pb_root] to apply rendered partial to top level protobuf message.
# but also needs locals[:pb_parent] to apply rendered partial to top level protobuf message.

# This logic could be found in CollectionRenderer#build_rendered_collection method that we overwrote.
# This logic could be found in CollectionRenderer#build_rendered_collection method that we over wrote.
options[:locals].merge!(pb: ::PbbuilderTemplate.new(@context, new_message_for(field)))
options[:locals].merge!(pb_root: self)
options[:locals].merge!(pb_parent: self)
options[:locals].merge!(field: field)

if options.has_key?(:layout)
Expand Down
16 changes: 10 additions & 6 deletions test/pbbuilder_template_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,19 @@ class PbbuilderTemplateTest < ActiveSupport::TestCase
end

test "render collections with partial as kwarg" do
result = render('pb.friends partial: "racers/racer", as: :racer, collection: [Racer.new(1, "Johnny Test", [], nil, API::Asset.new(url: "https://google.com/test.svg")), Racer.new(2, "Max Verstappen", [])]')
template = <<-PBBUILDER
more_friends = [Racer.new(4, "Johnny Brave", [], nil, API::Asset.new(url: "https://google.com/test3.svg"))]
friends_of_racer = [Racer.new(3, "Chris Harris", more_friends, nil, API::Asset.new(url: "https://google.com/test2.svg"))]
racers = [Racer.new(1, "Johnny Test", friends_of_racer, nil, API::Asset.new(url: "https://google.com/test1.svg")), Racer.new(2, "Max Verstappen", [])]
pb.friends partial: "racers/racer", as: :racer, collection: racers
PBBUILDER
result = render(template)

assert_equal 2, result.friends.count
assert_nil result.logo
result.friends.first.logo.tap do |logo|
assert_equal "https://google.com/test.svg", logo.url
assert_equal "https://google.com/test.svg", logo.url_2x
assert_equal "https://google.com/test.svg", logo.url_3x
end
assert_equal "https://google.com/test1.svg", result.friends.first.logo.url
assert_equal "https://google.com/test2.svg", result.friends.first.friends.first.logo.url
assert_equal "https://google.com/test3.svg", result.friends.first.friends.first.friends.first.logo.url
end

test "CollectionRenderer: raises an error on a render with :layout option" do
Expand Down

0 comments on commit 456c283

Please sign in to comment.