activerecord 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (68) hide show
  1. data/CHANGELOG +250 -0
  2. data/README +17 -9
  3. data/dev-utils/eval_debugger.rb +1 -1
  4. data/install.rb +3 -1
  5. data/lib/active_record.rb +9 -2
  6. data/lib/active_record/acts/list.rb +178 -0
  7. data/lib/active_record/acts/tree.rb +44 -0
  8. data/lib/active_record/associations.rb +45 -8
  9. data/lib/active_record/associations/association_collection.rb +18 -9
  10. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +14 -13
  11. data/lib/active_record/associations/has_many_association.rb +21 -12
  12. data/lib/active_record/base.rb +137 -37
  13. data/lib/active_record/callbacks.rb +30 -25
  14. data/lib/active_record/connection_adapters/abstract_adapter.rb +57 -33
  15. data/lib/active_record/connection_adapters/mysql_adapter.rb +4 -0
  16. data/lib/active_record/connection_adapters/sqlite_adapter.rb +3 -2
  17. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +298 -0
  18. data/lib/active_record/fixtures.rb +241 -147
  19. data/lib/active_record/support/class_inheritable_attributes.rb +5 -2
  20. data/lib/active_record/support/inflector.rb +13 -12
  21. data/lib/active_record/support/misc.rb +6 -0
  22. data/lib/active_record/timestamp.rb +33 -0
  23. data/lib/active_record/transactions.rb +1 -1
  24. data/lib/active_record/validations.rb +294 -16
  25. data/rakefile +3 -7
  26. data/test/abstract_unit.rb +1 -4
  27. data/test/associations_test.rb +17 -4
  28. data/test/base_test.rb +37 -5
  29. data/test/connections/native_sqlserver/connection.rb +15 -0
  30. data/test/deprecated_associations_test.rb +40 -38
  31. data/test/finder_test.rb +82 -4
  32. data/test/fixtures/accounts.yml +8 -0
  33. data/test/fixtures/company.rb +6 -0
  34. data/test/fixtures/company_in_module.rb +1 -1
  35. data/test/fixtures/db_definitions/mysql.sql +13 -0
  36. data/test/fixtures/db_definitions/postgresql.sql +13 -0
  37. data/test/fixtures/db_definitions/sqlite.sql +14 -0
  38. data/test/fixtures/db_definitions/sqlserver.sql +110 -0
  39. data/test/fixtures/db_definitions/sqlserver2.sql +4 -0
  40. data/test/fixtures/developer.rb +2 -2
  41. data/test/fixtures/developers.yml +13 -0
  42. data/test/fixtures/fixture_database.sqlite +0 -0
  43. data/test/fixtures/fixture_database_2.sqlite +0 -0
  44. data/test/fixtures/mixin.rb +17 -0
  45. data/test/fixtures/mixins.yml +14 -0
  46. data/test/fixtures/naked/csv/accounts.csv +1 -0
  47. data/test/fixtures/naked/yml/accounts.yml +1 -0
  48. data/test/fixtures/naked/yml/companies.yml +1 -0
  49. data/test/fixtures/naked/yml/courses.yml +1 -0
  50. data/test/fixtures/project.rb +6 -0
  51. data/test/fixtures/reply.rb +14 -1
  52. data/test/fixtures/topic.rb +2 -2
  53. data/test/fixtures/topics/first +1 -0
  54. data/test/fixtures_test.rb +42 -12
  55. data/test/inflector_test.rb +2 -1
  56. data/test/inheritance_test.rb +22 -12
  57. data/test/mixin_test.rb +138 -0
  58. data/test/pk_test.rb +4 -2
  59. data/test/reflection_test.rb +3 -3
  60. data/test/transactions_test.rb +15 -0
  61. data/test/validations_test.rb +229 -4
  62. metadata +24 -10
  63. data/lib/active_record/associations.rb.orig +0 -555
  64. data/test/deprecated_associations_test.rb.orig +0 -334
  65. data/test/fixtures/accounts/signals37 +0 -3
  66. data/test/fixtures/accounts/unknown +0 -2
  67. data/test/fixtures/developers/david +0 -2
  68. data/test/fixtures/developers/jamis +0 -2
@@ -1,147 +1,258 @@
1
+ require 'erb'
1
2
  require 'yaml'
3
+ require 'csv'
2
4
  require 'active_record/support/class_inheritable_attributes'
3
5
  require 'active_record/support/inflector'
4
6
 
5
- # Fixtures are a way of organizing data that you want to test against. Each fixture file is created as a row
6
- # in the database and created as a hash with column names as keys and data as values. All of these fixture hashes
7
- # are kept in an overall hash where they can be accessed by their file name.
7
+ # Fixtures are a way of organizing data that you want to test against; in short, sample data. They come in 3 flavours:
8
8
  #
9
- # Example:
9
+ # 1. YAML fixtures
10
+ # 2. CSV fixtures
11
+ # 3. Single-file fixtures
10
12
  #
11
- # Directory with the fixture files
13
+ # = YAML fixtures
12
14
  #
13
- # developers/
14
- # david
15
- # luke
16
- # jamis
15
+ # This type of fixture is in YAML format and the preferred default. YAML is a file format which describes data structures
16
+ # in a non-verbose, humanly-readable format. It ships with Ruby 1.8.1+.
17
17
  #
18
- # The file +david+ then contains:
18
+ # Unlike single-file fixtures, YAML fixtures are stored in a single file per model, which is place in the directory appointed
19
+ # by <tt>Test::Unit::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
20
+ # put your files in <your-rails-app>/test/fixtures/). The fixture file ends with the .yml file extension (Rails example:
21
+ # "<your-rails-app>/test/fixtures/web_sites.yml"). The format of a YAML fixture file looks like this:
22
+ #
23
+ # rubyonrails:
24
+ # id: 1
25
+ # name: Ruby on Rails
26
+ # url: http://www.rubyonrails.org
27
+ #
28
+ # google:
29
+ # id: 2
30
+ # name: Google
31
+ # url: http://www.google.com
32
+ #
33
+ # This YAML fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and is followed by an
34
+ # indented list of key/value pairs in the "key: value" format. Records are separated by a blank line for your viewing
35
+ # pleasure.
36
+ #
37
+ # = CSV fixtures
38
+ #
39
+ # Fixtures can also be kept in the Comma Separated Value format. Akin to YAML fixtures, CSV fixtures are stored
40
+ # in a single file, but, instead end with the .csv file extension (Rails example: "<your-rails-app>/test/fixtures/web_sites.csv")
41
+ #
42
+ # The format of this tye of fixture file is much more compact than the others, but also a little harder to read by us
43
+ # humans. The first line of the CSV file is a comma-separated list of field names. The rest of the file is then comprised
44
+ # of the actual data (1 per line). Here's an example:
45
+ #
46
+ # id, name, url
47
+ # 1, Ruby On Rails, http://www.rubyonrails.org
48
+ # 2, Google, http://www.google.com
49
+ #
50
+ # Should you have a piece of data with a comma character in it, you can place double quotes around that value. If you
51
+ # need to use a double quote character, you must escape it with another double quote.
52
+ #
53
+ # Another unique attribute of the CSV fixture is that it has *no* fixture name like the other two formats. Instead, the
54
+ # fixture names are automatically generated by deriving the class name of the fixture file and adding an incrementing
55
+ # number to the end. In our example, the 1st fixture would be called "web_site_1" and the 2nd one would be called
56
+ # "web_site_2".
57
+ #
58
+ # Most databases and spreadsheets support exporting to CSV format, so this is a great format for you to choose if you
59
+ # have existing data somewhere already.
60
+ #
61
+ # = Single-file fixtures
62
+ #
63
+ # This type of fixtures was the original format for Active Record that has since been deprecated in favor of the YAML and CSV formats.
64
+ # Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory
65
+ # appointed by <tt>Test::Unit::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
66
+ # put your files in <your-rails-app>/test/fixtures/<your-model-name>/ -- like <your-rails-app>/test/fixtures/web_sites/ for the WebSite
67
+ # model).
68
+ #
69
+ # Each text file placed in this directory represents a "record". Usually these types of fixtures are named without
70
+ # extensions, but if you are on a Windows machine, you might consider adding .txt as the extension. Here's what the
71
+ # above example might look like:
72
+ #
73
+ # web_sites/google
74
+ # web_sites/yahoo.txt
75
+ # web_sites/ruby-on-rails
76
+ #
77
+ # The file format of a standard fixture is simple. Each line is a property (or column in db speak) and has the syntax
78
+ # of "name => value". Here's an example of the ruby-on-rails fixture above:
19
79
  #
20
80
  # id => 1
21
- # name => David Heinemeier Hansson
22
- # birthday => 1979-10-15
23
- # profession => Systems development
81
+ # name => Ruby on Rails
82
+ # url => http://www.rubyonrails.org
24
83
  #
25
- # Now when we call <tt>@developers = Fixtures.new(ActiveRecord::Base.connection, "developers", "developers/")</tt> all three
26
- # developers will get inserted into the "developers" table through the active Active Record connection (that must be setup
27
- # before-hand). And we can now query the fixture data through the <tt>@developers</tt> hash, so <tt>@developers["david"]["name"]</tt>
28
- # will return <tt>"David Heinemeier Hansson"</tt> and <tt>@developers["david"]["birthday"]</tt> will return <tt>Date.new(1979, 10, 15)</tt>.
84
+ # = Using Fixtures
29
85
  #
30
- # This can then be used for comparison in a unit test. Something like:
86
+ # Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the
87
+ # fixtures, but first lets take a look at a sample unit test found:
31
88
  #
32
- # def test_find
33
- # assert_equal @developers["david"]["name"], Developer.find(@developers["david"]["id"]).name
89
+ # require 'web_site'
90
+ #
91
+ # class WebSiteTest < Test::Unit::TestCase
92
+ # def test_web_site_count
93
+ # assert_equal 2, WebSite.count
94
+ # end
34
95
  # end
35
96
  #
36
- # == Automatic fixture setup and instance variable availability
97
+ # As it stands, unless we pre-load the web_site table in our database with two records, this test will fail. Here's the
98
+ # easiest way to add fixtures to the database:
37
99
  #
38
- # Fixtures can also be automatically instantiated in instance variables relating to their names using the following style:
100
+ # ...
101
+ # class WebSiteTest < Test::Unit::TestCase
102
+ # fixtures :web_sites # add more by separating the symbols with commas
103
+ # ...
39
104
  #
40
- # class FixturesTest < Test::Unit::TestCase
41
- # fixtures :developers # you can add more with comma separation
105
+ # By adding a "fixtures" method to the test case and passing it a list of symbols (only one is shown here tho), we trigger
106
+ # the testing environment to automatically load the appropriate fixtures into the database before each test, and
107
+ # automatically delete them after each test.
42
108
  #
43
- # def test_developers
44
- # assert_equal 3, @developers.size # the container for all the fixtures is automatically set
45
- # assert_kind_of Developer, @david # works like @developers["david"].find
46
- # assert_equal "David Heinemeier Hansson", @david.name
47
- # end
109
+ # In addition to being available in the database, the fixtures are also loaded into a hash stored in an instance variable
110
+ # of the test case. It is named after the symbol... so, in our example, there would be a hash available called
111
+ # @web_sites. This is where the "fixture name" comes into play.
112
+ #
113
+ # On top of that, each record is automatically "found" (using Model.find(id)) and placed in the instance variable of its name.
114
+ # So for the YAML fixtures, we'd get @rubyonrails and @google, which could be interrogated using regular Active Record semantics:
115
+ #
116
+ # # test if the object created from the fixture data has the same attributes as the data itself
117
+ # def test_find
118
+ # assert_equal @web_sites["rubyonrails"]["name"], @rubyonrails.name
48
119
  # end
49
120
  #
50
- # == YAML fixtures
51
- #
52
- # Additionally, fixtures supports yaml files. Like fixture files, these yaml files have a pre-defined format. The document
53
- # must be formatted like this:
54
- #
55
- # name: david
56
- # data:
57
- # id: 1
58
- # name: David Heinemeier Hansson
59
- # birthday: 1979-10-15
60
- # profession: Systems development
61
- # ---
62
- # name: steve
63
- # data:
64
- # id: 2
65
- # name: Steve Ross Kellock
66
- # birthday: 1974-09-27
67
- # profession: guy with keyboard
68
- #
69
- # In that file, there's two records. Each record must have two parts: 'name' and 'data'. The data that you add
70
- # must be indented like you see above.
71
- #
72
- # Yaml fixtures file names must end with .yml as in people.yml or camel.yml. The yaml fixtures are placed in the same
73
- # directory as the normal fixtures and can happy co-exist. :)
121
+ # As seen above, the data hash created from the YAML fixtures would have @web_sites["rubyonrails"]["url"] return
122
+ # "http://www.rubyonrails.org" and @web_sites["google"]["name"] would return "Google". The same fixtures, but loaded
123
+ # from a CSV fixture file would be accessible via @web_sites["web_site_1"]["name"] == "Ruby on Rails" and have the individual
124
+ # fixtures available as instance variables @web_site_1 and @web_site_2.
125
+ #
126
+ # = Dynamic fixtures with ERb
127
+ #
128
+ # Some times you don't care about the content of the fixtures as much as you care about the volume. In these cases, you can
129
+ # mix ERb in with your YAML or CSV fixtures to create a bunch of fixtures for load testing, like:
130
+ #
131
+ # <% for i in 1..1000 %>
132
+ # fix_<%= i %>:
133
+ # id: <%= i %>
134
+ # name: guy_<%= 1 %>
135
+ # <% end %>
136
+ #
137
+ # This will create 1000 very simple YAML fixtures.
138
+ #
139
+ # Using ERb, you can also inject dynamic values into your fixtures with inserts like <%= Date.today.strftime("%Y-%m-%d") %>.
140
+ # This is however a feature to be used with some caution. The point of fixtures are that they're stable units of predictable
141
+ # sample data. If you feel that you need to inject dynamic values, then perhaps you should reexamine whether your application
142
+ # is properly testable. Hence, dynamic values in fixtures are to be considered a code smell.
74
143
  class Fixtures < Hash
144
+ DEFAULT_FILTER_RE = /\.ya?ml$/
145
+
75
146
  def self.instantiate_fixtures(object, fixtures_directory, *table_names)
76
147
  [ create_fixtures(fixtures_directory, *table_names) ].flatten.each_with_index do |fixtures, idx|
77
148
  object.instance_variable_set "@#{table_names[idx]}", fixtures
78
149
  fixtures.each { |name, fixture| object.instance_variable_set "@#{name}", fixture.find }
79
150
  end
80
151
  end
81
-
152
+
82
153
  def self.create_fixtures(fixtures_directory, *table_names)
83
154
  connection = block_given? ? yield : ActiveRecord::Base.connection
84
155
  old_logger_level = ActiveRecord::Base.logger.level
85
156
 
86
157
  begin
87
158
  ActiveRecord::Base.logger.level = Logger::ERROR
88
- fixtures = connection.transaction do
89
- table_names.flatten.map do |table_name|
90
- Fixtures.new(connection, table_name.to_s, File.join(fixtures_directory, table_name.to_s))
91
- end
159
+
160
+ fixtures = table_names.flatten.map do |table_name|
161
+ Fixtures.new(connection, table_name.to_s, File.join(fixtures_directory, table_name.to_s))
162
+ end
163
+
164
+ connection.transaction do
165
+ fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures }
166
+ fixtures.each { |fixture| fixture.insert_fixtures }
92
167
  end
168
+
93
169
  return fixtures.size > 1 ? fixtures : fixtures.first
94
170
  ensure
95
171
  ActiveRecord::Base.logger.level = old_logger_level
96
172
  end
97
173
  end
98
174
 
99
- def initialize(connection, table_name, fixture_path, file_filter = /^\.|CVS|\.yaml/)
175
+ def initialize(connection, table_name, fixture_path, file_filter = DEFAULT_FILTER_RE)
100
176
  @connection, @table_name, @fixture_path, @file_filter = connection, table_name, fixture_path, file_filter
101
177
  @class_name = Inflector.classify(@table_name)
102
178
 
103
179
  read_fixture_files
104
- delete_existing_fixtures
105
- insert_fixtures
180
+ end
181
+
182
+ def delete_existing_fixtures
183
+ @connection.delete "DELETE FROM #{@table_name}", 'Fixture Delete'
184
+ end
185
+
186
+ def insert_fixtures
187
+ values.each do |fixture|
188
+ @connection.execute "INSERT INTO #{@table_name} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
189
+ end
106
190
  end
107
191
 
108
192
  private
109
193
  def read_fixture_files
110
- Dir.entries(@fixture_path).each do |file|
111
- case file
112
- when /\.ya?ml$/
113
- path = File.join(@fixture_path, file)
114
- YamlFixture.produce(path).each { |fixture|
115
- self[fixture.yaml_name] = fixture
116
- }
117
- when @file_filter
118
- # skip
119
- else
120
- self[file] = Fixture.new(@fixture_path, file, @class_name)
194
+ if File.file?(yaml_file_path)
195
+ # YAML fixtures
196
+ begin
197
+ yaml = YAML::load(erb_render(IO.read(yaml_file_path)))
198
+ yaml.each { |name, data| self[name] = Fixture.new(data, @class_name) } if yaml
199
+ rescue Exception=>boom
200
+ raise Fixture::FormatError, "a YAML error occured parsing #{yaml_file_path}"
201
+ end
202
+ elsif File.file?(csv_file_path)
203
+ # CSV fixtures
204
+ reader = CSV::Reader.create(erb_render(IO.read(csv_file_path)))
205
+ header = reader.shift
206
+ i = 0
207
+ reader.each do |row|
208
+ data = {}
209
+ row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.to_s.strip }
210
+ self["#{Inflector::underscore(@class_name)}_#{i+=1}"]= Fixture.new(data, @class_name)
211
+ end
212
+ elsif File.file?(deprecated_yaml_file_path)
213
+ raise Fixture::FormatError, ".yml extension required: rename #{deprecated_yaml_file_path} to #{yaml_file_path}"
214
+ else
215
+ # Standard fixtures
216
+ Dir.entries(@fixture_path).each do |file|
217
+ path = File.join(@fixture_path, file)
218
+ if File.file?(path) and file !~ @file_filter
219
+ self[file] = Fixture.new(path, @class_name)
220
+ end
121
221
  end
122
222
  end
123
223
  end
124
224
 
125
- def delete_existing_fixtures
126
- @connection.delete "DELETE FROM #{@table_name}"
225
+ def yaml_file_path
226
+ "#{@fixture_path}.yml"
127
227
  end
128
228
 
129
- def insert_fixtures
130
- values.each do |fixture|
131
- @connection.execute "INSERT INTO #{@table_name} (#{fixture.key_list}) VALUES(#{fixture.value_list})"
132
- end
229
+ def deprecated_yaml_file_path
230
+ "#{@fixture_path}.yaml"
231
+ end
232
+
233
+ def csv_file_path
234
+ @fixture_path + ".csv"
235
+ end
236
+
237
+ def yaml_fixtures_key(path)
238
+ File.basename(@fixture_path).split(".").first
239
+ end
240
+
241
+ def erb_render(fixture_content)
242
+ ERB.new(fixture_content).result
133
243
  end
134
244
  end
135
245
 
136
246
  class Fixture #:nodoc:
137
247
  include Enumerable
138
- class FixtureError < StandardError; end
139
- class FormatError < FixtureError; end
248
+ class FixtureError < StandardError#:nodoc:
249
+ end
250
+ class FormatError < FixtureError#:nodoc:
251
+ end
140
252
 
141
- def initialize(fixture_path, file, class_name)
142
- @fixture_path, @file, @class_name = fixture_path, file, class_name
143
- @fixture = read_fixture_file
144
- @class_name
253
+ def initialize(fixture, class_name)
254
+ @fixture = fixture.is_a?(Hash) ? fixture : read_fixture_file(fixture)
255
+ @class_name = class_name
145
256
  end
146
257
 
147
258
  def each
@@ -163,93 +274,76 @@ class Fixture #:nodoc:
163
274
  def value_list
164
275
  @fixture.values.map { |v| ActiveRecord::Base.connection.quote(v).gsub('\\n', "\n").gsub('\\r', "\r") }.join(", ")
165
276
  end
166
-
277
+
167
278
  def find
168
- Object.const_get(@class_name).find(self["id"])
279
+ Object.const_get(@class_name).find(self[Object.const_get(@class_name).primary_key])
169
280
  end
170
-
281
+
171
282
  private
172
- def read_fixture_file
173
- path = File.join(@fixture_path, @file)
174
- IO.readlines(path).inject({}) do |fixture, line|
283
+ def read_fixture_file(fixture_file_path)
284
+ IO.readlines(fixture_file_path).inject({}) do |fixture, line|
175
285
  # Mercifully skip empty lines.
176
- next if line.empty?
286
+ next if line =~ /^\s*$/
177
287
 
178
288
  # Use the same regular expression for attributes as Active Record.
179
289
  unless md = /^\s*([a-zA-Z][-_\w]*)\s*=>\s*(.+)\s*$/.match(line)
180
- raise FormatError, "#{path}: fixture format error at '#{line}'. Expecting 'key => value'."
290
+ raise FormatError, "#{fixture_file_path}: fixture format error at '#{line}'. Expecting 'key => value'."
181
291
  end
182
292
  key, value = md.captures
183
293
 
184
294
  # Disallow duplicate keys to catch typos.
185
- raise FormatError, "#{path}: duplicate '#{key}' in fixture." if fixture[key]
295
+ raise FormatError, "#{fixture_file_path}: duplicate '#{key}' in fixture." if fixture[key]
186
296
  fixture[key] = value.strip
187
297
  fixture
188
298
  end
189
299
  end
190
300
  end
191
301
 
192
- # A YamlFixture is like a fixture, but instead of a name to use as
193
- # a key, it uses a yaml_name.
194
- class YamlFixture < Fixture #:nodoc:
195
- class YamlFormatError < FormatError; end
302
+ module Test#:nodoc:
303
+ module Unit#:nodoc:
304
+ class TestCase #:nodoc:
305
+ include ClassInheritableAttributes
196
306
 
197
- # yaml_name is analogous to a normal fixture's filename
198
- attr_reader :yaml_name
199
-
200
- # Instantiate with fixture name and data.
201
- def initialize(yaml_name, fixture)
202
- @yaml_name, @fixture = yaml_name, fixture
203
- end
204
-
205
- def produce(yaml_file_name)
206
- YamlFixture.produce(yaml_file_name)
207
- end
307
+ cattr_accessor :fixture_path
308
+ cattr_accessor :fixture_table_names
208
309
 
209
- # Extract an array of YamlFixtures from a yaml file.
210
- def self.produce(yaml_file_name)
211
- fixtures = []
212
- File.open(yaml_file_name) do |yaml_file|
213
- YAML::load_documents(yaml_file) do |doc|
214
- missing = %w(name data).reject { |key| doc[key] }.join(' and ')
215
- raise YamlFormatError, "#{path}: yaml fixture missing #{missing}: #{doc.to_yaml}" unless missing.empty?
216
- fixtures << YamlFixture.new(doc['name'], doc['data'])
310
+ def self.fixtures(*table_names)
311
+ require_fixture_classes(table_names)
312
+ write_inheritable_attribute("fixture_table_names", table_names)
217
313
  end
218
- end
219
- fixtures
220
- end
221
- end
222
314
 
223
- class Test::Unit::TestCase #:nodoc:
224
- include ClassInheritableAttributes
225
-
226
- cattr_accessor :fixture_path
227
- cattr_accessor :fixture_table_names
228
-
229
- def self.fixtures(*table_names)
230
- write_inheritable_attribute("fixture_table_names", table_names)
231
- end
315
+ def self.require_fixture_classes(table_names)
316
+ table_names.each do |table_name|
317
+ begin
318
+ require(Inflector.singularize(table_name.to_s))
319
+ rescue LoadError
320
+ # Let's hope the developer is included it himself
321
+ end
322
+ end
323
+ end
232
324
 
233
- def setup
234
- instantiate_fixtures(*fixture_table_names) if fixture_table_names
235
- end
236
-
237
- def self.method_added(method_symbol)
238
- if method_symbol == :setup && !method_defined?(:setup_without_fixtures)
239
- alias_method :setup_without_fixtures, :setup
240
- define_method(:setup) do
325
+ def setup
241
326
  instantiate_fixtures(*fixture_table_names) if fixture_table_names
242
- setup_without_fixtures
243
327
  end
244
- end
245
- end
246
328
 
247
- private
248
- def instantiate_fixtures(*table_names)
249
- Fixtures.instantiate_fixtures(self, fixture_path, *table_names)
250
- end
251
-
252
- def fixture_table_names
253
- self.class.read_inheritable_attribute("fixture_table_names")
329
+ def self.method_added(method_symbol)
330
+ if method_symbol == :setup && !method_defined?(:setup_without_fixtures)
331
+ alias_method :setup_without_fixtures, :setup
332
+ define_method(:setup) do
333
+ instantiate_fixtures(*fixture_table_names) if fixture_table_names
334
+ setup_without_fixtures
335
+ end
336
+ end
337
+ end
338
+
339
+ private
340
+ def instantiate_fixtures(*table_names)
341
+ Fixtures.instantiate_fixtures(self, fixture_path, *table_names)
342
+ end
343
+
344
+ def fixture_table_names
345
+ self.class.read_inheritable_attribute("fixture_table_names")
346
+ end
254
347
  end
348
+ end
255
349
  end