File: builder_test.rb

package info (click to toggle)
ruby-uber 0.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 216 kB
  • sloc: ruby: 466; makefile: 4
file content (147 lines) | stat: -rw-r--r-- 3,222 bytes parent folder | download
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