blueprints 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +82 -18
- data/LICENSE +1 -1
- data/README.rdoc +38 -8
- data/Rakefile +11 -35
- data/blueprints.gemspec +29 -123
- data/features/support/env.rb +7 -10
- data/lib/blueprints.rb +68 -12
- data/lib/blueprints/blueprint.rb +39 -19
- data/lib/blueprints/buildable.rb +92 -74
- data/lib/blueprints/configuration.rb +18 -4
- data/lib/blueprints/context.rb +148 -5
- data/lib/blueprints/database_cleaner_fix.rb +9 -0
- data/lib/blueprints/dependency.rb +32 -21
- data/lib/blueprints/eval_context.rb +51 -0
- data/lib/blueprints/extensions.rb +115 -0
- data/lib/blueprints/extensions/rspec.rb +3 -1
- data/lib/blueprints/helper.rb +52 -20
- data/lib/blueprints/namespace.rb +31 -12
- data/lib/blueprints/root_namespace.rb +24 -25
- data/lib/blueprints/version.rb +3 -0
- data/spec/{active_record/blueprint.rb → blueprint.rb} +14 -17
- data/spec/{active_record/blueprints_spec.rb → blueprints_spec.rb} +40 -59
- data/spec/spec_helper.rb +34 -0
- data/spec/support/active_record/database.yml.example +7 -0
- data/spec/support/active_record/initializer.rb +15 -0
- data/spec/{active_record/fixtures → support/active_record}/schema.rb +0 -0
- data/spec/support/dm-core/initializer.rb +31 -0
- data/spec/support/mongo_mapper/database.yml.example +2 -0
- data/spec/support/mongo_mapper/initializer.rb +20 -0
- data/spec/support/mongoid/database.yml.example +2 -0
- data/spec/support/mongoid/initializer.rb +23 -0
- data/spec/support/none/initializer.rb +63 -0
- data/spec/unit/active_record_spec.rb +1 -6
- data/spec/unit/blueprint_spec.rb +91 -20
- data/spec/unit/blueprints_spec.rb +44 -0
- data/spec/unit/buildable_spec.rb +37 -6
- data/spec/unit/configuration_spec.rb +11 -0
- data/spec/unit/context_spec.rb +100 -0
- data/spec/unit/dependency_spec.rb +24 -19
- data/spec/unit/eval_context_spec.rb +56 -0
- data/spec/unit/fixtures.rb +61 -0
- data/spec/unit/namespace_spec.rb +59 -11
- data/spec/unit/spec_helper.rb +8 -16
- data/test/blueprints_test.rb +40 -59
- data/test/test_helper.rb +6 -16
- data/test_all.sh +45 -0
- metadata +178 -61
- data/VERSION +0 -1
- data/lib/blueprints/core_ext.rb +0 -69
- data/lib/blueprints/file_context.rb +0 -37
- data/spec/active_record/fixtures/database.yml.example +0 -8
- data/spec/active_record/fixtures/fruit.rb +0 -3
- data/spec/active_record/fixtures/tree.rb +0 -4
- data/spec/active_record/spec_helper.rb +0 -37
- data/spec/no_db/blueprint.rb +0 -9
- data/spec/no_db/blueprints_spec.rb +0 -45
- data/spec/no_db/fixtures/fruit.rb +0 -15
- data/spec/no_db/spec_helper.rb +0 -14
- data/spec/test_all.sh +0 -39
@@ -1,10 +1,12 @@
|
|
1
1
|
module DescribeHelper
|
2
2
|
# Creates new before filter that builds blueprints before each spec.
|
3
|
+
# @param names (see Helper#build)
|
3
4
|
def build_blueprint(*names)
|
4
5
|
before { build_blueprint *names }
|
5
6
|
end
|
6
7
|
|
7
|
-
# Same as #build_blueprint except that you can use it to build same blueprint several times.
|
8
|
+
# Same as DescribeHelper#build_blueprint except that you can use it to build same blueprint several times.
|
9
|
+
# @param names (see Helper#build)
|
8
10
|
def build_blueprint!(*names)
|
9
11
|
before { build_blueprint! *names }
|
10
12
|
end
|
data/lib/blueprints/helper.rb
CHANGED
@@ -2,42 +2,74 @@ module Blueprints
|
|
2
2
|
# A helper module that should be included in test framework. Adds methods <tt>build</tt> and <tt>demolish</tt>
|
3
3
|
module Helper
|
4
4
|
# Builds one or more blueprints by their names. You can pass names as symbols or strings. You can also pass additional
|
5
|
-
# options hash which will be available by calling <tt>options</tt> in blueprint block. Returns result of blueprint block.
|
6
|
-
#
|
5
|
+
# options hash which will be available by calling <tt>options</tt> in blueprint block. Returns result of last blueprint block.
|
6
|
+
# @example build :apple and :orange blueprints.
|
7
7
|
# build :apple, :orange
|
8
|
-
#
|
9
|
-
# # build :apple scenario with additional options
|
8
|
+
# @example build :apple blueprint with additional options.
|
10
9
|
# build :apple => {:color => 'red'}
|
11
|
-
#
|
12
|
-
# # options can also be passed for several blueprints
|
10
|
+
# @example passing options to several blueprints.
|
13
11
|
# build :pear, :apple => {:color => 'red'}, :orange => {:color => 'orange'}
|
14
|
-
|
12
|
+
# @param [Array<Symbol, String, Hash>] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
|
13
|
+
# @return Return value of last blueprint
|
14
|
+
def build(*names)
|
15
15
|
Namespace.root.build(names, self, true)
|
16
16
|
end
|
17
17
|
|
18
|
-
# Same as #
|
19
|
-
|
20
|
-
|
18
|
+
# Same as #build except that you can use it to build same blueprint several times.
|
19
|
+
# @overload build!(*names)
|
20
|
+
# @param [Array<Symbol, String, Hash>] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
|
21
|
+
# @return Return value of last blueprint
|
22
|
+
# @overload build!(count, *names)
|
23
|
+
# @param [Integer] count Times to build passed blueprint
|
24
|
+
# @param [Array<Symbol, String, Hash>] names Names of blueprints/namespaces to build. Pass Hash if you want to pass additional options.
|
25
|
+
# @return [Array] Array of return values of last blueprint, which is same size as count that you pass
|
26
|
+
def build!(*names)
|
27
|
+
if names.first.is_a?(Integer)
|
28
|
+
(0...names.shift).collect { build! *names }
|
29
|
+
else
|
30
|
+
Namespace.root.build(names, self, false)
|
31
|
+
end
|
21
32
|
end
|
22
33
|
|
23
|
-
# Returns attributes that are used to build blueprint.
|
24
|
-
#
|
25
|
-
# blueprint
|
34
|
+
# Returns attributes that are used to build blueprint.
|
35
|
+
# @example Setting and retrieving attributes.
|
36
|
+
# # In blueprint.rb file
|
37
|
+
# attributes(:name => 'apple').blueprint :apple do
|
26
38
|
# Fruit.build attributes
|
27
|
-
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# # In spec/test file
|
42
|
+
# build_attributes :apple #=> {:name => 'apple'}
|
43
|
+
# @param [Symbol, String] name Name of blueprint/namespace.
|
44
|
+
# @return [Hash] Normalized attributes of blueprint/namespace
|
28
45
|
def build_attributes(name)
|
29
|
-
Namespace.root[name]
|
30
|
-
|
46
|
+
blueprint = Namespace.root[name]
|
47
|
+
blueprint.build_parents(Namespace.root.eval_context)
|
48
|
+
Namespace.root.eval_context.normalize_hash(blueprint.attributes).tap { Namespace.root.eval_context.copy_instance_variables(self) }
|
31
49
|
end
|
32
50
|
|
33
|
-
|
34
|
-
|
51
|
+
# Returns Blueprint::Dependency object that can be used to define dependencies on other blueprints.
|
52
|
+
# @example Building :post blueprint with different user.
|
53
|
+
# build :post => {:user => d(:admin)}
|
54
|
+
# @example Building :post blueprint by first building :user_profile with :name => 'John', then taking value of @profile and calling +user+ on it.
|
55
|
+
# build :post => {:user => d(:user_profile, :profile, :name => 'John').user}
|
56
|
+
# @see Blueprints::Dependency#initialize Blueprints::Dependency for accepted arguments.
|
57
|
+
# @return [Blueprints::Dependency] Dependency object that can be passed as option when building blueprint/namespace.
|
58
|
+
def d(*args)
|
59
|
+
Dependency.new(*args)
|
60
|
+
end
|
35
61
|
|
36
62
|
# Demolishes built blueprints (by default simply calls destroy method on result of blueprint, but can be customized).
|
37
|
-
#
|
63
|
+
# @example Demolish :apple and :pear blueprints
|
38
64
|
# demolish :apple, :pear
|
65
|
+
# @param [Array<Symbol, String>] names Names of blueprints/namespaces to demolish.
|
39
66
|
def demolish(*names)
|
40
|
-
names.each { |name| Namespace.root[name].demolish }
|
67
|
+
names.each { |name| Namespace.root[name].demolish(Namespace.root.eval_context) }
|
41
68
|
end
|
69
|
+
|
70
|
+
alias :build_blueprint :build
|
71
|
+
alias :build_blueprint! :build!
|
72
|
+
alias :blueprint_dependency :d
|
73
|
+
alias :blueprint_demolish :demolish
|
42
74
|
end
|
43
75
|
end
|
data/lib/blueprints/namespace.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Blueprints
|
2
|
-
# Namespace class, inherits from
|
2
|
+
# Namespace class, inherits from Buildable. Allows adding and finding child blueprints/namespaces and building
|
3
3
|
# all it's children.
|
4
4
|
class Namespace < Buildable
|
5
5
|
cattr_accessor :root
|
@@ -7,20 +7,27 @@ module Blueprints
|
|
7
7
|
delegate :empty?, :size, :to => :@children
|
8
8
|
|
9
9
|
# Creates namespace by name. See Buildable#new.
|
10
|
-
|
11
|
-
|
10
|
+
# @param name (see Buildable#initialize)
|
11
|
+
# @param context (see Buildable#initialize)
|
12
|
+
def initialize(name, context)
|
12
13
|
@children = {}
|
14
|
+
super(name, context)
|
13
15
|
end
|
14
16
|
|
15
|
-
# Adds child to namespaces children.
|
17
|
+
# Adds child to namespaces children. Warns if this will overwrite existing child.
|
18
|
+
# @param [Blueprints::Buildable] child Namespace or blueprint to add as a child.
|
16
19
|
def add_child(child)
|
20
|
+
Blueprints.warn("Overwriting existing blueprint", child) if @children[child.name]
|
17
21
|
@children[child.name] = child
|
18
|
-
child.namespace = self
|
19
22
|
end
|
20
23
|
|
21
|
-
# Finds child by relative name.
|
24
|
+
# Finds child by relative name.
|
25
|
+
# @param [String] path Path to child. Path parts should be joined with '.' symbol.
|
26
|
+
# @return [Blueprints::Buildable] Blueprint or namespace that matches path.
|
27
|
+
# @raise [BlueprintNotFoundError] If child can't be found.
|
22
28
|
def [](path)
|
23
29
|
child_name, path = path.to_s.split('.', 2)
|
30
|
+
|
24
31
|
child = @children[child_name.to_sym] or raise BlueprintNotFoundError, child_name
|
25
32
|
if path
|
26
33
|
child[path]
|
@@ -29,14 +36,26 @@ module Blueprints
|
|
29
36
|
end
|
30
37
|
end
|
31
38
|
|
32
|
-
# Builds all children and sets instance variable named by name of namespace with the results.
|
33
|
-
|
34
|
-
|
39
|
+
# Builds all children and sets an instance variable named by name of namespace with the results.
|
40
|
+
# @param eval_context (see Buildable#build)
|
41
|
+
# @param build_once (see Buildable#build)
|
42
|
+
# @param options (see Buildable#build)
|
43
|
+
# @return [Array] Results of all blueprints.
|
44
|
+
def build_self(eval_context, build_once, options)
|
45
|
+
result(eval_context) { @children.values.collect { |child| child.build(eval_context, build_once, options) }.uniq }
|
46
|
+
end
|
47
|
+
|
48
|
+
# Demolishes all child blueprints and namespaces.
|
49
|
+
# @param [Blueprints::EvalContext] eval_context Eval context that this namespace was built in.
|
50
|
+
def demolish(eval_context)
|
51
|
+
@children.each_value { |blueprint| blueprint.demolish(eval_context) }
|
35
52
|
end
|
36
53
|
|
37
|
-
|
38
|
-
|
39
|
-
|
54
|
+
protected
|
55
|
+
|
56
|
+
def update_context(options)
|
57
|
+
@children.each_value { |child| child.update_context(options) }
|
58
|
+
super
|
40
59
|
end
|
41
60
|
end
|
42
61
|
end
|
@@ -1,68 +1,67 @@
|
|
1
|
+
|
1
2
|
module Blueprints
|
2
3
|
# Defines a root namespace that is used when no other namespace is. Apart from functionality in namespace it also allows
|
3
4
|
# building blueprints/namespaces by name. Is also used for copying instance variables between blueprints/contexts/global
|
4
5
|
# context.
|
5
6
|
class RootNamespace < Namespace
|
6
|
-
|
7
|
+
# Lists of executed blueprints (to prevent executing twice). Cleared before each test.
|
8
|
+
attr_reader :executed_blueprints
|
9
|
+
# Context that blueprints/namespaces are built against. Reset before each test.
|
10
|
+
attr_writer :eval_context
|
7
11
|
|
12
|
+
# Initialized new root context.
|
8
13
|
def initialize
|
9
14
|
@executed_blueprints = @global_executed_blueprints = []
|
10
15
|
@auto_iv_list = Set.new
|
11
16
|
|
12
|
-
super ''
|
17
|
+
super '', Context.new
|
13
18
|
end
|
14
19
|
|
15
|
-
# Loads all instance variables from global context to current one.
|
20
|
+
# Loads all instance variables from global context to current one. Creates new eval context.
|
16
21
|
def setup
|
22
|
+
@eval_context = EvalContext.new
|
17
23
|
(@executed_blueprints - @global_executed_blueprints).each(&:undo!)
|
18
24
|
@executed_blueprints = @global_executed_blueprints.clone
|
19
|
-
@context = Blueprints::Context.new
|
20
25
|
|
21
26
|
if Blueprints.config.transactions
|
22
|
-
Marshal.load(@global_variables).each { |name, value|
|
27
|
+
Marshal.load(@global_variables).each { |name, value| eval_context.instance_variable_set(name, value) }
|
23
28
|
else
|
24
29
|
build(Blueprints.config.prebuild)
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
28
|
-
# Copies all instance variables from current context to another one.
|
29
|
-
def copy_ivars(to)
|
30
|
-
@context.instance_variables.each do |iv|
|
31
|
-
to.instance_variable_set(iv, @context.instance_variable_get(iv))
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
33
|
# Sets up global context and executes prebuilt blueprints against it.
|
34
|
+
# @param [Array<Symbol, String>] blueprints Names of blueprints that are prebuilt.
|
36
35
|
def prebuild(blueprints)
|
37
|
-
@context = Blueprints::Context.new
|
38
36
|
build(blueprints) if blueprints
|
39
37
|
|
40
38
|
@global_executed_blueprints = @executed_blueprints
|
41
|
-
@global_variables = Marshal.dump(
|
39
|
+
@global_variables = Marshal.dump(eval_context.instance_variables.each_with_object({}) { |iv, hash| hash[iv] = eval_context.instance_variable_get(iv) })
|
42
40
|
end
|
43
41
|
|
44
42
|
# Builds blueprints that are passed against current context. Copies instance variables to context given if one is given.
|
45
|
-
|
43
|
+
# @param [Array<Symbol, String>] names List of blueprints/namespaces to build.
|
44
|
+
# @param current_context Object to copy instance variables from eval context after building to.
|
45
|
+
# @param build_once (see Buildable.build)
|
46
|
+
# @return Result of last blueprint/namespace.
|
47
|
+
def build(names, current_context = nil, build_once = true)
|
46
48
|
names = [names] unless names.is_a?(Array)
|
47
49
|
result = names.inject(nil) do |result, member|
|
48
50
|
if member.is_a?(Hash)
|
49
|
-
member.map { |name, options| self[name].build(build_once, options) }.last
|
51
|
+
member.map { |name, options| self[name].build(eval_context, build_once, options) }.last
|
50
52
|
else
|
51
|
-
self[member].build(build_once)
|
53
|
+
self[member].build(eval_context, build_once)
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
|
-
|
57
|
+
eval_context.copy_instance_variables(current_context) if current_context
|
56
58
|
result
|
57
59
|
end
|
58
60
|
|
59
|
-
#
|
60
|
-
#
|
61
|
-
def
|
62
|
-
|
63
|
-
@auto_iv_list << name
|
64
|
-
@context.instance_variable_set(name, value)
|
65
|
-
end
|
61
|
+
# Return current eval context or creates a new one.
|
62
|
+
# @return [Blueprints::EvalContext] Eval context to be used to build blueprints.
|
63
|
+
def eval_context
|
64
|
+
@eval_context ||= EvalContext.new
|
66
65
|
end
|
67
66
|
|
68
67
|
@@root = RootNamespace.new
|
@@ -1,19 +1,15 @@
|
|
1
|
-
blueprint :error do
|
2
|
-
raise 'error'
|
3
|
-
end
|
4
|
-
|
5
1
|
blueprint :apple do
|
6
|
-
Fruit.
|
2
|
+
Fruit.blueprint :species => 'apple'
|
7
3
|
end
|
8
4
|
|
9
5
|
blueprint :many_apples => [:apple, :apple, :apple]
|
10
6
|
|
11
7
|
blueprint :bananas_and_apples => :apple do
|
12
|
-
@banana = Fruit.
|
8
|
+
@banana = Fruit.blueprint :species => 'banana'
|
13
9
|
end
|
14
10
|
|
15
11
|
blueprint :orange do
|
16
|
-
Fruit.
|
12
|
+
Fruit.blueprint :species => 'orange'
|
17
13
|
end
|
18
14
|
|
19
15
|
blueprint :fruit => [:apple, :orange] do
|
@@ -25,11 +21,11 @@ blueprint :bananas_and_apples_and_oranges => [:bananas_and_apples, :orange] do
|
|
25
21
|
end
|
26
22
|
|
27
23
|
blueprint :cherry do
|
28
|
-
Fruit.
|
24
|
+
Fruit.blueprint :species => 'cherry', :average_diameter => 3
|
29
25
|
end
|
30
26
|
|
31
27
|
blueprint :big_cherry => :cherry do
|
32
|
-
Fruit.
|
28
|
+
Fruit.blueprint options.reverse_merge(:species => @cherry.species, :average_diameter => 7)
|
33
29
|
end
|
34
30
|
|
35
31
|
blueprint :cherry_basket => [:big_cherry, :cherry] do
|
@@ -49,15 +45,15 @@ end
|
|
49
45
|
|
50
46
|
Fruit.blueprint(:acorn, :species => 'Acorn', :tree => d(:oak))
|
51
47
|
blueprint :small_acorn do
|
52
|
-
@small_acorn = build :acorn => {:average_diameter => 1}
|
53
48
|
@small_acorn_options = options
|
49
|
+
build :acorn => {:average_diameter => 1}
|
54
50
|
end
|
55
51
|
blueprint(:huge_acorn => :huge_oak).extends(:acorn, :average_diameter => 100)
|
56
52
|
|
57
53
|
namespace :pitted => :pine do
|
58
54
|
Tree.blueprint :peach_tree, :name => 'pitted peach tree'
|
59
|
-
Fruit.blueprint
|
60
|
-
Fruit.blueprint
|
55
|
+
Fruit.blueprint :peach, :species => 'pitted peach', :tree => d(:'pitted.peach_tree')
|
56
|
+
Fruit.blueprint :acorn, :species => 'pitted acorn', :tree => d(:oak)
|
61
57
|
|
62
58
|
namespace :red => :orange do
|
63
59
|
Fruit.blueprint(:apple, :species => 'pitted red apple')
|
@@ -65,18 +61,19 @@ namespace :pitted => :pine do
|
|
65
61
|
end
|
66
62
|
|
67
63
|
blueprint :apple_with_params do
|
68
|
-
Fruit.
|
64
|
+
Fruit.blueprint options.reverse_merge(:species => 'apple')
|
69
65
|
end
|
70
66
|
|
71
|
-
namespace :attributes do
|
67
|
+
attributes(:average_diameter => 10, :species => 'fruit with attributes').namespace :attributes do
|
72
68
|
blueprint :cherry do
|
73
69
|
Fruit.blueprint attributes
|
74
70
|
end.attributes(:species => 'cherry')
|
75
71
|
|
76
72
|
Fruit.blueprint :shortened_cherry, :species => 'cherry'
|
77
73
|
|
78
|
-
Fruit.blueprint :
|
79
|
-
|
80
|
-
end.attributes(:average_diameter => 10, :species => 'fruit with attributes')
|
74
|
+
Fruit.blueprint :dependent_cherry, :tree => d(:pine, :the_pine)
|
75
|
+
end
|
81
76
|
|
82
77
|
blueprint :circular_reference => :circular_reference
|
78
|
+
|
79
|
+
Tree.blueprint :name => 'infered'
|
@@ -67,16 +67,30 @@ describe Blueprints do
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
describe "build per describe" do
|
71
|
+
unless File.dirname(__FILE__) =~ /test$/
|
72
|
+
build_blueprint :apple
|
73
|
+
|
74
|
+
it "should have cherry" do
|
75
|
+
@apple.should_not be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should have correct cherry species" do
|
79
|
+
@apple.species.should == 'apple'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
70
84
|
describe 'with preloaded cherry scenario' do
|
71
85
|
it "should have correct size after changed by second test" do
|
72
86
|
@cherry.average_diameter.should == 3
|
73
|
-
@cherry.
|
87
|
+
@cherry.blueprint(:average_diameter => 1)
|
74
88
|
@cherry.average_diameter.should == 1
|
75
89
|
end
|
76
90
|
|
77
91
|
it "should have correct size" do
|
78
92
|
@cherry.average_diameter.should == 3
|
79
|
-
@cherry.
|
93
|
+
@cherry.blueprint(:average_diameter => 5)
|
80
94
|
@cherry.average_diameter.should == 5
|
81
95
|
end
|
82
96
|
|
@@ -94,7 +108,7 @@ describe Blueprints do
|
|
94
108
|
demolish :apple
|
95
109
|
Fruit.all.should_not include(@apple)
|
96
110
|
build :apple
|
97
|
-
Fruit.
|
111
|
+
Fruit.all.should include(@apple)
|
98
112
|
end
|
99
113
|
|
100
114
|
it "should overwrite auto created instance variable with another auto created one" do
|
@@ -120,11 +134,11 @@ describe Blueprints do
|
|
120
134
|
end
|
121
135
|
|
122
136
|
it "should create only one apple" do
|
123
|
-
Fruit.all(:conditions =>
|
137
|
+
Fruit.all(:conditions => {:species => "apple"}).size.should == 1
|
124
138
|
end
|
125
139
|
|
126
140
|
it "should create only two cherries even if they were preloaded" do
|
127
|
-
Fruit.all(:conditions =>
|
141
|
+
Fruit.all(:conditions => {:species => "cherry"}).size.should == 2
|
128
142
|
end
|
129
143
|
|
130
144
|
it "should contain cherries in basket if basket is loaded in test and cherries preloaded" do
|
@@ -132,26 +146,6 @@ describe Blueprints do
|
|
132
146
|
end
|
133
147
|
end
|
134
148
|
|
135
|
-
describe 'transactions' do
|
136
|
-
before do
|
137
|
-
build :apple
|
138
|
-
end
|
139
|
-
|
140
|
-
it "should drop only inner transaction" do
|
141
|
-
@apple.reload.should_not be_nil
|
142
|
-
begin
|
143
|
-
ActiveRecord::Base.transaction do
|
144
|
-
f = Fruit.create(:species => 'orange')
|
145
|
-
f.reload.should_not be_nil
|
146
|
-
raise 'some error'
|
147
|
-
end
|
148
|
-
rescue
|
149
|
-
end
|
150
|
-
@apple.reload.should_not be_nil
|
151
|
-
Fruit.find_by_species('orange').should be_nil
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
149
|
describe 'errors' do
|
156
150
|
it 'should raise ScenarioNotFoundError when scenario could not be found' do
|
157
151
|
lambda {
|
@@ -164,12 +158,6 @@ describe Blueprints do
|
|
164
158
|
build :parent_not_existing
|
165
159
|
}.should raise_error(Blueprints::BlueprintNotFoundError)
|
166
160
|
end
|
167
|
-
|
168
|
-
it 'should raise TypeError when scenario name is not symbol or string' do
|
169
|
-
lambda {
|
170
|
-
Blueprints::Blueprint.new(1, __FILE__)
|
171
|
-
}.should raise_error(TypeError, "Pass blueprint names as strings or symbols only, cannot define blueprint 1")
|
172
|
-
end
|
173
161
|
end
|
174
162
|
|
175
163
|
describe 'with active record blueprints extensions' do
|
@@ -202,7 +190,7 @@ describe Blueprints do
|
|
202
190
|
|
203
191
|
it "should normalize attributes when updating with blueprint method" do
|
204
192
|
build :cherry, :oak
|
205
|
-
|
193
|
+
build :cherry => {:tree => d(:oak)}
|
206
194
|
@cherry.tree.should == @oak
|
207
195
|
end
|
208
196
|
|
@@ -213,8 +201,7 @@ describe Blueprints do
|
|
213
201
|
end
|
214
202
|
|
215
203
|
it "should allow to pass array of hashes to blueprint method" do
|
216
|
-
Fruit.
|
217
|
-
fruits = Fruit.blueprint([{:species => 'fruit1'}, {:species => 'fruit2'}])
|
204
|
+
fruits = Fruit.blueprint({:species => 'fruit1'}, {:species => 'fruit2'})
|
218
205
|
fruits.collect(&:species).should == %w{fruit1 fruit2}
|
219
206
|
end
|
220
207
|
|
@@ -331,23 +318,27 @@ describe Blueprints do
|
|
331
318
|
end
|
332
319
|
end
|
333
320
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
321
|
+
describe "build!" do
|
322
|
+
it "should allow to building same blueprint again" do
|
323
|
+
build! :big_cherry, :big_cherry => {:species => 'not so big cherry'}
|
324
|
+
Fruit.count.should == 4
|
325
|
+
Fruit.first(:conditions => {:species => 'not so big cherry'}).should_not be_nil
|
326
|
+
end
|
339
327
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
328
|
+
it "should allow building same blueprint n times" do
|
329
|
+
oaks = build! 5, :oak
|
330
|
+
oaks.should have(5).items
|
331
|
+
oaks.each do |oak|
|
332
|
+
oak.should be_instance_of(Tree)
|
333
|
+
oak.name.should == 'Oak'
|
334
|
+
end
|
335
|
+
end
|
345
336
|
end
|
346
337
|
|
347
338
|
describe 'attributes' do
|
348
339
|
it "should allow to extract attributes from blueprint" do
|
349
|
-
build_attributes('attributes.cherry').should == {:species => 'cherry'}
|
350
|
-
build_attributes('attributes.shortened_cherry').should == {:species => 'cherry'}
|
340
|
+
build_attributes('attributes.cherry').should == {:species => 'cherry', :average_diameter => 10}
|
341
|
+
build_attributes('attributes.shortened_cherry').should == {:species => 'cherry', :average_diameter => 10}
|
351
342
|
build_attributes(:big_cherry).should == {}
|
352
343
|
end
|
353
344
|
|
@@ -367,13 +358,7 @@ describe Blueprints do
|
|
367
358
|
end
|
368
359
|
|
369
360
|
it "should return build attributes for dependencies" do
|
370
|
-
attrs = build_attributes('attributes.
|
371
|
-
@the_pine.should_not be_nil
|
372
|
-
attrs[:tree].should == @the_pine
|
373
|
-
end
|
374
|
-
|
375
|
-
it "should return build attributes for :@var" do
|
376
|
-
attrs = build_attributes('attributes.dependent_cherry2')
|
361
|
+
attrs = build_attributes('attributes.dependent_cherry')
|
377
362
|
@the_pine.should_not be_nil
|
378
363
|
attrs[:tree].should == @the_pine
|
379
364
|
end
|
@@ -383,11 +368,7 @@ describe Blueprints do
|
|
383
368
|
build :circular_reference
|
384
369
|
end
|
385
370
|
|
386
|
-
it "should
|
387
|
-
|
388
|
-
build :error
|
389
|
-
rescue RuntimeError => e
|
390
|
-
e.backtrace[0].should == "spec/active_record/blueprint.rb:2:in blueprint 'error'"
|
391
|
-
end
|
371
|
+
it "should allow inferring blueprint name" do
|
372
|
+
build(:infered).name.should == 'infered'
|
392
373
|
end
|
393
374
|
end
|