blueprints 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/README.rdoc +55 -57
- data/Rakefile +15 -0
- data/VERSION +1 -0
- data/blueprints.gemspec +88 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/blueprints.rb +21 -42
- data/lib/blueprints/database_backends/abstract.rb +17 -0
- data/lib/blueprints/database_backends/active_record.rb +58 -0
- data/lib/blueprints/database_backends/none.rb +14 -0
- data/lib/blueprints/{rspec_extensions.rb → extensions/rspec.rb} +0 -0
- data/lib/blueprints/{test_unit_extensions.rb → extensions/test_unit.rb} +0 -0
- data/script/load_schema +14 -0
- data/script/rspec_to_test +26 -0
- data/spec/active_record/blueprints_spec.rb +14 -11
- data/spec/active_record/spec_helper.rb +0 -1
- data/test/blueprints_test.rb +104 -22
- data/test/test_helper.rb +5 -5
- data/uninstall.rb +1 -0
- metadata +48 -33
- data/lib/blueprints/ar_extensions.rb +0 -23
data/.gitignore
ADDED
data/README.rdoc
CHANGED
@@ -6,44 +6,44 @@ Another replacement for factories and fixtures that focuses on being DRY and mak
|
|
6
6
|
|
7
7
|
Blueprints look like this:
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
blueprint :apple do
|
10
|
+
Fruit.create! :species => 'apple'
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
blueprint :orange do
|
14
|
+
Fruit.create! :species => 'orange'
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
blueprint :fruitbowl => [:apple, :orange] do
|
18
|
+
FruitBowl.create! :fruit => [@apple,@orange]
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
blueprint :kitchen => :fruitbowl do
|
22
|
+
Kitchen.create! :fruitbowl => @fruitbowl
|
23
|
+
end
|
24
24
|
|
25
25
|
...and you use them in specs like:
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should be an apple" do
|
33
|
-
@apple.species.should == 'apple'
|
34
|
-
end
|
27
|
+
describe Fruit, "apple" do
|
28
|
+
before do
|
29
|
+
build :apple
|
35
30
|
end
|
36
31
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
32
|
+
it "should be an apple" do
|
33
|
+
@apple.species.should == 'apple'
|
34
|
+
end
|
35
|
+
end
|
41
36
|
|
42
|
-
|
43
|
-
|
44
|
-
|
37
|
+
describe FruitBowl, "with and apple and an orange" do
|
38
|
+
before do
|
39
|
+
build :fruitbowl
|
45
40
|
end
|
46
41
|
|
42
|
+
it "should have 2 fruits" do
|
43
|
+
@fruitbowl.should have(2).fruit
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
47
|
Result of 'blueprint' block is assigned to an instance variable with the same name. You can also assign your own instance variables
|
48
48
|
inside 'blueprint' block and they will be accessible in tests that build this blueprint.
|
49
49
|
|
@@ -53,31 +53,31 @@ and attr_accessible restrictions (which is what you usually want in tests).
|
|
53
53
|
All blueprints are run only once, no matter how many times they were called, meaning that you don't need to worry about
|
54
54
|
duplicating data.
|
55
55
|
|
56
|
-
=== Shorthands
|
56
|
+
=== Shorthands
|
57
57
|
|
58
58
|
There's a shorthand for these type of scenarios:
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
blueprint :something do
|
61
|
+
@something = SomeModel.blueprint :field => 'value'
|
62
|
+
end
|
63
63
|
|
64
64
|
You can just type:
|
65
65
|
|
66
|
-
|
66
|
+
SomeModel.blueprint :something, :field => 'value'
|
67
67
|
|
68
68
|
If you need to make associations then:
|
69
69
|
|
70
|
-
|
70
|
+
SomeModel.blueprint :something, :associated_column => :@association_instance_variable
|
71
71
|
|
72
72
|
And if you also need it to depend on other blueprints:
|
73
73
|
|
74
|
-
|
74
|
+
SomeModel.blueprint({:something => :some_blueprint}, :associated_column => :@some_iv)
|
75
75
|
|
76
76
|
...or...
|
77
77
|
|
78
|
-
|
78
|
+
SomeModel.blueprint(:something, :associated_column => :@some_iv).depends_on(:some_blueprint) # I prefer this one
|
79
79
|
|
80
|
-
=== Blueprints file
|
80
|
+
=== Blueprints file
|
81
81
|
|
82
82
|
Blueprints searches for blueprints files in this particular order in Rails (Merb) root:
|
83
83
|
* blueprint.rb
|
@@ -86,22 +86,22 @@ Blueprints searches for blueprints files in this particular order in Rails (Merb
|
|
86
86
|
* spec/blueprint/*.rb
|
87
87
|
* test/blueprint.rb
|
88
88
|
* test/blueprint/*.rb
|
89
|
-
You can pass :root option to override framework root and :filename option to pass custom filename pattern
|
89
|
+
You can pass :root option to override framework root and :filename option to pass custom filename pattern
|
90
90
|
|
91
91
|
== Setup
|
92
92
|
|
93
93
|
The easiest way to install this gem for Ruby on Rails is just add this line to config/environment.rb (or config/environments/test.rb):
|
94
94
|
|
95
|
-
|
95
|
+
config.gem 'blueprints', :source => 'http://gemcutter.org'
|
96
96
|
|
97
97
|
If you’re not using rails, then you can install it through command line
|
98
98
|
|
99
|
-
|
100
|
-
|
99
|
+
gem sources -a http://gemcutter.org
|
100
|
+
sudo gem install blueprints
|
101
101
|
|
102
102
|
Lastly you could use it as plugin:
|
103
103
|
|
104
|
-
|
104
|
+
ruby script/plugin install git://github.com/sinsiliux/blueprints.git
|
105
105
|
|
106
106
|
Blueprints is activated by calling enable_blueprints. For specifics on how to call that in your testing framework see a little lower.
|
107
107
|
enable_blueprints supports these parameters:
|
@@ -114,32 +114,29 @@ enable_blueprints supports these parameters:
|
|
114
114
|
|
115
115
|
Add the following to spec_helper.rb
|
116
116
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
117
|
+
Spec::Runner.configure do |config|
|
118
|
+
...
|
119
|
+
config.enable_blueprints :filename => 'scenarios.rb', :prebuild => :preloaded_scenario
|
120
|
+
end
|
122
121
|
|
123
122
|
=== Test::Unit
|
124
123
|
|
125
124
|
Add the following lines to test_helper.rb
|
126
125
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
end
|
126
|
+
class ActiveSupport::TestCase
|
127
|
+
...
|
128
|
+
enable_blueprints
|
129
|
+
end
|
132
130
|
|
133
131
|
== Advanced Usage
|
134
132
|
|
135
133
|
Its just ruby, right? So go nuts:
|
136
134
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
instance_variable_set("@user_#{i}",user)
|
141
|
-
end
|
135
|
+
1.upto(9) do |i|
|
136
|
+
blueprint("user_#{i}") do
|
137
|
+
User.create! :name => "user#{i}"
|
142
138
|
end
|
139
|
+
end
|
143
140
|
|
144
141
|
== Transactions
|
145
142
|
|
@@ -148,10 +145,11 @@ starting point. Starting point is empty database + any scenarios that you specif
|
|
148
145
|
|
149
146
|
== TODO
|
150
147
|
|
151
|
-
* Add plan namespaces for better organisation.
|
152
148
|
* Add ability to revert one plan.
|
153
149
|
* Add preloading plans for whole block of tests.
|
154
150
|
* Fix rake tasks
|
151
|
+
* Add merb support
|
152
|
+
* Add support for other test frameworks (check support of cucumber)
|
155
153
|
|
156
154
|
== Credits
|
157
155
|
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require 'jeweler'
|
4
|
+
Jeweler::Tasks.new do |gemspec|
|
5
|
+
gemspec.name = "blueprints"
|
6
|
+
gemspec.summary = "Another replacement for factories and fixtures"
|
7
|
+
gemspec.description = "Another replacement for factories and fixtures. The library that lazy typists will love"
|
8
|
+
gemspec.email = "sinsiliux@gmail.com"
|
9
|
+
gemspec.homepage = "http://github.com/sinsiliux/blueprints"
|
10
|
+
gemspec.authors = ["Andrius Chamentauskas"]
|
11
|
+
end
|
12
|
+
Jeweler::GemcutterTasks.new
|
13
|
+
rescue LoadError
|
14
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
15
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.4
|
data/blueprints.gemspec
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{blueprints}
|
8
|
+
s.version = "0.3.4"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Andrius Chamentauskas"]
|
12
|
+
s.date = %q{2009-12-10}
|
13
|
+
s.description = %q{Another replacement for factories and fixtures. The library that lazy typists will love}
|
14
|
+
s.email = %q{sinsiliux@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"blueprints.gemspec",
|
26
|
+
"init.rb",
|
27
|
+
"install.rb",
|
28
|
+
"lib/blueprints.rb",
|
29
|
+
"lib/blueprints/buildable.rb",
|
30
|
+
"lib/blueprints/database_backends/abstract.rb",
|
31
|
+
"lib/blueprints/database_backends/active_record.rb",
|
32
|
+
"lib/blueprints/database_backends/none.rb",
|
33
|
+
"lib/blueprints/errors.rb",
|
34
|
+
"lib/blueprints/extensions/rspec.rb",
|
35
|
+
"lib/blueprints/extensions/test_unit.rb",
|
36
|
+
"lib/blueprints/file_context.rb",
|
37
|
+
"lib/blueprints/helper.rb",
|
38
|
+
"lib/blueprints/namespace.rb",
|
39
|
+
"lib/blueprints/plan.rb",
|
40
|
+
"lib/blueprints/root_namespace.rb",
|
41
|
+
"script/load_schema",
|
42
|
+
"script/rspec_to_test",
|
43
|
+
"spec/active_record/blueprint.rb",
|
44
|
+
"spec/active_record/blueprints_spec.rb",
|
45
|
+
"spec/active_record/fixtures/database.yml.example",
|
46
|
+
"spec/active_record/fixtures/fruit.rb",
|
47
|
+
"spec/active_record/fixtures/schema.rb",
|
48
|
+
"spec/active_record/fixtures/tree.rb",
|
49
|
+
"spec/active_record/spec_helper.rb",
|
50
|
+
"spec/no_db/blueprint.rb",
|
51
|
+
"spec/no_db/blueprints_spec.rb",
|
52
|
+
"spec/no_db/fixtures/fruit.rb",
|
53
|
+
"spec/no_db/spec_helper.rb",
|
54
|
+
"test/blueprints_test.rb",
|
55
|
+
"test/test_helper.rb",
|
56
|
+
"uninstall.rb"
|
57
|
+
]
|
58
|
+
s.homepage = %q{http://github.com/sinsiliux/blueprints}
|
59
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
60
|
+
s.require_paths = ["lib"]
|
61
|
+
s.rubygems_version = %q{1.3.5}
|
62
|
+
s.summary = %q{Another replacement for factories and fixtures}
|
63
|
+
s.test_files = [
|
64
|
+
"spec/no_db/fixtures/fruit.rb",
|
65
|
+
"spec/no_db/blueprint.rb",
|
66
|
+
"spec/no_db/blueprints_spec.rb",
|
67
|
+
"spec/no_db/spec_helper.rb",
|
68
|
+
"spec/active_record/fixtures/tree.rb",
|
69
|
+
"spec/active_record/fixtures/fruit.rb",
|
70
|
+
"spec/active_record/fixtures/schema.rb",
|
71
|
+
"spec/active_record/blueprint.rb",
|
72
|
+
"spec/active_record/blueprints_spec.rb",
|
73
|
+
"spec/active_record/spec_helper.rb",
|
74
|
+
"test/test_helper.rb",
|
75
|
+
"test/blueprints_test.rb"
|
76
|
+
]
|
77
|
+
|
78
|
+
if s.respond_to? :specification_version then
|
79
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
80
|
+
s.specification_version = 3
|
81
|
+
|
82
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
83
|
+
else
|
84
|
+
end
|
85
|
+
else
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'blueprints' if RAILS_ENV == 'test'
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
data/lib/blueprints.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
require 'activesupport'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
require File.join(File.dirname(__FILE__), 'blueprints/errors')
|
9
|
-
if defined? Spec or $0 =~ /script.spec$/
|
10
|
-
require File.join(File.dirname(__FILE__), 'blueprints/rspec_extensions')
|
2
|
+
files = %w{
|
3
|
+
buildable namespace root_namespace plan file_context helper errors
|
4
|
+
database_backends/abstract database_backends/active_record database_backends/none
|
5
|
+
}
|
6
|
+
files << if defined? Spec or $0 =~ /script.spec$/
|
7
|
+
'extensions/rspec'
|
11
8
|
else
|
12
|
-
|
9
|
+
'extensions/test_unit'
|
13
10
|
end
|
11
|
+
files.each {|f| require File.join(File.dirname(__FILE__), 'blueprints', f) }
|
14
12
|
|
15
13
|
module Blueprints
|
16
14
|
PLAN_FILES = [nil, "spec", "test"].map do |dir|
|
@@ -19,9 +17,10 @@ module Blueprints
|
|
19
17
|
["#{path}.rb", File.join(path, "*.rb")]
|
20
18
|
end
|
21
19
|
end.flatten
|
22
|
-
SUPPORTED_ORMS = [:none, :active_record]
|
23
20
|
|
24
|
-
|
21
|
+
def self.supported_orms
|
22
|
+
(DatabaseBackends.constants - ['Abstract']).collect {|class_name| class_name.underscore.to_sym }
|
23
|
+
end
|
25
24
|
|
26
25
|
def self.framework_root
|
27
26
|
@@framework_root ||= RAILS_ROOT rescue Rails.root rescue Merb.root rescue nil
|
@@ -30,18 +29,11 @@ module Blueprints
|
|
30
29
|
def self.setup(current_context)
|
31
30
|
Namespace.root.setup
|
32
31
|
Namespace.root.copy_ivars(current_context)
|
33
|
-
|
34
|
-
ActiveRecord::Base.connection.increment_open_transactions
|
35
|
-
ActiveRecord::Base.connection.transaction_joinable = false
|
36
|
-
ActiveRecord::Base.connection.begin_db_transaction
|
37
|
-
end
|
32
|
+
@@orm.start_transaction
|
38
33
|
end
|
39
34
|
|
40
35
|
def self.teardown
|
41
|
-
|
42
|
-
ActiveRecord::Base.connection.rollback_db_transaction
|
43
|
-
ActiveRecord::Base.connection.decrement_open_transactions
|
44
|
-
end
|
36
|
+
@@orm.rollback_transaction
|
45
37
|
end
|
46
38
|
|
47
39
|
def self.load(options = {})
|
@@ -49,13 +41,11 @@ module Blueprints
|
|
49
41
|
options.symbolize_keys!
|
50
42
|
return unless Namespace.root.empty?
|
51
43
|
|
52
|
-
|
53
|
-
raise ArgumentError, "Unsupported ORM #{
|
44
|
+
orm = (options.delete(:orm) || :active_record).to_sym
|
45
|
+
raise ArgumentError, "Unsupported ORM #{orm}. Blueprints supports only #{supported_orms.join(', ')}" unless supported_orms.include?(orm)
|
46
|
+
@@orm = DatabaseBackends.const_get(orm.to_s.classify).new
|
47
|
+
@@orm.delete_tables(@@delete_policy = options[:delete_policy])
|
54
48
|
|
55
|
-
require File.join(File.dirname(__FILE__), 'blueprints', 'ar_extensions') unless @@orm == :none
|
56
|
-
|
57
|
-
@@delete_sql = DELETE_POLICIES[options[:delete_policy]] || DELETE_POLICIES[:delete]
|
58
|
-
delete_tables
|
59
49
|
@@framework_root = options[:root] if options[:root]
|
60
50
|
load_scenarios_files(options[:filename] || PLAN_FILES)
|
61
51
|
|
@@ -65,29 +55,18 @@ module Blueprints
|
|
65
55
|
def self.load_scenarios_files(*patterns)
|
66
56
|
patterns.flatten!
|
67
57
|
patterns.collect! {|pattern| File.join(framework_root, pattern)} if framework_root
|
68
|
-
|
58
|
+
|
69
59
|
patterns.each do |pattern|
|
70
60
|
unless (files = Dir.glob(pattern)).empty?
|
71
61
|
files.each{|f| FileContext.module_eval File.read(f)}
|
72
62
|
return
|
73
63
|
end
|
74
64
|
end
|
75
|
-
|
76
|
-
raise "Plans file not found! Put plans in #{patterns.join(' or ')} or pass custom filename pattern with :filename option"
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.delete_tables(*args)
|
80
|
-
unless @@orm == :none
|
81
|
-
args = tables if args.blank?
|
82
|
-
args.each { |t| ActiveRecord::Base.connection.delete(@@delete_sql % t) }
|
83
|
-
end
|
84
|
-
end
|
85
65
|
|
86
|
-
|
87
|
-
ActiveRecord::Base.connection.tables - skip_tables
|
66
|
+
raise "Plans file not found! Put plans in #{patterns.join(' or ')} or pass custom filename pattern with :filename option"
|
88
67
|
end
|
89
68
|
|
90
|
-
def self.
|
91
|
-
|
69
|
+
def self.delete_tables(*tables)
|
70
|
+
@@orm.delete_tables(@@delete_policy, *tables)
|
92
71
|
end
|
93
72
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Blueprints
|
2
|
+
module DatabaseBackends
|
3
|
+
class Abstract
|
4
|
+
def start_transaction
|
5
|
+
raise NotImplementedError
|
6
|
+
end
|
7
|
+
|
8
|
+
def revert_transaction
|
9
|
+
raise NotImplementedError
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_tables(delete_policy, *args)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Blueprints
|
2
|
+
module DatabaseBackends
|
3
|
+
class ActiveRecord
|
4
|
+
DELETE_POLICIES = {:delete => "DELETE FROM %s", :truncate => "TRUNCATE %s"}
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
::ActiveRecord::Base.extend(ActiveRecordExtensions)
|
8
|
+
end
|
9
|
+
|
10
|
+
def start_transaction
|
11
|
+
::ActiveRecord::Base.connection.increment_open_transactions
|
12
|
+
::ActiveRecord::Base.connection.transaction_joinable = false
|
13
|
+
::ActiveRecord::Base.connection.begin_db_transaction
|
14
|
+
end
|
15
|
+
|
16
|
+
def rollback_transaction
|
17
|
+
::ActiveRecord::Base.connection.rollback_db_transaction
|
18
|
+
::ActiveRecord::Base.connection.decrement_open_transactions
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete_tables(delete_policy, *args)
|
22
|
+
delete_policy ||= :delete
|
23
|
+
raise ArgumentError, "Unknown delete policy #{delete_policy}" unless DELETE_POLICIES.keys.include?(delete_policy)
|
24
|
+
args = tables if args.blank?
|
25
|
+
args.each { |t| ::ActiveRecord::Base.connection.delete(DELETE_POLICIES[delete_policy] % t) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def tables
|
29
|
+
::ActiveRecord::Base.connection.tables - skip_tables
|
30
|
+
end
|
31
|
+
|
32
|
+
def skip_tables
|
33
|
+
%w( schema_info schema_migrations )
|
34
|
+
end
|
35
|
+
|
36
|
+
module ActiveRecordExtensions
|
37
|
+
def blueprint(*args)
|
38
|
+
options = args.extract_options!
|
39
|
+
if args.present?
|
40
|
+
klass = self
|
41
|
+
Blueprints::Plan.new(*args) do
|
42
|
+
klass.blueprint options
|
43
|
+
end
|
44
|
+
else
|
45
|
+
returning(self.new) do |object|
|
46
|
+
options.each do |attr, value|
|
47
|
+
value = Blueprints::Namespace.root.context.instance_variable_get(value) if value.is_a? Symbol and value.to_s =~ /^@.+$/
|
48
|
+
object.send("#{attr}=", value)
|
49
|
+
end
|
50
|
+
object.save!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
File without changes
|
File without changes
|
data/script/load_schema
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
Dir.chdir File.join(File.dirname(__FILE__), '..')
|
7
|
+
|
8
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
9
|
+
|
10
|
+
databases = YAML::load(IO.read("spec/active_record/fixtures/database.yml"))
|
11
|
+
db_info = databases[ENV["DB"] || "test"]
|
12
|
+
ActiveRecord::Base.establish_connection(db_info)
|
13
|
+
|
14
|
+
load("spec/active_record/fixtures/schema.rb")
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
Dir.chdir File.join(File.dirname(__FILE__), '..')
|
3
|
+
data = IO.read('spec/active_record/blueprints_spec.rb')
|
4
|
+
|
5
|
+
data.gsub!("require File.dirname(__FILE__) + '/spec_helper'", "require File.dirname(__FILE__) + '/test_helper'")
|
6
|
+
data.gsub!("describe Blueprints do", 'class BlueprintsTest < ActiveSupport::TestCase')
|
7
|
+
|
8
|
+
# lambda {
|
9
|
+
# hornsby_clear :undo => :just_orange
|
10
|
+
# }.should raise_error(ArgumentError)
|
11
|
+
data.gsub!(/(\s+)lambda \{\n(.*)\n(\s+)\}.should raise_error\((.*)\)/, "\\1assert_raise(\\4) do\n\\2\n\\3end")
|
12
|
+
# .should_not => assert(!())
|
13
|
+
data.gsub!(/^(\s+)(.*)\.should_not(.*)/, '\1assert(!(\2\3))')
|
14
|
+
# .should => assert()
|
15
|
+
data.gsub!(/^(\s+)(.*)\.should(.*)/, '\1assert(\2\3)')
|
16
|
+
# be_nil => .nil?
|
17
|
+
data.gsub!(/ be_([^\(\)]*)/, '.\1?')
|
18
|
+
# have(2).items => .size == 2
|
19
|
+
data.gsub!(/ have\((\d+)\)\.items/, '.size == \1')
|
20
|
+
|
21
|
+
data.gsub!(/^(\s+)describe/, '\1context')
|
22
|
+
data.gsub!(/^(\s+)it (["'])(should )?/, '\1should \2')
|
23
|
+
data.gsub!(/^(\s+)before.*do/, '\1setup do')
|
24
|
+
data.gsub!(/^(\s+)after.*do/, '\1teardown do')
|
25
|
+
|
26
|
+
File.open('test/blueprints_test.rb', 'w') {|f| f.write(data)}
|
@@ -7,7 +7,7 @@ describe Blueprints do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should support required ORMS" do
|
10
|
-
Blueprints
|
10
|
+
Blueprints.supported_orms.should == [:active_record, :none]
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -137,9 +137,13 @@ describe Blueprints do
|
|
137
137
|
|
138
138
|
describe 'delete policies' do
|
139
139
|
before do
|
140
|
-
Blueprints::Namespace.root.
|
141
|
-
Blueprints.
|
142
|
-
Blueprints::Namespace.root.
|
140
|
+
Blueprints::Namespace.root.stubs(:empty?).returns(true)
|
141
|
+
Blueprints.stubs(:load_scenarios_files).with(Blueprints::PLAN_FILES)
|
142
|
+
Blueprints::Namespace.root.stubs(:prebuild).with(nil)
|
143
|
+
end
|
144
|
+
|
145
|
+
after do
|
146
|
+
Blueprints.send(:class_variable_set, :@@delete_policy, nil)
|
143
147
|
end
|
144
148
|
|
145
149
|
it "should allow using custom delete policy" do
|
@@ -149,11 +153,10 @@ describe Blueprints do
|
|
149
153
|
Blueprints.load(:delete_policy => :truncate)
|
150
154
|
end
|
151
155
|
|
152
|
-
it "should
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
Blueprints.load(:delete_policy => :ukndown)
|
156
|
+
it "should raise an error if unexisting delete policy given" do
|
157
|
+
lambda {
|
158
|
+
Blueprints.load(:delete_policy => :unknown)
|
159
|
+
}.should raise_error(ArgumentError, 'Unknown delete policy unknown')
|
157
160
|
end
|
158
161
|
end
|
159
162
|
|
@@ -218,7 +221,7 @@ describe Blueprints do
|
|
218
221
|
Blueprints::Namespace.root.expects(:empty?).returns(true)
|
219
222
|
lambda {
|
220
223
|
Blueprints.load(:orm => :unknown)
|
221
|
-
}.should raise_error(ArgumentError, "Unsupported ORM unknown. Blueprints supports only
|
224
|
+
}.should raise_error(ArgumentError, "Unsupported ORM unknown. Blueprints supports only active_record, none")
|
222
225
|
end
|
223
226
|
end
|
224
227
|
|
@@ -269,7 +272,7 @@ describe Blueprints do
|
|
269
272
|
@pitted_peach.should_not be_nil
|
270
273
|
@pitted_acorn.should_not be_nil
|
271
274
|
@pitted_red_apple.should_not be_nil
|
272
|
-
@pitted.should
|
275
|
+
@pitted.sort_by(&:id).should == [@pitted_peach_tree, @pitted_peach, @pitted_acorn, [@pitted_red_apple]].sort_by(&:id)
|
273
276
|
end
|
274
277
|
|
275
278
|
describe "with red namespace" do
|
data/test/blueprints_test.rb
CHANGED
@@ -1,10 +1,22 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
3
|
class BlueprintsTest < ActiveSupport::TestCase
|
4
|
-
context "
|
4
|
+
context "constants" do
|
5
5
|
should "be loaded from specified dirs" do
|
6
|
-
assert(Blueprints::PLAN_FILES == ["blueprint.rb", "blueprint/*.rb", "
|
6
|
+
assert(Blueprints::PLAN_FILES == ["blueprint.rb", "blueprint/*.rb", "spec/blueprint.rb", "spec/blueprint/*.rb", "test/blueprint.rb", "test/blueprint/*.rb"])
|
7
7
|
end
|
8
|
+
|
9
|
+
should "support required ORMS" do
|
10
|
+
assert(Blueprints::SUPPORTED_ORMS == [:none, :active_record])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
should "return result of built scenario when calling build" do
|
15
|
+
fruit = build :fruit
|
16
|
+
assert(fruit == @fruit)
|
17
|
+
|
18
|
+
apple = build :apple
|
19
|
+
assert(apple == @apple)
|
8
20
|
end
|
9
21
|
|
10
22
|
context "with apple scenario" do
|
@@ -117,7 +129,7 @@ class BlueprintsTest < ActiveSupport::TestCase
|
|
117
129
|
end
|
118
130
|
|
119
131
|
should "raise error when not executed scenarios passed to :undo option" do
|
120
|
-
assert_raise(
|
132
|
+
assert_raise(Blueprints::PlanNotFoundError, "Plan/namespace not found 'orange'") do
|
121
133
|
demolish :undo => :orange
|
122
134
|
end
|
123
135
|
end
|
@@ -125,9 +137,13 @@ class BlueprintsTest < ActiveSupport::TestCase
|
|
125
137
|
|
126
138
|
context 'delete policies' do
|
127
139
|
setup do
|
128
|
-
Blueprints::
|
129
|
-
Blueprints.
|
130
|
-
Blueprints::
|
140
|
+
Blueprints::Namespace.root.stubs(:empty?).returns(true)
|
141
|
+
Blueprints.stubs(:load_scenarios_files).with(Blueprints::PLAN_FILES)
|
142
|
+
Blueprints::Namespace.root.stubs(:prebuild).with(nil)
|
143
|
+
end
|
144
|
+
|
145
|
+
teardown do
|
146
|
+
Blueprints.send(:class_variable_set, :@@delete_policy, nil)
|
131
147
|
end
|
132
148
|
|
133
149
|
should "allow using custom delete policy" do
|
@@ -137,11 +153,10 @@ class BlueprintsTest < ActiveSupport::TestCase
|
|
137
153
|
Blueprints.load(:delete_policy => :truncate)
|
138
154
|
end
|
139
155
|
|
140
|
-
should "
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
Blueprints.load(:delete_policy => :ukndown)
|
156
|
+
should "raise an error if unexisting delete policy given" do
|
157
|
+
assert_raise(ArgumentError, 'Unknown delete policy unknown') do
|
158
|
+
Blueprints.load(:delete_policy => :unknown)
|
159
|
+
end
|
145
160
|
end
|
146
161
|
end
|
147
162
|
|
@@ -185,13 +200,13 @@ class BlueprintsTest < ActiveSupport::TestCase
|
|
185
200
|
|
186
201
|
context 'errors' do
|
187
202
|
should 'raise ScenarioNotFoundError when scenario could not be found' do
|
188
|
-
assert_raise(Blueprints::PlanNotFoundError, "Plan
|
203
|
+
assert_raise(Blueprints::PlanNotFoundError, "Plan/namespace not found 'not_existing'") do
|
189
204
|
build :not_existing
|
190
205
|
end
|
191
206
|
end
|
192
|
-
|
207
|
+
|
193
208
|
should 'raise ScenarioNotFoundError when scenario parent could not be found' do
|
194
|
-
assert_raise(Blueprints::PlanNotFoundError, "Plan
|
209
|
+
assert_raise(Blueprints::PlanNotFoundError, "Plan/namespace not found 'not_existing'") do
|
195
210
|
build :parent_not_existing
|
196
211
|
end
|
197
212
|
end
|
@@ -201,16 +216,83 @@ class BlueprintsTest < ActiveSupport::TestCase
|
|
201
216
|
Blueprints::Plan.new(1)
|
202
217
|
end
|
203
218
|
end
|
219
|
+
|
220
|
+
should "raise ArgumentError when unknown ORM specified" do
|
221
|
+
Blueprints::Namespace.root.expects(:empty?).returns(true)
|
222
|
+
assert_raise(ArgumentError, "Unsupported ORM unknown. Blueprints supports only none, active_record") do
|
223
|
+
Blueprints.load(:orm => :unknown)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context 'with active record blueprints extensions' do
|
229
|
+
should "build oak correctly" do
|
230
|
+
build :oak
|
231
|
+
assert(!(@oak.nil?))
|
232
|
+
assert(@oak.name == 'Oak')
|
233
|
+
assert(@oak.size == 'large')
|
234
|
+
end
|
235
|
+
|
236
|
+
should "build pine correctly" do
|
237
|
+
build :pine
|
238
|
+
assert(!(@the_pine.nil?))
|
239
|
+
assert(@the_pine.name == 'Pine')
|
240
|
+
assert(@the_pine.size == 'medium')
|
241
|
+
end
|
242
|
+
|
243
|
+
should "associate acorn with oak correctly" do
|
244
|
+
build :acorn
|
245
|
+
assert(!(@oak.nil?))
|
246
|
+
assert(!(@acorn.nil?))
|
247
|
+
assert(@acorn.tree == @oak)
|
248
|
+
end
|
204
249
|
end
|
205
250
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
251
|
+
context "with pitted namespace" do
|
252
|
+
should "allow building namespaced scenarios" do
|
253
|
+
build 'pitted.peach_tree'
|
254
|
+
assert(@pitted_peach_tree.name == 'pitted peach tree')
|
255
|
+
end
|
210
256
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
257
|
+
should "allow adding dependencies from same namespace" do
|
258
|
+
build 'pitted.peach'
|
259
|
+
assert(@pitted_peach.species == 'pitted peach')
|
260
|
+
assert(!(@pitted_peach_tree.nil?))
|
261
|
+
end
|
262
|
+
|
263
|
+
should "allow adding dependencies from root namespace" do
|
264
|
+
build 'pitted.acorn'
|
265
|
+
assert(@pitted_acorn.species == 'pitted acorn')
|
266
|
+
assert(!(@oak.nil?))
|
267
|
+
end
|
268
|
+
|
269
|
+
should "allow building whole namespace" do
|
270
|
+
build :pitted
|
271
|
+
assert(!(@pitted_peach_tree.nil?))
|
272
|
+
assert(!(@pitted_peach.nil?))
|
273
|
+
assert(!(@pitted_acorn.nil?))
|
274
|
+
assert(!(@pitted_red_apple.nil?))
|
275
|
+
assert(@pitted.sort_by(&:id) == [@pitted_peach_tree, @pitted_peach, @pitted_acorn, [@pitted_red_apple]].sort_by(&:id))
|
276
|
+
end
|
277
|
+
|
278
|
+
context "with red namespace" do
|
279
|
+
should "allow building blueprint with same name in different namespaces" do
|
280
|
+
build :apple, 'pitted.red.apple'
|
281
|
+
assert(@apple.species == 'apple')
|
282
|
+
assert(@pitted_red_apple.species == 'pitted red apple')
|
283
|
+
end
|
284
|
+
|
285
|
+
should "load dependencies when building namespaced blueprint if parent namespaces have any" do
|
286
|
+
build 'pitted.red.apple'
|
287
|
+
assert(!(@the_pine.nil?))
|
288
|
+
assert(!(@orange.nil?))
|
289
|
+
end
|
290
|
+
|
291
|
+
should "allow building nested namespaces scenarios" do
|
292
|
+
build 'pitted.red.apple'
|
293
|
+
assert(@pitted_red_apple.species == 'pitted red apple')
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
215
297
|
end
|
216
298
|
|
data/test/test_helper.rb
CHANGED
@@ -13,14 +13,14 @@ Dir.chdir(File.join(File.dirname(__FILE__), '..'))
|
|
13
13
|
|
14
14
|
ActiveRecord::Base.logger = Logger.new("debug.log")
|
15
15
|
|
16
|
-
databases = YAML::load(IO.read("spec/
|
16
|
+
databases = YAML::load(IO.read("spec/active_record/fixtures/database.yml"))
|
17
17
|
db_info = databases[ENV["DB"] || "test"]
|
18
18
|
ActiveRecord::Base.establish_connection(db_info)
|
19
19
|
|
20
20
|
require 'lib/blueprints'
|
21
|
-
require 'spec/
|
22
|
-
require 'spec/
|
21
|
+
require 'spec/active_record/fixtures/fruit'
|
22
|
+
require 'spec/active_record/fixtures/tree'
|
23
23
|
|
24
24
|
class ActiveSupport::TestCase
|
25
|
-
enable_blueprints :root => File.join(File.dirname(__FILE__), '..'), :prebuild => :big_cherry
|
26
|
-
end
|
25
|
+
enable_blueprints :root => File.join(File.dirname(__FILE__), '..'), :prebuild => :big_cherry, :filename => 'spec/active_record/blueprint.rb'
|
26
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
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.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrius Chamentauskas
|
@@ -9,48 +9,64 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-10 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
name: activesupport
|
17
|
-
type: :runtime
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 2.0.0
|
24
|
-
version:
|
14
|
+
dependencies: []
|
15
|
+
|
25
16
|
description: Another replacement for factories and fixtures. The library that lazy typists will love
|
26
17
|
email: sinsiliux@gmail.com
|
27
18
|
executables: []
|
28
19
|
|
29
20
|
extensions: []
|
30
21
|
|
31
|
-
extra_rdoc_files:
|
32
|
-
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.rdoc
|
33
25
|
files:
|
26
|
+
- .gitignore
|
27
|
+
- LICENSE
|
28
|
+
- README.rdoc
|
29
|
+
- Rakefile
|
30
|
+
- VERSION
|
31
|
+
- blueprints.gemspec
|
32
|
+
- init.rb
|
33
|
+
- install.rb
|
34
34
|
- lib/blueprints.rb
|
35
|
+
- lib/blueprints/buildable.rb
|
36
|
+
- lib/blueprints/database_backends/abstract.rb
|
37
|
+
- lib/blueprints/database_backends/active_record.rb
|
38
|
+
- lib/blueprints/database_backends/none.rb
|
39
|
+
- lib/blueprints/errors.rb
|
40
|
+
- lib/blueprints/extensions/rspec.rb
|
41
|
+
- lib/blueprints/extensions/test_unit.rb
|
35
42
|
- lib/blueprints/file_context.rb
|
36
|
-
- lib/blueprints/ar_extensions.rb
|
37
|
-
- lib/blueprints/test_unit_extensions.rb
|
38
43
|
- lib/blueprints/helper.rb
|
39
|
-
- lib/blueprints/
|
44
|
+
- lib/blueprints/namespace.rb
|
40
45
|
- lib/blueprints/plan.rb
|
41
|
-
- lib/blueprints/rspec_extensions.rb
|
42
46
|
- lib/blueprints/root_namespace.rb
|
43
|
-
-
|
44
|
-
-
|
45
|
-
-
|
46
|
-
-
|
47
|
+
- script/load_schema
|
48
|
+
- script/rspec_to_test
|
49
|
+
- spec/active_record/blueprint.rb
|
50
|
+
- spec/active_record/blueprints_spec.rb
|
51
|
+
- spec/active_record/fixtures/database.yml.example
|
52
|
+
- spec/active_record/fixtures/fruit.rb
|
53
|
+
- spec/active_record/fixtures/schema.rb
|
54
|
+
- spec/active_record/fixtures/tree.rb
|
55
|
+
- spec/active_record/spec_helper.rb
|
56
|
+
- spec/no_db/blueprint.rb
|
57
|
+
- spec/no_db/blueprints_spec.rb
|
58
|
+
- spec/no_db/fixtures/fruit.rb
|
59
|
+
- spec/no_db/spec_helper.rb
|
60
|
+
- test/blueprints_test.rb
|
61
|
+
- test/test_helper.rb
|
62
|
+
- uninstall.rb
|
47
63
|
has_rdoc: true
|
48
64
|
homepage: http://github.com/sinsiliux/blueprints
|
49
65
|
licenses: []
|
50
66
|
|
51
67
|
post_install_message:
|
52
|
-
rdoc_options:
|
53
|
-
|
68
|
+
rdoc_options:
|
69
|
+
- --charset=UTF-8
|
54
70
|
require_paths:
|
55
71
|
- lib
|
56
72
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -73,16 +89,15 @@ signing_key:
|
|
73
89
|
specification_version: 3
|
74
90
|
summary: Another replacement for factories and fixtures
|
75
91
|
test_files:
|
76
|
-
- spec/no_db/spec_helper.rb
|
77
|
-
- spec/no_db/blueprints_spec.rb
|
78
|
-
- spec/no_db/blueprint.rb
|
79
92
|
- spec/no_db/fixtures/fruit.rb
|
80
|
-
- spec/
|
81
|
-
- spec/
|
82
|
-
- spec/
|
83
|
-
- spec/active_record/fixtures/fruit.rb
|
93
|
+
- spec/no_db/blueprint.rb
|
94
|
+
- spec/no_db/blueprints_spec.rb
|
95
|
+
- spec/no_db/spec_helper.rb
|
84
96
|
- spec/active_record/fixtures/tree.rb
|
85
|
-
- spec/active_record/fixtures/
|
97
|
+
- spec/active_record/fixtures/fruit.rb
|
86
98
|
- spec/active_record/fixtures/schema.rb
|
99
|
+
- spec/active_record/blueprint.rb
|
100
|
+
- spec/active_record/blueprints_spec.rb
|
101
|
+
- spec/active_record/spec_helper.rb
|
87
102
|
- test/test_helper.rb
|
88
103
|
- test/blueprints_test.rb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'activerecord'
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
class Base
|
5
|
-
def self.blueprint(*args)
|
6
|
-
options = args.extract_options!
|
7
|
-
if args.present?
|
8
|
-
klass = self
|
9
|
-
Blueprints::Plan.new(*args) do
|
10
|
-
klass.blueprint options
|
11
|
-
end
|
12
|
-
else
|
13
|
-
returning(self.new) do |object|
|
14
|
-
options.each do |attr, value|
|
15
|
-
value = Blueprints::Namespace.root.context.instance_variable_get(value) if value.is_a? Symbol and value.to_s =~ /^@.+$/
|
16
|
-
object.send("#{attr}=", value)
|
17
|
-
end
|
18
|
-
object.save!
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|