Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion lib/uber/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ def initialize(constant, context)
end

def call(*args)
build_class_for(*args)
kls = build_class_for(*args)
return kls if kls == @constant
return kls unless kls.include?(Uber::Builder)
kls.class_builder.call(*args)
end

private
Expand Down
62 changes: 60 additions & 2 deletions test/builder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class Boomerang
include Uber::Builder

builds ->(options) do
return Song if options[:hit]
return Song if options[:song]
end

def self.build(options)
Expand All @@ -71,7 +71,7 @@ def self.build(options)
end

it { Boomerang.build({}).must_be_instance_of Boomerang }
it { Boomerang.build({hit: true}).must_be_instance_of Song }
it { Boomerang.build({song: true}).must_be_instance_of Song }
end


Expand Down Expand Up @@ -135,4 +135,62 @@ def self.builder_method(options)

Evergreen.build(Evergreen, from_builder_method: true).must_equal BuilderScopeTest::Evergreen
end
end


class DeeplyNestedBuilderTest < MiniTest::Spec
class FromOutside
end

class Parent
include Uber::Builder

builds ->(params) do
return Sub if params[:sub]
end

def self.build(options)
class_builder.call(options).new
end

class Sub < self

builds ->(params) do
return DeepSub if params[:deep_sub]
return FromOutside if params[:outside]
end

class DeepSub < self

builds do |params|
if params[:very_deep_sub]
VeryDeepSub
elsif params[:outside]
FromOutside
end
end

class VeryDeepSub < self
# and I can go even further!!!!
end
end
end
end

it { Parent.build({}).must_be_instance_of Parent }
it { Parent.build({sub: true})
.must_be_instance_of Parent::Sub }
it { Parent.build({sub: true, deep_sub: true})
.must_be_instance_of Parent::Sub::DeepSub }
it { Parent.build({sub: true, deep_sub: true, very_deep_sub: true})
.must_be_instance_of Parent::Sub::DeepSub::VeryDeepSub }

# calling a class that's not inherited
it { Parent.build({outside: true}).must_be_instance_of Parent }
it { Parent.build({sub: true, outside: true})
.must_be_instance_of FromOutside }
it { Parent.build({sub: true, deep_sub: true, outside: true})
.must_be_instance_of FromOutside }
it { Parent.build({sub: true, deep_sub: true, very_deep_sub: true, outside: true})
.must_be_instance_of Parent::Sub::DeepSub::VeryDeepSub }
end