1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
require 'test_helper'
require "uber/builder"
class BuilderTest < Minitest::Spec
Evergreen = Struct.new(:title)
Hit = Struct.new(:title)
class Song
include Uber::Builder
builds do |options|
if options[:evergreen]
Evergreen
elsif options[:hit]
Hit
end
end
def self.build(options)
build!(self, options).new
end
end
# building class if no block matches
it { Song.build({}).must_be_instance_of Song }
it { Song.build({evergreen: true}).must_be_instance_of Evergreen }
it { Song.build({hit: true}).must_be_instance_of Hit }
# test chained builds.
class Track
include Uber::Builder
builds do |options|
Evergreen if options[:evergreen]
end
builds do |options|
Hit if options[:hit]
end
def self.build(options)
build!(self, options).new
end
end
it { Track.build({}).must_be_instance_of Track }
it { Track.build({evergreen: true}).must_be_instance_of Evergreen }
it { Track.build({hit: true}).must_be_instance_of Hit }
# test inheritance. builder do not inherit.
class Play < Song
end
it { Play.build({}).must_be_instance_of Play }
it { Play.build({evergreen: true}).must_be_instance_of Play }
it { Play.build({hit: true}).must_be_instance_of Play }
# test return from builds
class Boomerang
include Uber::Builder
builds ->(options) do
return Song if options[:hit]
end
def self.build(options)
build!(self, options).new
end
end
it { Boomerang.build({}).must_be_instance_of Boomerang }
it { Boomerang.build({hit: true}).must_be_instance_of Song }
end
class BuilderScopeTest < Minitest::Spec
def self.builder_method(options)
options[:from_builder_method] and return self
end
class Hit; end
class Song
class Hit
end
include Uber::Builder
builds :builder_method # i get called first.
builds ->(options) do # and i second.
self::Hit
end
def self.build(context, options={})
build!(context, options)
end
end
it do
Song.build(self.class).must_equal BuilderScopeTest::Hit
# this runs BuilderScopeTest::builder_method and returns self.
Song.build(self.class, from_builder_method: true).must_equal BuilderScopeTest
end
class Evergreen
class Hit
end
include Uber::Builder
class << self
attr_writer :builders
end
self.builders = Song.builders
def self.build(context, options={})
build!(context, options)
end
def self.builder_method(options)
options[:from_builder_method] and return self
end
end
it do
# running the "copied" block in Evergreen will reference the correct @context.
Evergreen.build(Evergreen).must_equal BuilderScopeTest::Evergreen::Hit
Evergreen.build(Evergreen, from_builder_method: true).must_equal BuilderScopeTest::Evergreen
end
#---
# Builders API
# Builders#call
# Builders#<<
A = Class.new
MyBuilders = Uber::Builder::Builders.new
MyBuilders << ->(options) do
return Song if options[:hit]
end
it { MyBuilders.call(A, {}).new.must_be_instance_of A }
it { MyBuilders.call(A, { hit: true }).new.must_be_instance_of Song }
end
|