uber 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f71a66b9f3f5b51c0ceb68c2aa396d9f1571d28b
4
- data.tar.gz: 243f81afa103da2cc3b1c2d8f9d1445b9acf8013
3
+ metadata.gz: d35993c8fa8e0378bda6e3207c7a34c79fcaf901
4
+ data.tar.gz: 57e3c7e6251134b7c38f4e946768f795d842da1e
5
5
  SHA512:
6
- metadata.gz: c67f0fe6bf6fe588af3848e9a243f4fe5ca2857468c7ccdf9e0100e3a94b717a923e395ec77c2cc31edb301593663f8de6483f06f7cfb6cf53fb603cea1b43a9
7
- data.tar.gz: 4c3ef47a30140dc3191d582e678a28362477ec0786ab30194f9434e26ced92bc12ce937385a7848918e715b22218ea7c12329e17bb5f64e65d171f85dd48d730
6
+ metadata.gz: 02482631941669e1ce796a484b4876e3b9e82dc1a163935579b6ce46acba7a6533ad0b3655df7cb455bec8ac723108ca256c0effb6895a759a584b2e9dd559b4
7
+ data.tar.gz: 47e7927839f0d30ba4ef9ea11e400b114744d65ade257036d8f018476c17a4ada0bfdaed5c2667d4cd7336987c424d2d298b55717ca5fe8b751ff751b8127023
data/CHANGES.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.0.15
2
+
3
+ * `Value#evaluate` is now `#call`. This will make it easier to introduce Null objects.
4
+ * Options passed to `::builds` are now wrapped in `Uber::Options::Value` which allows specifying builder _class methods_ using `builds :builder_method`.
5
+ * `Builder::class_builder` now accepts an optional context object which is used to `instance_exec` the builder blocks. This allows to share predefined builder blocks between different classes while resolving the constants in the respective class.
6
+
1
7
  # 0.0.14
2
8
 
3
9
  * Add `inheritable_attr :title, clone: false`. Thanks to @katafrakt.
data/README.md CHANGED
@@ -222,7 +222,7 @@ Note how `#title` calls the original title and then downcases the string.
222
222
  When included, `Builder` allows to add builder instructions on the class level. These can then be evaluated when instantiating
223
223
  the class to conditionally build (sub-)classes based on the incoming parameters.
224
224
 
225
- Builders can be defined in two different ways.
225
+ Builders can be defined in three different ways.
226
226
 
227
227
  ## Block Syntax
228
228
 
@@ -271,6 +271,33 @@ end
271
271
 
272
272
  This makes the block extremely readable.
273
273
 
274
+ ## Method Syntax
275
+
276
+ You can also specify a build method.
277
+
278
+ ```ruby
279
+ build :build_method
280
+
281
+ def self.build_method(params)
282
+ return SignedIn if params[:current_user]
283
+ end
284
+ ```
285
+
286
+ The method has to be a class method on the building class.
287
+
288
+ ## Build Context
289
+
290
+ Normally, build blocks and methods are run in the context where they were defined in. You can change that by passing any context object to `class_builder`.
291
+
292
+ ```ruby
293
+ def self.build(params)
294
+ class_builder(context_object) # ...
295
+ end
296
+ ```
297
+
298
+ This allows copying builders to other classes and evaluate blocks in the new context.
299
+
300
+ ## More On Builders
274
301
 
275
302
  Note that builders are _not_ inherited to subclasses. This allows instantiating subclasses directly without running builders.
276
303
 
@@ -1,3 +1,5 @@
1
+ require "uber/options"
2
+
1
3
  module Uber
2
4
  # When included, allows to add builder on the class level.
3
5
  #
@@ -28,9 +30,11 @@ module Uber
28
30
  end
29
31
  end
30
32
 
33
+ # Computes the concrete target class.
31
34
  class Constant
32
- def initialize(constant) # TODO: evaluate usage of builders and implement using Uber::Options::Value.
35
+ def initialize(constant, context)
33
36
  @constant = constant
37
+ @context = context
34
38
  @builders = @constant.builders # only dependency, must be a Cell::Base subclass.
35
39
  end
36
40
 
@@ -47,7 +51,7 @@ module Uber
47
51
  end
48
52
 
49
53
  def run_builder_block(block, *args)
50
- block.call(*args)
54
+ block.(@context, *args) # Uber::Value.call()
51
55
  end
52
56
  end
53
57
 
@@ -78,13 +82,15 @@ module Uber
78
82
  # AdminUserBox if model.admin?
79
83
  # end
80
84
  #
81
- # In your view #cell will instantiate the right cell for you now.
85
+ # In your view #cell will instantiate the right class for you now.
82
86
  def builds(proc=nil, &block)
83
- builders << (proc.kind_of?(Proc) ? proc : block)
87
+ builders << Uber::Options::Value.new(proc.nil? ? block : proc) # TODO: provide that in Uber::O:Value.
84
88
  end
85
89
 
86
- def class_builder
87
- @class_builder ||= Constant.new(self)
90
+ # Call this from your classes' own ::build method to compute the concrete target class.
91
+ # The class_builder is cached, you can't change the context once it's set.
92
+ def class_builder(context=nil)
93
+ @class_builder ||= Constant.new(self, context)
88
94
  end
89
95
  end # ClassMethods
90
96
  end
@@ -54,11 +54,12 @@ module Uber
54
54
  @dynamic = @proc || @callable || @method
55
55
  end
56
56
 
57
- def evaluate(context, *args)
57
+ def call(context, *args)
58
58
  return @value unless dynamic?
59
59
 
60
60
  evaluate_for(context, *args)
61
61
  end
62
+ alias_method :evaluate, :call
62
63
 
63
64
  def dynamic?
64
65
  @dynamic
@@ -1,3 +1,3 @@
1
1
  module Uber
2
- VERSION = "0.0.14"
2
+ VERSION = "0.0.15"
3
3
  end
@@ -72,4 +72,67 @@ class BuilderTest < MiniTest::Spec
72
72
 
73
73
  it { Boomerang.build({}).must_be_instance_of Boomerang }
74
74
  it { Boomerang.build({hit: true}).must_be_instance_of Song }
75
+ end
76
+
77
+
78
+ class BuilderScopeTest < MiniTest::Spec
79
+ def self.builder_method(options)
80
+ options[:from_builder_method] and return self
81
+ end
82
+
83
+ class Hit; end
84
+
85
+ class Song
86
+ class Hit
87
+ end
88
+
89
+ include Uber::Builder
90
+
91
+ builds :builder_method # i get called first.
92
+ builds ->(options) do # and i second.
93
+ self::Hit
94
+ end
95
+
96
+ def self.build(context, options={})
97
+ class_builder(context).call(options)
98
+ end
99
+ end
100
+
101
+ class Evergreen
102
+ class Hit
103
+ end
104
+
105
+ include Uber::Builder
106
+
107
+ class << self
108
+ attr_writer :builders
109
+ end
110
+ self.builders = Song.builders
111
+
112
+ def self.build(context, options={})
113
+ class_builder(context).call(options)
114
+ end
115
+
116
+ def self.builder_method(options)
117
+ options[:from_builder_method] and return self
118
+ end
119
+ end
120
+
121
+ it do
122
+ Song.build(self.class).must_equal BuilderScopeTest::Hit
123
+
124
+ # this runs BuilderScopeTest::builder_method and returns self.
125
+ Song.build(self.class, from_builder_method: true).must_equal BuilderScopeTest
126
+
127
+ # since the class_builder gets cached, this won't change.
128
+ Song.build(Song).must_equal BuilderScopeTest::Hit
129
+ end
130
+
131
+
132
+ it do
133
+ # running the "copied" block in Evergreen will reference the correct @context.
134
+ Evergreen.build(Evergreen).must_equal BuilderScopeTest::Evergreen::Hit
135
+
136
+ Evergreen.build(Evergreen, from_builder_method: true).must_equal BuilderScopeTest::Evergreen
137
+ end
75
138
  end
@@ -25,24 +25,28 @@ class UberOptionTest < MiniTest::Spec
25
25
  it { Value.new(Callable.new).dynamic?.must_equal true }
26
26
  end
27
27
 
28
- describe "#evaluate" do
28
+ describe "#call" do
29
29
  let (:version) { Module.new { def version; 999 end } }
30
30
 
31
- it { Value.new(nil).evaluate(Object.new).must_equal nil }
32
- # it { Value.new(nil, :dynamic => true).evaluate(Object.new).must_equal nil } # DISCUSS: should we handle that?
31
+ it { Value.new(nil).(Object.new).must_equal nil }
32
+ # it { Value.new(nil, :dynamic => true).(Object.new).must_equal nil } # DISCUSS: should we handle that?
33
33
 
34
- it { Value.new(true).evaluate(Object.new).must_equal true }
34
+ it { Value.new(true).(Object.new).must_equal true }
35
35
 
36
- it { Value.new(:version).evaluate(object.extend(version)).must_equal 999 }
37
- it { Value.new("version", :dynamic => true).evaluate(object.extend(version)).must_equal 999 }
38
- it { Value.new(:version, :dynamic => false).evaluate(object.extend(version)).must_equal :version }
39
- it { Value.new(lambda { self }).evaluate(object).must_equal object }
40
- it { Value.new(lambda { self }).evaluate(nil).must_equal self }
36
+ it { Value.new(:version).(object.extend(version)).must_equal 999 }
37
+ it { Value.new("version", :dynamic => true).(object.extend(version)).must_equal 999 }
38
+ it { Value.new(:version, :dynamic => false).(object.extend(version)).must_equal :version }
39
+ it { Value.new(lambda { self }).(object).must_equal object }
40
+ it { Value.new(lambda { self }).(nil).must_equal self }
41
41
 
42
- it { Value.new(lambda { :loud }, :dynamic => true).evaluate(object).must_equal :loud }
42
+ it { Value.new(lambda { :loud }, :dynamic => true).(object).must_equal :loud }
43
43
 
44
44
  # Uber::Callable
45
- it { Value.new(Callable.new).evaluate(nil).must_equal 999 }
45
+ it { Value.new(Callable.new).(nil).must_equal 999 }
46
+ end
47
+
48
+ it "#call is aliased to evaluate" do
49
+ Value.new(Callable.new).(nil).must_equal 999
46
50
  end
47
51
 
48
52
  describe "passing options" do
@@ -50,9 +54,9 @@ class UberOptionTest < MiniTest::Spec
50
54
  let (:block) { Proc.new { |*args| args.inspect } }
51
55
  let (:callable) { (Class.new { include Uber::Callable; def call(*args); args.inspect; end }).new }
52
56
 
53
- it { Value.new(:version).evaluate(object.extend(version), 1, 2, 3).must_equal "[1, 2, 3]" }
54
- it { Value.new(block).evaluate(object, 1, 2, 3).must_equal "[1, 2, 3]" }
55
- it { Value.new(callable).evaluate(Object, 1, 2, 3).must_equal "[Object, 1, 2, 3]" }
57
+ it { Value.new(:version).(object.extend(version), 1, 2, 3).must_equal "[1, 2, 3]" }
58
+ it { Value.new(block).(object, 1, 2, 3).must_equal "[1, 2, 3]" }
59
+ it { Value.new(callable).(Object, 1, 2, 3).must_equal "[Object, 1, 2, 3]" }
56
60
  end
57
61
 
58
62
  # it "speed" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-14 00:00:00.000000000 Z
11
+ date: 2015-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake