bricks 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +6 -0
- data/README.md +25 -0
- data/VERSION +1 -1
- data/bricks.gemspec +2 -2
- data/lib/bricks/builder.rb +58 -11
- data/spec/bricks/builder_spec.rb +16 -1
- data/spec/bricks_spec.rb +14 -0
- data/spec/support/active_record.rb +1 -0
- metadata +3 -3
data/History.md
CHANGED
data/README.md
CHANGED
@@ -18,6 +18,7 @@ We'll use the following domain to describe *Brick's* features:
|
|
18
18
|
# title :string(255)
|
19
19
|
# author :string(255)
|
20
20
|
# formatted_title :string(510)
|
21
|
+
# popularity :integer(4)
|
21
22
|
# publication_id :integer(4)
|
22
23
|
#
|
23
24
|
class Article < ActiveRecord::Base
|
@@ -244,6 +245,30 @@ Note that if you want to override a *-to-many association inside a trait, you ne
|
|
244
245
|
|
245
246
|
For an executable version of this documentation, please see spec/bricks_spec.rb.
|
246
247
|
|
248
|
+
### Hooks
|
249
|
+
|
250
|
+
*Bricks includes a simple, general hook framework. It allows you to do something like this:
|
251
|
+
|
252
|
+
builder Article
|
253
|
+
# ...
|
254
|
+
|
255
|
+
trait :on_the_bugle do
|
256
|
+
publication.name "The Daily Bugle"
|
257
|
+
popularity 75
|
258
|
+
end
|
259
|
+
|
260
|
+
trait :on_the_planet do
|
261
|
+
publication.name "The Daily Planet"
|
262
|
+
popularity 85
|
263
|
+
end
|
264
|
+
|
265
|
+
after :clone do
|
266
|
+
send %w(on_the_bugle on_the_planet)[rand(2)]
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
*Bricks* supports a single hook right now: after(:clone). It will be executed whenever you use any of #build, #build!, #create or #create!, right before you start customizing the resulting builder on your test.
|
271
|
+
|
247
272
|
Installation
|
248
273
|
------------
|
249
274
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/bricks.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bricks}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["David Leal"]
|
12
|
-
s.date = %q{2011-06-
|
12
|
+
s.date = %q{2011-06-29}
|
13
13
|
s.email = %q{david@mojotech.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE.txt",
|
data/lib/bricks/builder.rb
CHANGED
@@ -23,6 +23,12 @@ module Bricks
|
|
23
23
|
self
|
24
24
|
end
|
25
25
|
|
26
|
+
def after(hook, &block)
|
27
|
+
@traits.class_eval do
|
28
|
+
define_method "__after_#{hook}", &block
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
26
32
|
def derive(args = {})
|
27
33
|
build_attrs
|
28
34
|
|
@@ -30,7 +36,9 @@ module Bricks
|
|
30
36
|
save = args.has_key?(:save) ? args[:save] : @save
|
31
37
|
search = args.has_key?(:search) ? args[:search] : @search
|
32
38
|
|
33
|
-
Builder.new(klass, @attrs, @traits, save, search)
|
39
|
+
Builder.new(klass, @attrs, @traits, save, search).tap { |b|
|
40
|
+
b.run_hook :after, :clone if ! args[:class]
|
41
|
+
}
|
34
42
|
end
|
35
43
|
|
36
44
|
def initialize(
|
@@ -80,7 +88,8 @@ module Bricks
|
|
80
88
|
elsif settable?(attr)
|
81
89
|
set attr, *args, &block
|
82
90
|
else
|
83
|
-
raise Bricks::NoAttributeOrTrait,
|
91
|
+
raise Bricks::NoAttributeOrTrait,
|
92
|
+
"Can't find `#{name}' on builder for #{@class}."
|
84
93
|
end
|
85
94
|
|
86
95
|
if return_object
|
@@ -93,6 +102,14 @@ module Bricks
|
|
93
102
|
end
|
94
103
|
end
|
95
104
|
|
105
|
+
protected
|
106
|
+
|
107
|
+
def run_hook(position, name)
|
108
|
+
full_name = "__#{position}_#{name}"
|
109
|
+
|
110
|
+
send full_name if respond_to?(full_name)
|
111
|
+
end
|
112
|
+
|
96
113
|
private
|
97
114
|
|
98
115
|
def subject
|
@@ -113,23 +130,53 @@ module Bricks
|
|
113
130
|
obj.save!
|
114
131
|
end
|
115
132
|
|
116
|
-
|
117
|
-
obj
|
133
|
+
class Proxy
|
134
|
+
attr_reader :obj
|
135
|
+
|
136
|
+
def initialize(obj, attrs, parent)
|
137
|
+
@obj = obj
|
138
|
+
@attrs_in = attrs.dup
|
139
|
+
@attrs_out = {}
|
140
|
+
@parent = parent
|
141
|
+
end
|
118
142
|
|
119
|
-
|
120
|
-
|
143
|
+
def method_missing(name, *args)
|
144
|
+
name_y = name.to_sym
|
145
|
+
|
146
|
+
if @attrs_in.assoc(name_y) && ! @attrs_out.has_key?(name_y)
|
147
|
+
fix_attr name
|
148
|
+
else
|
149
|
+
@obj.send name, *args
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def build
|
154
|
+
@attrs_in.each { |(k, _)| send k }
|
155
|
+
|
156
|
+
@obj
|
157
|
+
end
|
158
|
+
|
159
|
+
def fix_attr(name)
|
160
|
+
val = case v = @attrs_in.assoc(name).last
|
121
161
|
when Proc
|
122
|
-
v.call
|
162
|
+
case r = v.call(*[self, @parent].take([v.arity, 0].max))
|
163
|
+
when Proxy
|
164
|
+
r.obj
|
165
|
+
else
|
166
|
+
r
|
167
|
+
end
|
123
168
|
when Builder, BuilderSet
|
124
|
-
v.generate(:parent =>
|
169
|
+
v.generate(:parent => self)
|
125
170
|
else
|
126
171
|
v
|
127
172
|
end
|
128
173
|
|
129
|
-
obj.send
|
130
|
-
|
174
|
+
@attrs_out[name] = @obj.send("#{name}=", val)
|
175
|
+
end
|
176
|
+
end
|
131
177
|
|
132
|
-
|
178
|
+
def initialize_object(parent)
|
179
|
+
Proxy.new(@class.new, @attrs, parent).build
|
133
180
|
end
|
134
181
|
|
135
182
|
def settable?(name)
|
data/spec/bricks/builder_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe Bricks::Builder do
|
|
11
11
|
}.new
|
12
12
|
|
13
13
|
class Person
|
14
|
-
attr_accessor :name
|
14
|
+
attr_accessor :name, :first_name, :last_name
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -38,4 +38,19 @@ describe Bricks::Builder do
|
|
38
38
|
|
39
39
|
b.generate.object_id.should_not == b.generate.object_id
|
40
40
|
end
|
41
|
+
|
42
|
+
describe "attribute evaluation ordering" do
|
43
|
+
before :all do
|
44
|
+
end
|
45
|
+
|
46
|
+
it "doesn't care which order the attributes are declared" do
|
47
|
+
b = Bricks::Builder.new Person do
|
48
|
+
name { |obj| obj.first_name + " " + obj.last_name }
|
49
|
+
first_name { "Jack" }
|
50
|
+
last_name { "Black" }
|
51
|
+
end
|
52
|
+
|
53
|
+
b.derive.generate.name.should == "Jack Black"
|
54
|
+
end
|
55
|
+
end
|
41
56
|
end
|
data/spec/bricks_spec.rb
CHANGED
@@ -44,6 +44,10 @@ describe Bricks do
|
|
44
44
|
|
45
45
|
%w(Tom Dick Harry).each { |n| readers.name(n) }
|
46
46
|
end
|
47
|
+
|
48
|
+
after :clone do
|
49
|
+
popularity (1..100).to_a[rand(100)]
|
50
|
+
end
|
47
51
|
end
|
48
52
|
|
49
53
|
builder Newspaper do
|
@@ -217,5 +221,15 @@ describe Bricks do
|
|
217
221
|
build!(Reader).should be_a(Reader)
|
218
222
|
end
|
219
223
|
end
|
224
|
+
|
225
|
+
describe "hooks" do
|
226
|
+
it "executes the `generate' hook after a builder is cloned" do
|
227
|
+
build!(Article).popularity.should_not == build!(Article).popularity
|
228
|
+
end
|
229
|
+
|
230
|
+
it "it does not override values set after the builder is cloned" do
|
231
|
+
build(Article).popularity!(50).popularity.should == 50
|
232
|
+
end
|
233
|
+
end
|
220
234
|
end
|
221
235
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: bricks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.5.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David Leal
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-06-
|
13
|
+
date: 2011-06-29 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -101,7 +101,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
101
101
|
requirements:
|
102
102
|
- - ">="
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
hash: -
|
104
|
+
hash: -614702947
|
105
105
|
segments:
|
106
106
|
- 0
|
107
107
|
version: "0"
|