josevalim-nested_scenarios 0.1.1 → 0.2

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 CHANGED
@@ -1,62 +1,81 @@
1
- NestedScenarios v0.1.1
2
- ======================
1
+ NestedScenarios
2
+ License: MIT
3
+ Version: 0.2
4
+
5
+ Description
6
+ -----------
3
7
 
4
8
  This plugin is based on FixtureScenarios and FixtureScenarioBuilder.
5
9
  It includes both worlds in just one plugin with some fixes, new features
6
- and Rails 2.2 support.
10
+ and Rails 2.2 support (check what's new session bellow).
7
11
 
8
12
  You can check them at:
9
13
 
10
- FixtureScenarios
11
- Info: http://code.google.com/p/fixture-scenarios/
12
- SVN : http://fixture-scenarios.googlecode.com/svn/trunk/fixture_scenarios
14
+ NestedScenarios
15
+ Info: http://josevalim.blogspot.com/
16
+ Git : http://github.com/josevalim/nested_scenarios
13
17
 
14
18
  FixtureScenariosBuilder
15
19
  Info: http://errtheblog.com/post/7708
16
20
  SVN : svn://errtheblog.com/svn/plugins/fixture_scenarios_builder
17
21
 
18
- NestedScenarios
19
- Info: http://josevalim.blogspot.com/
20
- Git : http://github.com/josevalim/nested_scenarios
21
-
22
- == Install
22
+ FixtureScenarios
23
+ Info: http://code.google.com/p/fixture-scenarios/
24
+ SVN : http://fixture-scenarios.googlecode.com/svn/trunk/fixture_scenarios
23
25
 
24
- Install NestedScenarios is very easy. It is stored in GitHub, so if you have
25
- never installed a gem via GitHub run the following:
26
26
 
27
- gem sources -a http://gems.github.com
27
+ Install
28
+ -------
28
29
 
29
- Then install the gem:
30
+ Install Nested Scenarios is very easy. If you are using Rails 2.3.0, just do:
30
31
 
31
- sudo gem install josevalim-nested_scenarios
32
+ gem sources -a http://gems.github.com
33
+ sudo gem install josevalim-nested_scenarios
32
34
 
33
- In RAILS_ROOT/config/environment.rb:
35
+ If you want it as plugin, just do:
34
36
 
35
- config.gem "josevalim-nested_scenarios", :lib => "nested_scenarios", :source => "http://gems.github.com"
37
+ script/plugin install git://github.com/josevalim/nested_scenarios.git
36
38
 
37
- If you want it as plugin, just do:
39
+ If you are running on Rails 2.2.x, you should use Nested Scenarios v0.1.1:
38
40
 
39
41
  cd myapp
40
42
  git clone git://github.com/josevalim/nested_scenarios.git
41
- rm -rf vendor/plugins/nested_scenarios/.git
43
+ cd vendor/plugins/nested_scenarios
44
+ git checkout v0.1.1
45
+ rm -rf ./.git
46
+
42
47
 
43
- == Why
48
+ Why?
49
+ ----
44
50
 
45
51
  You may, from time to time, wish to build your fixtures entirely in Ruby.
46
52
  Doing so has its advantages, such as automatically created join tables
47
- and default attributes. YAML files, however, bring with them some real
53
+ and default attributes. YAML files, however, bring with them some real
48
54
  nice features in Rails which are difficult to abandon: transactional fixtures,
49
- table_name(:key) helpers, and auto-clearing between tests. How does one get
50
- the best of both worlds?
55
+ table_name(:key) helpers and auto-clearing between tests. This plugin allow to
56
+ get the best of both worlds.
51
57
 
52
- == Usage
58
+
59
+ What's new?
60
+ -----------
61
+
62
+ FixtureScenario is totally rewritten: it's lighter, smaller and faster.
63
+
64
+ FixtureScenarioBuilder was changed to expose some methods as API and it does
65
+ not try to guess anymore when you should rebuild your scenarios. You have to
66
+ call it explicitly using rake db:scenario:build.
67
+
68
+ Finally Rails 2.2 support was also added.
69
+
70
+
71
+ Usage
72
+ -----
53
73
 
54
74
  Using the +scenario+ method within <tt>scenarios.rb</tt> file,
55
- FixtureScenariosBuilder can create your YAML fixture scenarios automatically
56
- at run time from Ruby-created fixtures.
75
+ NestedScenarios can create your YAML fixtures automatically at run time.
57
76
 
58
- Any file inside the +fixture_path+ called scenarios.rb is loaded to
59
- generating scenarios:
77
+ Any file inside the +fixture_path+ called scenario.rb or scenarios.rb
78
+ is loaded to generating scenarios:
60
79
 
61
80
  [RAILS_ROOT]
62
81
  +-test/
@@ -75,8 +94,9 @@ Or:
75
94
  +-helpers/
76
95
  +-scenarios.rb
77
96
 
78
- Now build your scenarios in those file, wrapping scenarios in the
79
- +scenario+ method and providing it with the name of your scenario.
97
+ Now build your scenarios in those files, wrapping scenarios in the
98
+ +scenario+ method and providing it with the name of your scenario.
99
+
80
100
  A brief example of a complete <tt>scenarios.rb</tt> file:
81
101
 
82
102
  scenario :banned_users do
@@ -85,7 +105,7 @@ A brief example of a complete <tt>scenarios.rb</tt> file:
85
105
  end
86
106
  end
87
107
 
88
- Assuming +banned+ is a boolean field, this will create for us:
108
+ This will create a file for us:
89
109
 
90
110
  [RAILS_ROOT]
91
111
  +-test/
@@ -93,7 +113,8 @@ Assuming +banned+ is a boolean field, this will create for us:
93
113
  +-banned_users/
94
114
  +-users.yml
95
115
 
96
- Our generated <tt>users.yml</tt> file will look something like this:
116
+ Assuming that banned is a boolean field, our generated <tt>users.yml</tt>
117
+ file will look something like this:
97
118
 
98
119
  chris:
99
120
  name: Chris
@@ -117,9 +138,9 @@ Our generated <tt>users.yml</tt> file will look something like this:
117
138
  Notice how the keys correspond to the user names. You can register fields that
118
139
  can be used as fixtures names by:
119
140
 
120
- NestedScenarios.record_name_fields << :nickname
141
+ NestedScenarios.record_name_fields += [ :nickname ]
121
142
 
122
- You can assign your records to instance variables, then call +names_from_ivars+
143
+ You can also assign your records to instance variables, then call +names_from_ivars!+
123
144
  at the conclusion of your +scenario+ block.
124
145
 
125
146
  scenario :foo do
@@ -144,10 +165,9 @@ The above produces the following YAML:
144
165
 
145
166
  To build the scenario you have to run:
146
167
 
147
- rake db:build:scenario
168
+ rake db:scenario:build
148
169
 
149
- In NestedScenarios, scenarios are not generated automatically. Another change
150
- is how scenarios are nested:
170
+ NestedScenarios also allows you to nest scenarios:
151
171
 
152
172
  scenario :models => { :users => :banned } do
153
173
  User.create(:name => 'Kevin', :banned => true)
@@ -171,4 +191,30 @@ Or, in the case of nested scenarios:
171
191
 
172
192
  scenario :models => { :users => :banned }
173
193
 
174
- If no scenario is sent, the default behaviour is adopted.
194
+ If no scenario is sent after all, the default behaviour is adopted.
195
+
196
+
197
+ Fixtures path
198
+ -------------
199
+
200
+ If you have fixtures in your fixtures path root and you want those fixtures
201
+ to also be loaded, you can configure:
202
+
203
+ NestedScenarios.load_root_fixtures = true
204
+
205
+ You can disable such behaviour in your tests also, by doing:
206
+
207
+ scenario :models => { :users => :banned }, :root => false
208
+
209
+ You just have to remember if you have a scenario with fixtures for a specified
210
+ table, it will overwrite the fixtures in your root path for the same table.
211
+
212
+ Bugs and Feedback
213
+ -----------------
214
+
215
+ If you discover any bugs, please send an e-mail to jose.valim@gmail.com
216
+ If you just want to give some positive feedback or drop a line, that's fine too! =)
217
+
218
+ Copyright (c) 2009 José Valim
219
+ http://www.pagestacker.com/
220
+ http://josevalim.blogspot.com/
data/Rakefile CHANGED
@@ -2,11 +2,11 @@ require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rake/rdoctask'
4
4
 
5
- desc 'Generate documentation for Footnotes plugin.'
5
+ desc 'Generate documentation for NestedScenarios plugin.'
6
6
  Rake::RDocTask.new(:rdoc) do |rdoc|
7
7
  rdoc.rdoc_dir = 'rdoc'
8
8
  rdoc.title = 'NestedScenarios'
9
9
  rdoc.options << '--line-numbers' << '--inline-source'
10
10
  rdoc.rdoc_files.include('README')
11
11
  rdoc.rdoc_files.include('lib/**/*.rb')
12
- end
12
+ end
@@ -4,8 +4,8 @@ if RAILS_ENV == 'test'
4
4
  require 'active_record/fixtures'
5
5
 
6
6
  dir = File.dirname(__FILE__)
7
+ require File.join(dir, 'nested_scenarios', 'nested_scenarios')
7
8
  require File.join(dir, 'nested_scenarios', 'builder')
8
9
  require File.join(dir, 'nested_scenarios', 'fixtures')
9
10
  require File.join(dir, 'nested_scenarios', 'join')
10
- require File.join(dir, 'nested_scenarios', 'nested_scenarios')
11
11
  end
@@ -4,29 +4,62 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash)
4
4
  end
5
5
  end
6
6
 
7
- module Test #:nodoc:
8
- module Unit #:nodoc:
9
- class TestCase #:nodoc:
10
- superclass_delegating_accessor :scenario_path
7
+ module ActiveRecord #:nodoc:
8
+ module TestFixtures #:nodoc:
9
+
10
+ def self.included(base)
11
+ base.class_eval do
12
+ setup :setup_fixtures
13
+ teardown :teardown_fixtures
11
14
 
12
- def self.scenario(scenario_name = nil, options = {})
15
+ superclass_delegating_accessor :fixture_path
16
+ superclass_delegating_accessor :fixture_table_names
17
+ superclass_delegating_accessor :fixture_class_names
18
+ superclass_delegating_accessor :use_transactional_fixtures
19
+ superclass_delegating_accessor :use_instantiated_fixtures # true, false, or :no_instances
20
+ superclass_delegating_accessor :pre_loaded_fixtures
21
+
22
+ self.fixture_table_names = []
23
+ self.use_transactional_fixtures = false
24
+ self.use_instantiated_fixtures = true
25
+ self.pre_loaded_fixtures = false
26
+
27
+ self.fixture_class_names = {}
28
+
29
+ superclass_delegating_accessor :scenario_path
30
+ superclass_delegating_accessor :load_root_fixtures
31
+ superclass_delegating_accessor :root_table_names
32
+ superclass_delegating_accessor :scenario_table_names
33
+ self.load_root_fixtures = false
34
+ end
35
+
36
+ base.extend ClassMethods
37
+ end
38
+
39
+ module ClassMethods
40
+ def scenario(scenario_name = nil, options = {})
13
41
  case scenario_name
14
42
  when Hash
43
+ self.load_root_fixtures = scenario_name.delete(:root) unless scenario_name[:root].nil?
15
44
  scenario_name = scenario_name.join('/')
16
45
  when Symbol, String
46
+ self.load_root_fixtures = options.delete(:root) unless options[:root].nil?
17
47
  scenario_name = scenario_name.to_s
48
+ else
49
+ raise ArgumentError, "Scenario must be a symbol, string or hash. You gave #{scenario_name.class}."
18
50
  end
19
51
 
20
- self.scenario_path = "#{self.fixture_path}/#{scenario_name}/" if scenario_name
21
-
52
+ self.scenario_path = "#{self.fixture_path}/#{scenario_name}" if scenario_name
22
53
  self.fixtures(:all)
23
54
  end
24
55
 
25
- def self.fixtures(*table_names)
56
+ def fixtures(*table_names)
26
57
  if table_names.first == :all
27
- table_names = Dir["#{self.scenario_path || self.fixture_path}/*.yml"]
28
- table_names += Dir["#{self.scenario_path || self.fixture_path}/*.csv"]
29
- table_names.map! { |f| File.basename(f).split('.')[0..-2].join('.') }
58
+ self.root_table_names = self.load_root_fixtures ? load_table_names_in_path(self.fixture_path) : []
59
+ self.scenario_table_names = self.scenario_path ? load_table_names_in_path(self.scenario_path) : []
60
+
61
+ table_names = self.root_table_names + self.scenario_table_names
62
+ table_names.uniq!
30
63
  else
31
64
  table_names = table_names.flatten.map { |n| n.to_s }
32
65
  end
@@ -38,35 +71,53 @@ module Test #:nodoc:
38
71
  end
39
72
 
40
73
  private
41
- def load_fixtures
42
- @loaded_fixtures = {}
43
- fixtures = Fixtures.create_fixtures(self.scenario_path || self.fixture_path, fixture_table_names, fixture_class_names)
44
- unless fixtures.nil?
45
- if fixtures.instance_of?(Fixtures)
46
- @loaded_fixtures[fixtures.table_name] = fixtures
47
- else
48
- fixtures.each { |f| @loaded_fixtures[f.table_name] = f }
49
- end
50
- end
74
+ def load_table_names_in_path(path)
75
+ table_names = Dir["#{path}/*.yml"] + Dir["#{path}/*.csv"]
76
+ table_names.map! { |f| File.basename(f).split('.')[0..-2].join('.') }
77
+ return table_names
78
+ end
79
+ end
80
+
81
+ private
82
+ def load_fixtures
83
+ @loaded_fixtures = {}
84
+
85
+ if self.load_root_fixtures
86
+ root_fixtures = Fixtures.create_fixtures(self.fixture_path, self.root_table_names, fixture_class_names)
51
87
  end
52
88
 
53
- def teardown_fixtures
54
- return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
89
+ if self.scenario_path
90
+ scenario_fixtures = Fixtures.create_fixtures(self.scenario_path, self.scenario_table_names, fixture_class_names)
91
+ end
55
92
 
56
- Fixtures.destroy_fixtures(self.fixture_table_names)
93
+ [root_fixtures, scenario_fixtures].each do |fixtures|
94
+ next if fixtures.nil?
57
95
 
58
- unless use_transactional_fixtures?
59
- Fixtures.reset_cache
96
+ if fixtures.instance_of?(Fixtures)
97
+ @loaded_fixtures[fixtures.table_name] = fixtures
98
+ else
99
+ fixtures.each { |f| @loaded_fixtures[f.table_name] = f }
60
100
  end
101
+ end
102
+ end
61
103
 
62
- # Rollback changes if a transaction is active.
63
- if use_transactional_fixtures? && ActiveRecord::Base.connection.open_transactions != 0
64
- ActiveRecord::Base.connection.rollback_db_transaction
65
- ActiveRecord::Base.connection.decrement_open_transactions
66
- end
104
+ def teardown_fixtures
105
+ return unless defined?(ActiveRecord) && !ActiveRecord::Base.configurations.blank?
106
+
107
+ Fixtures.destroy_fixtures(self.fixture_table_names)
67
108
 
68
- ActiveRecord::Base.clear_active_connections!
109
+ unless use_transactional_fixtures?
110
+ Fixtures.reset_cache
69
111
  end
70
- end
112
+
113
+ # Rollback changes if a transaction is active.
114
+ if use_transactional_fixtures? && ActiveRecord::Base.connection.open_transactions != 0
115
+ ActiveRecord::Base.connection.rollback_db_transaction
116
+ ActiveRecord::Base.connection.decrement_open_transactions
117
+ end
118
+
119
+ ActiveRecord::Base.clear_active_connections!
120
+ end
121
+
71
122
  end
72
123
  end
@@ -17,4 +17,12 @@ class NestedScenarios
17
17
  def self.tables
18
18
  ActiveRecord::Base.connection.tables - @@skip_tables
19
19
  end
20
- end
20
+
21
+ def self.load_root_fixtures=(value)
22
+ Test::Unit::TestCase.load_root_fixtures = value
23
+ end
24
+
25
+ def self.load_root_fixtures
26
+ Test::Unit::TestCase.load_root_fixtures
27
+ end
28
+ end
@@ -10,7 +10,11 @@ namespace :db do
10
10
  # while building scenarios
11
11
  ActionMailer::Base.delivery_method = :test
12
12
 
13
- Dir.glob(NestedScenarios::Builder.fixtures_dir + '/**/scenarios.rb').each do |scenario_rb|
13
+ files = []
14
+ files += Dir.glob(NestedScenarios::Builder.fixtures_dir + '/**/scenario.rb')
15
+ files += Dir.glob(NestedScenarios::Builder.fixtures_dir + '/**/scenarios.rb')
16
+
17
+ files.each do |scenario_rb|
14
18
  puts "Reading #{scenario_rb.gsub(RAILS_ROOT, '')} scenario file:"
15
19
  require scenario_rb
16
20
  puts
metadata CHANGED
@@ -1,10 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: josevalim-nested_scenarios
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: "0.2"
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Jos\xC3\xA9 Valim"
8
+ - Tom Preston-Werner
9
+ - Chris Wanstrath
8
10
  autorequire:
9
11
  bindir: bin
10
12
  cert_chain: []