blueprints 0.7.3 → 0.8.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/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