blueprints 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Rakefile +7 -1
- data/VERSION +1 -1
- data/blueprints.gemspec +3 -2
- data/lib/blueprints.rb +22 -5
- data/lib/blueprints/buildable.rb +3 -1
- data/lib/blueprints/context.rb +6 -0
- data/lib/blueprints/database_backends/abstract.rb +4 -0
- data/lib/blueprints/database_backends/active_record.rb +41 -14
- data/lib/blueprints/database_backends/none.rb +4 -0
- data/lib/blueprints/errors.rb +2 -1
- data/lib/blueprints/extensions/rspec.rb +6 -3
- data/lib/blueprints/extensions/test_unit.rb +7 -3
- data/lib/blueprints/file_context.rb +4 -1
- data/lib/blueprints/helper.rb +13 -1
- data/lib/blueprints/namespace.rb +3 -1
- data/lib/blueprints/plan.rb +5 -2
- data/lib/blueprints/root_namespace.rb +16 -6
- data/spec/active_record/blueprint.rb +5 -1
- data/spec/active_record/blueprints_spec.rb +28 -2
- metadata +3 -2
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -9,7 +9,13 @@ begin
|
|
9
9
|
gemspec.homepage = "http://github.com/sinsiliux/blueprints"
|
10
10
|
gemspec.authors = ["Andrius Chamentauskas"]
|
11
11
|
end
|
12
|
-
Jeweler::GemcutterTasks.new
|
12
|
+
Jeweler::GemcutterTasks.new
|
13
13
|
rescue LoadError
|
14
14
|
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
15
15
|
end
|
16
|
+
|
17
|
+
require 'rake/rdoctask'
|
18
|
+
Rake::RDocTask.new do |rd|
|
19
|
+
rd.main = "README.rdoc"
|
20
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
21
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.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.
|
8
|
+
s.version = "0.4.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{2009-12-
|
12
|
+
s.date = %q{2009-12-25}
|
13
13
|
s.description = %q{Another replacement for factories and fixtures. The library that lazy typists will love}
|
14
14
|
s.email = %q{sinsiliux@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
"install.rb",
|
28
28
|
"lib/blueprints.rb",
|
29
29
|
"lib/blueprints/buildable.rb",
|
30
|
+
"lib/blueprints/context.rb",
|
30
31
|
"lib/blueprints/database_backends/abstract.rb",
|
31
32
|
"lib/blueprints/database_backends/active_record.rb",
|
32
33
|
"lib/blueprints/database_backends/none.rb",
|
data/lib/blueprints.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'activesupport'
|
2
2
|
files = %w{
|
3
|
-
buildable namespace root_namespace plan file_context helper errors
|
3
|
+
context buildable namespace root_namespace plan file_context helper errors
|
4
4
|
database_backends/abstract database_backends/active_record database_backends/none
|
5
5
|
}
|
6
6
|
files << if defined? Spec or $0 =~ /script.spec$/
|
@@ -18,24 +18,37 @@ module Blueprints
|
|
18
18
|
end
|
19
19
|
end.flatten
|
20
20
|
|
21
|
+
# Returns a list of supported ORMs. For now it supports ActiveRecord and None.
|
21
22
|
def self.supported_orms
|
22
23
|
(DatabaseBackends.constants - ['Abstract']).collect {|class_name| class_name.underscore.to_sym }
|
23
24
|
end
|
24
25
|
|
26
|
+
# Returns root of project blueprints is used in. Automatically detected for rails and merb. Can be overwritten by using
|
27
|
+
# <tt>:root</tt> options when loading blueprints. If root can't be determined, returns nil which means that current
|
28
|
+
# directory is asumed as root.
|
25
29
|
def self.framework_root
|
26
30
|
@@framework_root ||= RAILS_ROOT rescue Rails.root rescue Merb.root rescue nil
|
27
31
|
end
|
28
32
|
|
33
|
+
# Setups variables from global context and starts transaction. Should be called before every test case.
|
29
34
|
def self.setup(current_context)
|
30
35
|
Namespace.root.setup
|
31
36
|
Namespace.root.copy_ivars(current_context)
|
32
37
|
@@orm.start_transaction
|
33
38
|
end
|
34
39
|
|
40
|
+
# Rollbacks transaction returning everything to state before test. Should be called after every test case.
|
35
41
|
def self.teardown
|
36
42
|
@@orm.rollback_transaction
|
37
43
|
end
|
38
44
|
|
45
|
+
# Sets up configuration, clears database, runs scenarios that have to be prebuilt. Should be run before all test cases and before <tt>setup</tt>.
|
46
|
+
# Accepts following options:
|
47
|
+
# * <tt>:delete_policy</tt> - allows changing how tables in database should be cleared. By default simply uses delete statement. Supports :delete and :truncate options.
|
48
|
+
# * <tt>:filename</tt> - Allows passing custom filename pattern in case blueprints are held in place other than spec/blueprint, test/blueprint, blueprint.
|
49
|
+
# * <tt>:prebuild</tt> - Allows passing scenarios that should be prebuilt and available in all tests. Works similarly to fixtures.
|
50
|
+
# * <tt>:root</tt> - Allows passing custom root folder to use in case of non rails and non merb project.
|
51
|
+
# * <tt>:orm</tt> - Allows specifying what orm should be used. Default to <tt>:active_record</tt>, also allows <tt>:none</tt>
|
39
52
|
def self.load(options = {})
|
40
53
|
options.assert_valid_keys(:delete_policy, :filename, :prebuild, :root, :orm)
|
41
54
|
options.symbolize_keys!
|
@@ -52,6 +65,14 @@ module Blueprints
|
|
52
65
|
Namespace.root.prebuild(options[:prebuild])
|
53
66
|
end
|
54
67
|
|
68
|
+
# Clears all tables in database. Also accepts a list of tables in case not all tables should be cleared.
|
69
|
+
def self.delete_tables(*tables)
|
70
|
+
@@orm.delete_tables(@@delete_policy, *tables)
|
71
|
+
end
|
72
|
+
|
73
|
+
protected
|
74
|
+
|
75
|
+
# Loads blueprints file and creates blueprints from data it contains. Is run by setup method
|
55
76
|
def self.load_scenarios_files(*patterns)
|
56
77
|
patterns.flatten!
|
57
78
|
patterns.collect! {|pattern| File.join(framework_root, pattern)} if framework_root
|
@@ -65,8 +86,4 @@ module Blueprints
|
|
65
86
|
|
66
87
|
raise "Plans file not found! Put plans in #{patterns.join(' or ')} or pass custom filename pattern with :filename option"
|
67
88
|
end
|
68
|
-
|
69
|
-
def self.delete_tables(*tables)
|
70
|
-
@@orm.delete_tables(@@delete_policy, *tables)
|
71
|
-
end
|
72
89
|
end
|
data/lib/blueprints/buildable.rb
CHANGED
@@ -10,10 +10,12 @@ module Blueprints
|
|
10
10
|
Namespace.root.add_child(self) if Namespace.root
|
11
11
|
end
|
12
12
|
|
13
|
+
# Defines blueprint dependencies. Used internally, but can be used externally too.
|
13
14
|
def depends_on(*scenarios)
|
14
15
|
@parents = (@parents || []) + scenarios.map{|s| s.to_sym}
|
15
16
|
end
|
16
17
|
|
18
|
+
# Builds dependencies of blueprint and then blueprint itself.
|
17
19
|
def build
|
18
20
|
namespace = self
|
19
21
|
namespace.build_parent_plans while namespace = namespace.namespace
|
@@ -51,4 +53,4 @@ module Blueprints
|
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
54
|
-
end
|
56
|
+
end
|
@@ -1,14 +1,18 @@
|
|
1
1
|
module Blueprints
|
2
2
|
module DatabaseBackends
|
3
3
|
class Abstract
|
4
|
+
# Method to start transaction. Needs to be implemented in child class.
|
4
5
|
def start_transaction
|
5
6
|
raise NotImplementedError
|
6
7
|
end
|
7
8
|
|
9
|
+
# Method to revert transaction. Needs to be implemented in child class.
|
8
10
|
def revert_transaction
|
9
11
|
raise NotImplementedError
|
10
12
|
end
|
11
13
|
|
14
|
+
# Method to clear tables. Should accept delete policy and list of tables to delete. If list of tables is empty, should
|
15
|
+
# delete all tables. Needs to be implemented in child class.
|
12
16
|
def delete_tables(delete_policy, *args)
|
13
17
|
raise NotImplementedError
|
14
18
|
end
|
@@ -3,21 +3,26 @@ module Blueprints
|
|
3
3
|
class ActiveRecord
|
4
4
|
DELETE_POLICIES = {:delete => "DELETE FROM %s", :truncate => "TRUNCATE %s"}
|
5
5
|
|
6
|
+
# Extends active record with blueprint method
|
6
7
|
def initialize
|
7
|
-
::ActiveRecord::Base.
|
8
|
+
::ActiveRecord::Base.send(:include, ActiveRecordExtensions::Instance)
|
9
|
+
::ActiveRecord::Base.extend(ActiveRecordExtensions::Class)
|
8
10
|
end
|
9
11
|
|
12
|
+
# Starts new transaction and marks it as unjoinable so that test case could use transactions too.
|
10
13
|
def start_transaction
|
11
14
|
::ActiveRecord::Base.connection.increment_open_transactions
|
12
15
|
::ActiveRecord::Base.connection.transaction_joinable = false
|
13
16
|
::ActiveRecord::Base.connection.begin_db_transaction
|
14
17
|
end
|
15
18
|
|
19
|
+
# Rollbacks transaction
|
16
20
|
def rollback_transaction
|
17
21
|
::ActiveRecord::Base.connection.rollback_db_transaction
|
18
22
|
::ActiveRecord::Base.connection.decrement_open_transactions
|
19
23
|
end
|
20
24
|
|
25
|
+
# Clears all tables using delete policy specified. Also accepts list of tables to delete.
|
21
26
|
def delete_tables(delete_policy, *args)
|
22
27
|
delete_policy ||= :delete
|
23
28
|
raise ArgumentError, "Unknown delete policy #{delete_policy}" unless DELETE_POLICIES.keys.include?(delete_policy)
|
@@ -25,30 +30,52 @@ module Blueprints
|
|
25
30
|
args.each { |t| ::ActiveRecord::Base.connection.delete(DELETE_POLICIES[delete_policy] % t) }
|
26
31
|
end
|
27
32
|
|
33
|
+
# Returns all tables without skipped ones.
|
28
34
|
def tables
|
29
35
|
::ActiveRecord::Base.connection.tables - skip_tables
|
30
36
|
end
|
31
37
|
|
38
|
+
# Returns tables that should never be cleared (those that contain migrations information).
|
32
39
|
def skip_tables
|
33
40
|
%w( schema_info schema_migrations )
|
34
41
|
end
|
35
42
|
|
43
|
+
# Extensions for active record class
|
36
44
|
module ActiveRecordExtensions
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
module Class
|
46
|
+
# Two forms of this method can be used. First one is typically used inside blueprint block. Essentially it does
|
47
|
+
# same as <tt>create!</tt>, except it does bypass attr_protected and attr_accessible. It accepts only a hash or attributes,
|
48
|
+
# same as <tt>create!</tt> does.
|
49
|
+
# blueprint :post => :user do
|
50
|
+
# @user.posts.blueprint(:title => 'first post', :text => 'My first post')
|
51
|
+
# end
|
52
|
+
# The second form is used when you want to define new blueprint. It takes first argument as name of blueprint
|
53
|
+
# and second one as hash of attributes. As you cannot use instance variables outside of blueprint block, you need
|
54
|
+
# to prefix them with colon. So the example above could be rewritten like this:
|
55
|
+
# Post.blueprint(:post, :title => 'first post', :text => 'My first post', :user => :@user).depends_on(:user)
|
56
|
+
# or like this:
|
57
|
+
# Post.blueprint({:post => :user}, :title => 'first post', :text => 'My first post', :user => :@user)
|
58
|
+
def blueprint(*args)
|
59
|
+
attributes = args.extract_options!
|
60
|
+
if args.present?
|
61
|
+
klass = self
|
62
|
+
Blueprints::Plan.new(*args) do
|
63
|
+
klass.blueprint attributes.merge(options)
|
49
64
|
end
|
50
|
-
|
65
|
+
else
|
66
|
+
returning(self.new) { |object| object.blueprint(attributes) }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module Instance
|
72
|
+
# Updates attributes of object and calls save!. Bypasses attr_protected ant attr_accessible.
|
73
|
+
def blueprint(attributes)
|
74
|
+
attributes.each do |attr, value|
|
75
|
+
value = Blueprints::Namespace.root.context.instance_variable_get(value) if value.is_a? Symbol and value.to_s =~ /^@.+$/
|
76
|
+
send("#{attr}=", value)
|
51
77
|
end
|
78
|
+
save!
|
52
79
|
end
|
53
80
|
end
|
54
81
|
end
|
@@ -1,12 +1,16 @@
|
|
1
1
|
module Blueprints
|
2
2
|
module DatabaseBackends
|
3
|
+
# Database backend when no orm is actually used. Can be adapted to work with any kind of data.
|
3
4
|
class None
|
5
|
+
# Dummy method
|
4
6
|
def start_transaction
|
5
7
|
end
|
6
8
|
|
9
|
+
# Dummy method
|
7
10
|
def revert_transaction
|
8
11
|
end
|
9
12
|
|
13
|
+
# Dummy method
|
10
14
|
def delete_tables(delete_policy, *args)
|
11
15
|
end
|
12
16
|
end
|
data/lib/blueprints/errors.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Blueprints
|
2
|
+
# Is raised when blueprint or namespace is not found.
|
2
3
|
class PlanNotFoundError < NameError
|
3
4
|
def initialize(*args)
|
4
5
|
@plans = args
|
@@ -8,4 +9,4 @@ module Blueprints
|
|
8
9
|
"Plan/namespace not found '#{@plans.join(',')}'"
|
9
10
|
end
|
10
11
|
end
|
11
|
-
end
|
12
|
+
end
|
@@ -1,6 +1,9 @@
|
|
1
|
-
module Spec
|
2
|
-
module Runner
|
1
|
+
module Spec #:nodoc:
|
2
|
+
module Runner #:nodoc:
|
3
3
|
class Configuration
|
4
|
+
# Enables blueprints in rspec. Is automatically added if <tt>Spec</tt> is defined at loading time or <tt>script/spec</tt>
|
5
|
+
# is used. You might need to require it manually in certain case (eg. running specs from metrics).
|
6
|
+
# Accepts options hash. For supported options please check Blueprints.load.
|
4
7
|
def enable_blueprints(options = {})
|
5
8
|
Blueprints.load(options)
|
6
9
|
|
@@ -14,4 +17,4 @@ module Spec
|
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
17
|
-
end
|
20
|
+
end
|
@@ -1,12 +1,16 @@
|
|
1
|
-
module Test
|
2
|
-
module Unit
|
1
|
+
module Test #:nodoc:
|
2
|
+
module Unit #:nodoc:
|
3
3
|
class TestCase
|
4
|
+
# Runs tests with blueprints support
|
4
5
|
def run_with_blueprints(result, &progress_block)
|
5
6
|
Blueprints.setup(self)
|
6
7
|
run_without_blueprints(result, &progress_block)
|
7
8
|
Blueprints.teardown
|
8
9
|
end
|
9
10
|
|
11
|
+
# Enables blueprints in test/unit. Is automatically added if <tt>Spec</tt> is not defined at loading time.
|
12
|
+
# You might need to require it manually in certain case (eg. using both rspec and test/unit).
|
13
|
+
# Accepts options hash. For supported options please check Blueprints.load.
|
10
14
|
def self.enable_blueprints(options = {})
|
11
15
|
include Blueprints::Helper
|
12
16
|
Blueprints.load(options)
|
@@ -14,4 +18,4 @@ module Test
|
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
17
|
-
end
|
21
|
+
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
module Blueprints
|
2
|
+
# Module that blueprints file is executed against. Defined <tt>blueprint</tt> and <tt>namespace</tt> methods.
|
2
3
|
module FileContext
|
4
|
+
# Creates a new plan by name and block passed
|
3
5
|
def self.blueprint(plan, &block)
|
4
6
|
Plan.new(plan, &block)
|
5
7
|
end
|
6
8
|
|
9
|
+
# Creates new namespace by name, and evaluates block against it.
|
7
10
|
def self.namespace(name)
|
8
11
|
old_namespace = Namespace.root
|
9
12
|
namespace = Namespace.new(name)
|
@@ -13,4 +16,4 @@ module Blueprints
|
|
13
16
|
Namespace.root = old_namespace
|
14
17
|
end
|
15
18
|
end
|
16
|
-
end
|
19
|
+
end
|
data/lib/blueprints/helper.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
module Blueprints
|
2
|
+
# A helper module that should be included in test framework. Adds methods <tt>build</tt> and <tt>demolish</tt>
|
2
3
|
module Helper
|
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
|
+
# # build :apple and orange blueprints
|
7
|
+
# build :apple, :orange
|
8
|
+
#
|
9
|
+
# # build :apple scenario with additional options
|
10
|
+
# build :apple, :color => 'red'
|
3
11
|
def build_plan(*names)
|
4
12
|
result = Namespace.root.build(*names).last
|
5
13
|
Namespace.root.copy_ivars(self)
|
@@ -8,6 +16,10 @@ module Blueprints
|
|
8
16
|
|
9
17
|
alias :build :build_plan
|
10
18
|
|
19
|
+
# Clears all tables in database. You can pass table names to clear only those tables. You can also pass <tt>:undo</tt> option
|
20
|
+
# to remove scenarios from built scenarios cache.
|
21
|
+
#
|
22
|
+
# TODO: add sample usage
|
11
23
|
def demolish(*args)
|
12
24
|
options = args.extract_options!
|
13
25
|
Blueprints.delete_tables(*args)
|
@@ -23,4 +35,4 @@ module Blueprints
|
|
23
35
|
end
|
24
36
|
end
|
25
37
|
end
|
26
|
-
end
|
38
|
+
end
|
data/lib/blueprints/namespace.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
module Blueprints
|
2
|
+
# Namespace class, inherits from <tt>Buildable</tt>. Allows adding and finding child blueprints/namespaces and building
|
3
|
+
# all it's children.
|
2
4
|
class Namespace < Buildable
|
3
5
|
cattr_accessor :root
|
4
6
|
delegate :empty?, :size, :to => :@children
|
@@ -28,4 +30,4 @@ module Blueprints
|
|
28
30
|
Namespace.root.add_variable(path, @children.collect {|p| p.last.build }.uniq)
|
29
31
|
end
|
30
32
|
end
|
31
|
-
end
|
33
|
+
end
|
data/lib/blueprints/plan.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
module Blueprints
|
2
|
+
# Class for actual blueprints. Allows building itself by executing block passed against current context.
|
2
3
|
class Plan < Buildable
|
4
|
+
# Initializes blueprint by name and block
|
3
5
|
def initialize(name, &block)
|
4
6
|
super(name)
|
5
7
|
@block = block
|
6
8
|
end
|
7
9
|
|
10
|
+
# Builds plan and adds it to executed plan hash. Setups instance variable with same name as plan if it is not defined yet.
|
8
11
|
def build_plan
|
9
12
|
surface_errors do
|
10
13
|
if @block
|
11
|
-
@result = Namespace.root.context.
|
14
|
+
@result = Namespace.root.context.instance_eval(&@block)
|
12
15
|
Namespace.root.add_variable(path, @result)
|
13
16
|
end
|
14
17
|
end unless Namespace.root.executed_plans.include?(path)
|
@@ -25,4 +28,4 @@ module Blueprints
|
|
25
28
|
raise error
|
26
29
|
end
|
27
30
|
end
|
28
|
-
end
|
31
|
+
end
|
@@ -1,40 +1,50 @@
|
|
1
1
|
module Blueprints
|
2
|
+
# Defines a root namespace that is used when no other namespace is. Apart from functionality in namespace it also allows
|
3
|
+
# building blueprints/namespaces by name. Is also used for copying instance variables between blueprints/contexts/global
|
4
|
+
# context.
|
2
5
|
class RootNamespace < Namespace
|
3
6
|
attr_reader :context, :plans
|
4
7
|
attr_accessor :executed_plans
|
5
|
-
|
8
|
+
|
6
9
|
def initialize
|
7
10
|
@executed_plans = Set.new
|
8
11
|
@global_executed_plans = Set.new
|
9
|
-
@global_context = Module.new
|
10
12
|
|
11
13
|
super ''
|
12
14
|
end
|
13
15
|
|
16
|
+
# Loads all instance variables from global context to current one.
|
14
17
|
def setup
|
15
|
-
@context =
|
18
|
+
@context = Blueprints::Context.new
|
19
|
+
YAML.load(@global_variables).each { |name, value| @context.instance_variable_set(name, value) }
|
16
20
|
@executed_plans = @global_executed_plans.clone
|
17
21
|
end
|
18
22
|
|
23
|
+
# Copies all instance variables from current context to another one.
|
19
24
|
def copy_ivars(to)
|
20
25
|
@context.instance_variables.each do |iv|
|
21
26
|
to.instance_variable_set(iv, @context.instance_variable_get(iv))
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
30
|
+
# Sets up global context and executes prebuilt blueprints against it.
|
25
31
|
def prebuild(plans)
|
26
|
-
@context =
|
32
|
+
@context = Blueprints::Context.new
|
27
33
|
@global_scenarios = build(*plans) if plans
|
28
34
|
@global_executed_plans = @executed_plans
|
29
|
-
|
35
|
+
|
36
|
+
@global_variables = YAML.dump(@context.instance_variables.each_with_object({}) {|iv, hash| hash[iv] = @context.instance_variable_get(iv) })
|
30
37
|
end
|
31
38
|
|
39
|
+
# Builds blueprints that are passed against current context.
|
32
40
|
def build(*names)
|
41
|
+
@context.options = names.extract_options!
|
33
42
|
names.map {|name| self[name].build}
|
34
43
|
end
|
35
44
|
|
45
|
+
# Sets instance variable in current context to passed value.
|
36
46
|
def add_variable(name, value)
|
37
|
-
name = "@#{name}" unless name.to_s[0, 1] == "@"
|
47
|
+
name = "@#{name}" unless name.to_s[0, 1] == "@"
|
38
48
|
@context.instance_variable_set(name, value) unless @context.instance_variable_get(name)
|
39
49
|
end
|
40
50
|
|
@@ -7,7 +7,7 @@ describe Blueprints do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should support required ORMS" do
|
10
|
-
Blueprints.supported_orms.should
|
10
|
+
Blueprints.supported_orms.should =~ [:active_record, :none]
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -221,7 +221,7 @@ describe Blueprints do
|
|
221
221
|
Blueprints::Namespace.root.expects(:empty?).returns(true)
|
222
222
|
lambda {
|
223
223
|
Blueprints.load(:orm => :unknown)
|
224
|
-
}.should raise_error(ArgumentError, "Unsupported ORM unknown. Blueprints supports only
|
224
|
+
}.should raise_error(ArgumentError, "Unsupported ORM unknown. Blueprints supports only #{Blueprints.supported_orms.join(', ')}")
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
@@ -246,6 +246,18 @@ describe Blueprints do
|
|
246
246
|
@acorn.should_not be_nil
|
247
247
|
@acorn.tree.should == @oak
|
248
248
|
end
|
249
|
+
|
250
|
+
it "should allow updating object using blueprint method" do
|
251
|
+
build :oak
|
252
|
+
@oak.blueprint(:size => 'updated')
|
253
|
+
@oak.reload.size.should == 'updated'
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should automatically merge passed options" do
|
257
|
+
build :oak, :size => 'optional'
|
258
|
+
@oak.name.should == 'Oak'
|
259
|
+
@oak.size.should == 'optional'
|
260
|
+
end
|
249
261
|
end
|
250
262
|
|
251
263
|
describe "with pitted namespace" do
|
@@ -294,5 +306,19 @@ describe Blueprints do
|
|
294
306
|
end
|
295
307
|
end
|
296
308
|
end
|
309
|
+
|
310
|
+
describe 'extra parameters' do
|
311
|
+
it "should allow passing extra parameters when building" do
|
312
|
+
build :apple_with_params, :average_diameter => 14
|
313
|
+
@apple_with_params.average_diameter.should == 14
|
314
|
+
@apple_with_params.species.should == 'apple'
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should allow set options to empty hash if no parameters are passed" do
|
318
|
+
build :apple_with_params
|
319
|
+
@apple_with_params.average_diameter.should == nil
|
320
|
+
@apple_with_params.species.should == 'apple'
|
321
|
+
end
|
322
|
+
end
|
297
323
|
end
|
298
324
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blueprints
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrius Chamentauskas
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-25 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- install.rb
|
34
34
|
- lib/blueprints.rb
|
35
35
|
- lib/blueprints/buildable.rb
|
36
|
+
- lib/blueprints/context.rb
|
36
37
|
- lib/blueprints/database_backends/abstract.rb
|
37
38
|
- lib/blueprints/database_backends/active_record.rb
|
38
39
|
- lib/blueprints/database_backends/none.rb
|