-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathminifacture.rb
54 lines (48 loc) · 1.66 KB
/
minifacture.rb
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
require 'active_support/inflector'
require 'active_support/core_ext/hash'
# Factory girl, relaxed.
#
# Factory.define :user do |f|
# f.login 'johndoe%d' # Sequence.
# f.email '%{login}@example.com' # Interpolate.
# f.password f.password_confirmation('foobar') # Chain.
# end
#
# Factory.define :post do |f|
# f.user { Factory :user } # Blocks, if you must.
# end
class Minifacture < Struct.new(:__klass__)
undef_method *instance_methods.grep(/^(?!__|object_id)/)
@@attrs = {} and @@counts = Hash.new(0) and private_class_method :new
class << self
def define name, options = {}
@@attrs[name = name.to_s] = [{}, options] and yield new(name)
end
def build name, attrs = {}
(h, opts, n = @@attrs[name = name.to_s]) and m = opts[:class] || name
p = opts[:parent] and (h, m = @@attrs[p = p.to_s][0].merge(h), p)
(m = m.is_a?(Class) ? m : m.to_s.camelize.constantize).new.tap do |r|
c = @@counts[p || name] += 1
attrs.symbolize_keys!.reverse_update(h).each do |k, v|
r.send "#{k}=", case v when String # Sequence and interpolate.
v.sub(/%\d*d/) { |d| d % n ||= c } % attrs % n
when Proc then v.call(r) else v
end
end
end
end
def create name, attrs = {}
build(name, attrs).tap { |record| record.save! }
end
end
def method_missing name, value = nil, &block
@@attrs[__klass__][0][name] = block || value
end
end
def Minifacture name, attrs = {}
Minifacture.create(name, attrs)
end
unless Object.const_defined? :Factory
Factory = Minifacture
alias Factory Minifacture
end