blueprints 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -113,19 +113,15 @@ You can just type:
113
113
 
114
114
  If you need to make associations then:
115
115
 
116
- SomeModel.blueprint :something, :associated_column => :@association_instance_variable
116
+ SomeModel.blueprint(:something, :associated_column => d(:some_blueprint))
117
117
 
118
- And if you also need it to depend on other blueprints:
118
+ ...or if the name of blueprint and the name of instance variable are not the same:
119
119
 
120
- SomeModel.blueprint({:something => :some_blueprint}, :associated_column => :@some_iv)
120
+ SomeModel.blueprint(:something, :associated_column => d(:some_blueprint, :some_instance_variable))
121
121
 
122
- ...or...
122
+ ...and when you need to pass options to associated blueprint:
123
123
 
124
- SomeModel.blueprint(:something, :associated_column => :@some_iv).depends_on(:some_blueprint)
125
-
126
- ...or if name of blueprint that this one depends on and instance variable association uses are the same...
127
-
128
- SomeModel.blueprint(:something, :associated_column => d(:some_blueprint)) # I prefer this one
124
+ SomeModel.blueprint(:something, :associated_column => d(:some_blueprint, :option => 'value'))
129
125
 
130
126
  You can learn more about blueprint method in http://wiki.github.com/sinsiliux/blueprints/method-blueprint
131
127
 
@@ -148,11 +144,10 @@ which resets database to the state before the test. This state is empty database
148
144
 
149
145
  == TODO
150
146
 
151
- * Add ability to revert one blueprint.
152
147
  * Add preloading blueprints for whole block of tests.
153
148
  * Fix rake tasks
154
149
  * Add merb support
155
- * Add support for other test frameworks (check support of cucumber)
150
+ * Add support for other test frameworks
156
151
 
157
152
  == Credits
158
153
 
data/Rakefile CHANGED
@@ -56,6 +56,8 @@ task :rspec_to_test do
56
56
  data.gsub!(/(\s+)lambda \{\n(.*)\n(\s+)\}.should raise_error\((.*)\)/, "\\1assert_raise(\\4) do\n\\2\n\\3end")
57
57
  # should =~ => assert_similar
58
58
  data.gsub!(/^(\s+)(.*)\.should\s*=~\s*(.*)/, '\1assert_similar(\2, \3)')
59
+ # A.should_not include(B) => assert_false(A.include?(B))
60
+ data.gsub!(/^(\s+)(.*)\.should_not\s*include\((.*)\)/, '\1assert(!\2.include?(\3))')
59
61
 
60
62
  # .should_not => assert(!())
61
63
  data.gsub!(/^(\s+)(.*)\.should_not(.*)/, '\1assert(!(\2\3))')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.3
1
+ 0.8.0
data/blueprints.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{blueprints}
8
- s.version = "0.7.3"
8
+ s.version = "0.8.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andrius Chamentauskas"]
12
- s.date = %q{2010-07-17}
12
+ s.date = %q{2010-08-13}
13
13
  s.default_executable = %q{blueprintify}
14
14
  s.description = %q{Another replacement for factories and fixtures. The library that lazy typists will love}
15
15
  s.email = %q{sinsiliux@gmail.com}
@@ -38,10 +38,10 @@ Gem::Specification.new do |s|
38
38
  "lib/blueprints/context.rb",
39
39
  "lib/blueprints/convertable.rb",
40
40
  "lib/blueprints/convertable/fixtures.rb",
41
- "lib/blueprints/database_backends/active_record.rb",
41
+ "lib/blueprints/core_ext.rb",
42
+ "lib/blueprints/dependency.rb",
42
43
  "lib/blueprints/errors.rb",
43
44
  "lib/blueprints/extensions/cucumber.rb",
44
- "lib/blueprints/extensions/deprecated.rb",
45
45
  "lib/blueprints/extensions/rspec.rb",
46
46
  "lib/blueprints/extensions/test_unit.rb",
47
47
  "lib/blueprints/file_context.rb",
@@ -60,7 +60,12 @@ Gem::Specification.new do |s|
60
60
  "spec/no_db/fixtures/fruit.rb",
61
61
  "spec/no_db/spec_helper.rb",
62
62
  "spec/test_all.sh",
63
+ "spec/unit/active_record_spec.rb",
64
+ "spec/unit/blueprint_spec.rb",
65
+ "spec/unit/buildable_spec.rb",
63
66
  "spec/unit/configuration_spec.rb",
67
+ "spec/unit/dependency_spec.rb",
68
+ "spec/unit/namespace_spec.rb",
64
69
  "spec/unit/spec_helper.rb",
65
70
  "test/blueprints_test.rb",
66
71
  "test/test_helper.rb",
@@ -76,8 +81,13 @@ Gem::Specification.new do |s|
76
81
  "spec/no_db/spec_helper.rb",
77
82
  "spec/no_db/blueprints_spec.rb",
78
83
  "spec/no_db/blueprint.rb",
84
+ "spec/unit/active_record_spec.rb",
85
+ "spec/unit/blueprint_spec.rb",
79
86
  "spec/unit/spec_helper.rb",
80
87
  "spec/unit/configuration_spec.rb",
88
+ "spec/unit/namespace_spec.rb",
89
+ "spec/unit/buildable_spec.rb",
90
+ "spec/unit/dependency_spec.rb",
81
91
  "spec/active_record/fixtures/fruit.rb",
82
92
  "spec/active_record/fixtures/tree.rb",
83
93
  "spec/active_record/fixtures/schema.rb",
@@ -6,12 +6,22 @@ module Blueprints
6
6
  def initialize(name, file, &block)
7
7
  @file = file
8
8
  super(name)
9
+
10
+ ivname = :"@#{path}"
9
11
  @block = block
12
+ @demolish_block = lambda { instance_variable_get(ivname).destroy }
13
+ @update_block = lambda { instance_variable_get(ivname).blueprint(options) }
10
14
  end
11
15
 
12
16
  # Builds blueprint and adds it to executed blueprint hash. Setups instance variable with same name as blueprint if it is not defined yet.
13
17
  def build_self(build_once = true)
14
- surface_errors { @result = Namespace.root.context.instance_eval(&@block) if @block }
18
+ surface_errors do
19
+ if built? and build_once
20
+ Namespace.root.context.instance_eval(&@update_block) if RootNamespace.root.context.options.present?
21
+ elsif @block
22
+ @result = Namespace.root.context.instance_eval(&@block)
23
+ end
24
+ end
15
25
  end
16
26
 
17
27
  # Changes blueprint block to build another blueprint by passing additional options to it. Usually used to dry up
@@ -22,7 +32,26 @@ module Blueprints
22
32
  end
23
33
 
24
34
  def backtrace(trace)
25
- trace.collect {|line| line.sub(/^\(eval\):(\d+).*/, "#{@file}:\\1:in blueprint '#{@name}'") }
35
+ trace.collect { |line| line.sub(/^\(eval\):(\d+).*/, "#{@file}:\\1:in blueprint '#{@name}'") }
36
+ end
37
+
38
+ # If block is passed then sets custom demolish block for this blueprint.
39
+ # If no block is passed then calls demolish block and marks blueprint as not built.
40
+ # Raises DemolishError if blueprints has not been built.
41
+ def demolish(&block)
42
+ if block
43
+ @demolish_block = block
44
+ elsif built?
45
+ Namespace.root.context.instance_eval(&@demolish_block)
46
+ undo!
47
+ else
48
+ raise DemolishError, @name
49
+ end
50
+ end
51
+
52
+ # Allows customizing what happens when blueprint is already built and it's being built again.
53
+ def update(&block)
54
+ @update_block = block
26
55
  end
27
56
 
28
57
  private
@@ -1,13 +1,5 @@
1
1
  module Blueprints
2
2
  class Buildable
3
- class Dependency < Struct.new(:name) # :nodoc:
4
- alias :to_sym :name
5
-
6
- def iv_name
7
- :"@#{name}"
8
- end
9
- end
10
-
11
3
  attr_reader :name
12
4
  attr_accessor :namespace
13
5
 
@@ -31,15 +23,12 @@ module Blueprints
31
23
 
32
24
  # Builds dependencies of blueprint and then blueprint itself.
33
25
  #
34
- # +build_once+ - pass false if you want to build despite the fact that it was already built.
26
+ # +build_once+ - pass false if you want to build blueprint again instead of updating old one.
35
27
  #
36
28
  # +options+ - list of options to be accessible in the body of a blueprint. Defaults to empty Hash.
37
29
  def build(build_once = true, options = {})
38
- if build_once and Namespace.root.executed_blueprints.include?(path)
39
- Blueprints.warn("Building with options, but blueprint was already built", self) if options.present?
40
- return @result
41
- end
42
- Namespace.root.executed_blueprints << path
30
+ return @result if (built? or Namespace.root.executed_blueprints.include? self) and build_once and options.blank?
31
+ Namespace.root.executed_blueprints << self
43
32
 
44
33
  each_namespace {|namespace| namespace.build_parents }
45
34
  build_parents
@@ -53,6 +42,17 @@ module Blueprints
53
42
  Namespace.root.add_variable(path, @result)
54
43
  end
55
44
 
45
+ # Returns if blueprint has been built
46
+ def built?
47
+ instance_variable_defined?(:@result)
48
+ end
49
+
50
+ # Marks blueprint as not built
51
+ def undo!
52
+ remove_instance_variable(:@result) if built?
53
+ Namespace.root.executed_blueprints.delete self
54
+ end
55
+
56
56
  # If value is passed then it sets attributes for this buildable object.
57
57
  # Otherwise returns attributes (defaulting to empty Hash)
58
58
  def attributes(value)
@@ -69,13 +69,11 @@ module Blueprints
69
69
  def self.normalize_attributes(attributes)
70
70
  attributes = attributes.dup
71
71
  attributes.each do |attr, value|
72
- if value.is_a?(Blueprints::Buildable::Dependency)
73
- iv_name = value.iv_name
74
- Blueprints::Namespace.root.build(value.name)
72
+ attributes[attr] = value.value if value.is_a?(Blueprints::Dependency)
73
+ if value.is_a? Symbol and value.to_s =~ /^@.+$/
74
+ STDERR.puts "DEPRECATION WARNING: :@variables are deprecated in favor of `d` method"
75
+ attributes[attr] = Blueprints::Namespace.root.context.instance_variable_get(value)
75
76
  end
76
- iv_name = value if value.is_a? Symbol and value.to_s =~ /^@.+$/
77
-
78
- attributes[attr] = Blueprints::Namespace.root.context.instance_variable_get(iv_name) if iv_name
79
77
  end
80
78
  end
81
79
 
@@ -9,8 +9,6 @@ module Blueprints
9
9
  attr_reader :root
10
10
  # By default blueprints runs each test in it's own transaction. This may sometimes be not desirable so this options allows to turn this off.
11
11
  attr_accessor :transactions
12
- # Returns ORM that is used, default is :active_record
13
- attr_reader :orm
14
12
 
15
13
  # Sets default attributes for all attributes
16
14
  def initialize
@@ -26,15 +24,6 @@ module Blueprints
26
24
  @root = defined?(Rails) ? Rails.root : Pathname.pwd
27
25
  end
28
26
 
29
- # Allows specifying what ORM should be used. See SUPPORTED_ORMS to check what values it can contain.
30
- def orm=(value)
31
- if SUPPORTED_ORMS.include?(value)
32
- @orm = value
33
- else
34
- raise ArgumentError, "Unsupported ORM #{value.inspect}. Blueprints supports only #{SUPPORTED_ORMS.collect(&:inspect).join(', ')}"
35
- end
36
- end
37
-
38
27
  def filename=(value)
39
28
  @filename = Array(value).flatten.collect {|path| Pathname.new(path) }
40
29
  end
@@ -0,0 +1,69 @@
1
+ # Include this module into your class if you need klass.blueprint and object.blueprint methods.
2
+ module Blueprints::Blueprintable
3
+ module ClassMethods
4
+ # Two forms of this method can be used. First one is typically used inside blueprint block. Essentially it does
5
+ # same as <tt>create!</tt>, except it does bypass attr_protected and attr_accessible. It accepts only a hash or attributes,
6
+ # same as <tt>create!</tt> does.
7
+ # blueprint :post => [:user, :board] do
8
+ # @user.posts.blueprint(:title => 'first post', :text => 'My first post')
9
+ # end
10
+ # The second form is used when you want to define new blueprint. It takes first argument as name of blueprint
11
+ # and second one as hash of attributes. As you cannot use instance variables outside of blueprint block, you need
12
+ # to prefix them with colon. So the example above could be rewritten like this:
13
+ # Post.blueprint(:post, :title => 'first post', :text => 'My first post', :user => d(:user)).depends_on(:board)
14
+ def blueprint(name_or_attrs, attrs = {})
15
+ if Blueprints::FileContext.current
16
+ define_blueprint(name_or_attrs, attrs)
17
+ else
18
+ if name_or_attrs.is_a?(Array)
19
+ name_or_attrs.collect { |attrs| blueprint(attrs) }
20
+ else
21
+ blueprint_object(name_or_attrs)
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def define_blueprint(name, attrs)
29
+ klass = self
30
+ blueprint = Blueprints::Blueprint.new(name, Blueprints::FileContext.current.file) { klass.blueprint attributes }
31
+ blueprint.attributes(attrs)
32
+ blueprint
33
+ end
34
+
35
+ def blueprint_object(attrs)
36
+ object = new
37
+ object.blueprint(attrs)
38
+ object
39
+ end
40
+ end
41
+
42
+ def self.included(mod)
43
+ mod.extend Blueprints::Blueprintable::ClassMethods
44
+ end
45
+
46
+ # Updates attributes of object by calling setter methods.
47
+ def blueprint(attributes)
48
+ Blueprints::Blueprint.normalize_attributes(attributes).each do |attr, val|
49
+ send(:"#{attr}=", val)
50
+ end
51
+ end
52
+ end
53
+
54
+ # Include this instead of Blueprints::Blueprintable if record needs to persist, includes Blueprints::Blueprintable
55
+ module Blueprints::Saveable
56
+ include Blueprints::Blueprintable
57
+
58
+ def self.included(mod)
59
+ mod.extend Blueprints::Blueprintable::ClassMethods
60
+ end
61
+
62
+ # Overrides object.blueprint to also call save!
63
+ def blueprint(attributes)
64
+ super(attributes)
65
+ save!
66
+ end
67
+ end
68
+
69
+ ::ActiveRecord::Base.send(:include, Blueprints::Saveable) if defined?(ActiveRecord)
@@ -0,0 +1,35 @@
1
+ # Class for defining blueprint dependencies. Accepts up to 3 params:
2
+ # * name - pass the name of blueprint to build when trying to access value of this dependency.
3
+ # * iv_name (optional) - pass the name of instance variable to use for value. Defaults to same name as blueprint name.
4
+ # * options (optional) - pass options that are then passed to blueprint when building.
5
+ # Examples:
6
+ # Blueprints::Dependency.new(:blueprint).value # Builds blueprint 'blueprint' and returns value of @blueprint instance variable
7
+ # Blueprints::Dependency.new(:blueprint, value).value # Builds blueprint 'blueprint' and returns value of @value instance variable
8
+ # Blueprints::Dependency.new(:blueprint, :option => true).value # Builds blueprint 'blueprint' with options and returns value of @value instance variable
9
+ #
10
+ # Blueprints::Dependency objects also catch all missing methods. They are later replayed on instance variable when getting value. Example:
11
+ # d = Blueprints::Dependency.new(:blueprint).name.size
12
+ # d.value # => 4 when @blueprint.name == 'John'
13
+ class Blueprints::Dependency
14
+ # Initializes new copy of Blueprints::Dependency with name, iv_name and options.
15
+ def initialize(name, *args)
16
+ @name = name
17
+ @options = args.extract_options!
18
+ @iv_name = args.first || @name
19
+ @registry = []
20
+ end
21
+
22
+ # Builds blueprint (if necessary) and returns the value of instance variable.
23
+ def value
24
+ Blueprints::RootNamespace.root.build @name => @options
25
+ @registry.inject(Blueprints::RootNamespace.root.context.instance_variable_get(:"@#{@iv_name}")) do |value, (method, args, block)|
26
+ value.send(method, *args, &block)
27
+ end
28
+ end
29
+
30
+ # Catches all missing methods to later replay when asking for value.
31
+ def method_missing(method, *args, &block)
32
+ @registry << [method, args, block]
33
+ self
34
+ end
35
+ end
@@ -1,12 +1,24 @@
1
1
  module Blueprints
2
- # Is raised when blueprint or namespace is not found.
3
- class BlueprintNotFoundError < NameError
4
- def initialize(*args)
5
- @blueprints = args
2
+ class Error < StandardError
3
+ def initialize(blueprint)
4
+ @name = blueprint
6
5
  end
7
6
 
8
7
  def to_s
9
- "Blueprint/namespace not found '#{@blueprints.join(',')}'"
8
+ "Blueprint '#{@name}' #{message_append}"
9
+ end
10
+ end
11
+
12
+ class DemolishError < Error
13
+ def message_append
14
+ 'must be built before demolishing'
15
+ end
16
+ end
17
+
18
+ # Is raised when blueprint or namespace is not found.
19
+ class BlueprintNotFoundError < Error
20
+ def message_append
21
+ 'not found'
10
22
  end
11
23
  end
12
24
  end
@@ -1,6 +1,22 @@
1
+ module DescribeHelper
2
+ # Creates new before filter that builds blueprints before each spec.
3
+ def build_blueprint(*names)
4
+ before { build_blueprint *names }
5
+ end
6
+
7
+ # Same as #build_blueprint except that you can use it to build same blueprint several times.
8
+ def build_blueprint!(*names)
9
+ before { build_blueprint! *names }
10
+ end
11
+
12
+ alias :build :build_blueprint
13
+ alias :build! :build_blueprint!
14
+ end
15
+
1
16
  config_class = defined?(RSpec) ? RSpec : Spec::Runner
2
17
  config_class.configure do |config|
3
18
  config.include(Blueprints::Helper)
19
+ config.extend(DescribeHelper)
4
20
  config.before do
5
21
  Blueprints.setup(self)
6
22
  end
@@ -29,10 +29,9 @@ module Blueprints
29
29
  namespace
30
30
  end
31
31
 
32
- # Creates dependency for current blueprint on some other blueprint and marks that instance variable with same name
33
- # should be used for value of column. Only works on "Class.blueprint :name" type of blueprints
34
- def d(name)
35
- Buildable::Dependency.new(name)
32
+ # Wrapper around Blueprints::Dependency.new. See Blueprints::Dependency for more information.
33
+ def d(*args)
34
+ Dependency.new(*args)
36
35
  end
37
36
  end
38
37
  end
@@ -33,25 +33,11 @@ module Blueprints
33
33
  alias :build :build_blueprint
34
34
  alias :build! :build_blueprint!
35
35
 
36
- # Clears all tables in database. You can pass table names to clear only those tables. You can also pass <tt>:undo</tt> option
37
- # to remove scenarios from built scenarios cache.
36
+ # Demolishes built blueprints (by default simply calls destroy method on result of blueprint, but can be customized).
38
37
  #
39
- # TODO: add sample usage
40
- def demolish(*args)
41
- STDERR.puts "DEPRECATION WARNING: demolish is deprecated and will be changed to support per blueprint demolishing in blueprints 0.8.0"
42
- options = args.extract_options!
43
- args = (ActiveRecord::Base.connection.tables - ['schema_migrations']) if args.blank?
44
- args.each {|table| ActiveRecord::Base.connection.execute("DELETE FROM #{table}") }
45
-
46
- if options[:undo] == :all
47
- Namespace.root.executed_blueprints.clear
48
- else
49
- undo = [options[:undo]].flatten.compact.collect(&:to_s)
50
- unless (not_found = undo - Namespace.root.executed_blueprints.to_a).blank?
51
- raise(BlueprintNotFoundError, not_found)
52
- end
53
- Namespace.root.executed_blueprints -= undo
54
- end
38
+ # demolish :apple, :pear
39
+ def demolish(*names)
40
+ names.each { |name| Namespace.root[name].demolish }
55
41
  end
56
42
  end
57
43
  end
@@ -33,5 +33,10 @@ module Blueprints
33
33
  def build_self(build_once = true)
34
34
  @result = @children.collect {|p| p.last.build }.uniq
35
35
  end
36
+
37
+ # Demolished all child blueprints and namespaces
38
+ def demolish
39
+ @children.each_value(&:demolish)
40
+ end
36
41
  end
37
42
  end
@@ -3,12 +3,10 @@ module Blueprints
3
3
  # building blueprints/namespaces by name. Is also used for copying instance variables between blueprints/contexts/global
4
4
  # context.
5
5
  class RootNamespace < Namespace
6
- attr_reader :context, :blueprints
7
- attr_accessor :executed_blueprints
6
+ attr_reader :context, :executed_blueprints
8
7
 
9
8
  def initialize
10
- @executed_blueprints = Set.new
11
- @global_executed_blueprints = Set.new
9
+ @executed_blueprints = @global_executed_blueprints = []
12
10
  @auto_iv_list = Set.new
13
11
 
14
12
  super ''
@@ -16,8 +14,10 @@ module Blueprints
16
14
 
17
15
  # Loads all instance variables from global context to current one.
18
16
  def setup
19
- @context = Blueprints::Context.new
17
+ (@executed_blueprints - @global_executed_blueprints).each(&:undo!)
20
18
  @executed_blueprints = @global_executed_blueprints.clone
19
+ @context = Blueprints::Context.new
20
+
21
21
  if Blueprints.config.transactions
22
22
  Marshal.load(@global_variables).each { |name, value| @context.instance_variable_set(name, value) }
23
23
  else
@@ -35,10 +35,10 @@ module Blueprints
35
35
  # Sets up global context and executes prebuilt blueprints against it.
36
36
  def prebuild(blueprints)
37
37
  @context = Blueprints::Context.new
38
- @global_scenarios = build(blueprints) if blueprints
39
- @global_executed_blueprints = @executed_blueprints
38
+ build(blueprints) if blueprints
40
39
 
41
- @global_variables = Marshal.dump(@context.instance_variables.each_with_object({}) {|iv, hash| hash[iv] = @context.instance_variable_get(iv) })
40
+ @global_executed_blueprints = @executed_blueprints
41
+ @global_variables = Marshal.dump(@context.instance_variables.each_with_object({}) { |iv, hash| hash[iv] = @context.instance_variable_get(iv) })
42
42
  end
43
43
 
44
44
  # Builds blueprints that are passed against current context. Copies instance variables to context given if one is given.
@@ -46,7 +46,7 @@ module Blueprints
46
46
  names = [names] unless names.is_a?(Array)
47
47
  result = names.inject(nil) do |result, member|
48
48
  if member.is_a?(Hash)
49
- member.map {|name, options| self[name].build(build_once, options) }.last
49
+ member.map { |name, options| self[name].build(build_once, options) }.last
50
50
  else
51
51
  self[member].build(build_once)
52
52
  end
data/lib/blueprints.rb CHANGED
@@ -4,9 +4,9 @@ require 'database_cleaner'
4
4
  require 'set'
5
5
 
6
6
  files = %w{
7
- configuration context buildable namespace root_namespace blueprint file_context helper errors extensions/deprecated
7
+ configuration context buildable namespace root_namespace blueprint file_context helper errors dependency core_ext
8
8
  }
9
- files.each {|f| require File.join(File.dirname(__FILE__), 'blueprints', f) }
9
+ files.each { |f| require File.join(File.dirname(__FILE__), 'blueprints', f) }
10
10
 
11
11
  module Blueprints
12
12
  # Contains current configuration of blueprints
@@ -18,12 +18,12 @@ module Blueprints
18
18
  def self.setup(current_context)
19
19
  Namespace.root.setup
20
20
  Namespace.root.copy_ivars(current_context)
21
- DatabaseCleaner.start if config.orm
21
+ if_orm { DatabaseCleaner.start }
22
22
  end
23
23
 
24
24
  # Rollbacks transaction returning everything to state before test. Should be called after every test case.
25
25
  def self.teardown
26
- DatabaseCleaner.clean if config.orm
26
+ if_orm { DatabaseCleaner.clean }
27
27
  end
28
28
 
29
29
  # Enables blueprints support for RSpec or Test::Unit depending on whether (R)Spec is defined or not. Yields
@@ -36,7 +36,7 @@ module Blueprints
36
36
  elsif defined? Spec or defined? RSpec
37
37
  'rspec'
38
38
  else
39
- 'test_unit'
39
+ 'test_unit'
40
40
  end
41
41
  require File.join(File.dirname(__FILE__), 'blueprints', 'extensions', extension)
42
42
  end
@@ -45,12 +45,12 @@ module Blueprints
45
45
  def self.load
46
46
  return unless Namespace.root.empty?
47
47
 
48
- require File.join(File.dirname(__FILE__), 'blueprints', 'database_backends', config.orm.to_s) if config.orm
49
- DatabaseCleaner.clean_with :truncation if config.orm
50
-
48
+ if_orm do
49
+ DatabaseCleaner.clean_with :truncation
50
+ DatabaseCleaner.strategy = (config.transactions ? :transaction : :truncation)
51
+ end
51
52
  load_scenarios_files(config.filename)
52
53
 
53
- DatabaseCleaner.strategy = (config.transactions ? :transaction : :truncation) if config.orm
54
54
  Namespace.root.prebuild(config.prebuild) if config.transactions
55
55
  end
56
56
 
@@ -59,10 +59,10 @@ module Blueprints
59
59
  root_sub = /^#{config.root}[\\\/]/
60
60
  blueprints_path = File.dirname(__FILE__).sub(root_sub, '')
61
61
 
62
- bc.add_filter {|line| line.sub(root_sub, '') }
62
+ bc.add_filter { |line| line.sub(root_sub, '') }
63
63
 
64
- bc.add_silencer {|line| File.dirname(line).starts_with?(blueprints_path) }
65
- bc.add_silencer {|line| Gem.path.any? {|path| File.dirname(line).starts_with?(path) } }
64
+ bc.add_silencer { |line| File.dirname(line).starts_with?(blueprints_path) }
65
+ bc.add_silencer { |line| Gem.path.any? { |path| File.dirname(line).starts_with?(path) } }
66
66
  end
67
67
  end
68
68
 
@@ -77,10 +77,18 @@ module Blueprints
77
77
  def self.load_scenarios_files(patterns)
78
78
  patterns.each do |pattern|
79
79
  pattern = config.root.join(pattern)
80
- Dir[pattern].each {|f| FileContext.new f }
81
- return if Dir[pattern].size > 0
80
+ files = Dir[pattern.to_s]
81
+ files.each { |f| FileContext.new f }
82
+ return if files.size > 0
82
83
  end
83
84
 
84
85
  raise "Blueprints file not found! Put blueprints in #{patterns.join(' or ')} or pass custom filename pattern with :filename option"
85
86
  end
87
+
88
+ private
89
+
90
+ def self.if_orm
91
+ yield
92
+ rescue DatabaseCleaner::NoORMDetected, DatabaseCleaner::NoStrategySetError
93
+ end
86
94
  end
@@ -44,6 +44,7 @@ Tree.blueprint(:oak_without_attributes)
44
44
 
45
45
  blueprint :pine do
46
46
  @the_pine = Tree.blueprint :name => 'Pine', :size => 'medium'
47
+ @pine = Tree.blueprint :name => 'Pine', :size => 'small'
47
48
  end
48
49
 
49
50
  Fruit.blueprint(:acorn, :species => 'Acorn', :tree => d(:oak))
@@ -74,7 +75,7 @@ namespace :attributes do
74
75
 
75
76
  Fruit.blueprint :shortened_cherry, :species => 'cherry'
76
77
 
77
- Fruit.blueprint :dependent_cherry1, :tree => d(:pine)
78
+ Fruit.blueprint :dependent_cherry1, :tree => d(:pine, :the_pine)
78
79
  Fruit.blueprint(:dependent_cherry2, :tree => :@the_pine).depends_on(:pine)
79
80
  end.attributes(:average_diameter => 10, :species => 'fruit with attributes')
80
81