PageRenderTime 40ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/rails/activerecord/lib/active_record/fixtures.rb

http://github.com/benburkert/cruisecontrolrb
Ruby | 628 lines | 345 code | 66 blank | 217 comment | 36 complexity | 644900793457346fa3893538c45d942a MD5 | raw file
Possible License(s): Apache-2.0
  1. require 'erb'
  2. require 'yaml'
  3. require 'csv'
  4. module YAML #:nodoc:
  5. class Omap #:nodoc:
  6. def keys; map { |k, v| k } end
  7. def values; map { |k, v| v } end
  8. end
  9. end
  10. class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
  11. end
  12. # Fixtures are a way of organizing data that you want to test against; in short, sample data. They come in 3 flavours:
  13. #
  14. # 1. YAML fixtures
  15. # 2. CSV fixtures
  16. # 3. Single-file fixtures
  17. #
  18. # = YAML fixtures
  19. #
  20. # This type of fixture is in YAML format and the preferred default. YAML is a file format which describes data structures
  21. # in a non-verbose, humanly-readable format. It ships with Ruby 1.8.1+.
  22. #
  23. # Unlike single-file fixtures, YAML fixtures are stored in a single file per model, which are placed in the directory appointed
  24. # by <tt>Test::Unit::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
  25. # put your files in <your-rails-app>/test/fixtures/). The fixture file ends with the .yml file extension (Rails example:
  26. # "<your-rails-app>/test/fixtures/web_sites.yml"). The format of a YAML fixture file looks like this:
  27. #
  28. # rubyonrails:
  29. # id: 1
  30. # name: Ruby on Rails
  31. # url: http://www.rubyonrails.org
  32. #
  33. # google:
  34. # id: 2
  35. # name: Google
  36. # url: http://www.google.com
  37. #
  38. # This YAML fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and is followed by an
  39. # indented list of key/value pairs in the "key: value" format. Records are separated by a blank line for your viewing
  40. # pleasure.
  41. #
  42. # Note that YAML fixtures are unordered. If you want ordered fixtures, use the omap YAML type. See http://yaml.org/type/omap.html
  43. # for the specification. You will need ordered fixtures when you have foreign key constraints on keys in the same table.
  44. # This is commonly needed for tree structures. Example:
  45. #
  46. # --- !omap
  47. # - parent:
  48. # id: 1
  49. # parent_id: NULL
  50. # title: Parent
  51. # - child:
  52. # id: 2
  53. # parent_id: 1
  54. # title: Child
  55. #
  56. # = CSV fixtures
  57. #
  58. # Fixtures can also be kept in the Comma Separated Value format. Akin to YAML fixtures, CSV fixtures are stored
  59. # in a single file, but instead end with the .csv file extension (Rails example: "<your-rails-app>/test/fixtures/web_sites.csv")
  60. #
  61. # The format of this type of fixture file is much more compact than the others, but also a little harder to read by us
  62. # humans. The first line of the CSV file is a comma-separated list of field names. The rest of the file is then comprised
  63. # of the actual data (1 per line). Here's an example:
  64. #
  65. # id, name, url
  66. # 1, Ruby On Rails, http://www.rubyonrails.org
  67. # 2, Google, http://www.google.com
  68. #
  69. # Should you have a piece of data with a comma character in it, you can place double quotes around that value. If you
  70. # need to use a double quote character, you must escape it with another double quote.
  71. #
  72. # Another unique attribute of the CSV fixture is that it has *no* fixture name like the other two formats. Instead, the
  73. # fixture names are automatically generated by deriving the class name of the fixture file and adding an incrementing
  74. # number to the end. In our example, the 1st fixture would be called "web_site_1" and the 2nd one would be called
  75. # "web_site_2".
  76. #
  77. # Most databases and spreadsheets support exporting to CSV format, so this is a great format for you to choose if you
  78. # have existing data somewhere already.
  79. #
  80. # = Single-file fixtures
  81. #
  82. # This type of fixtures was the original format for Active Record that has since been deprecated in favor of the YAML and CSV formats.
  83. # Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory
  84. # appointed by <tt>Test::Unit::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
  85. # put your files in <your-rails-app>/test/fixtures/<your-model-name>/ -- like <your-rails-app>/test/fixtures/web_sites/ for the WebSite
  86. # model).
  87. #
  88. # Each text file placed in this directory represents a "record". Usually these types of fixtures are named without
  89. # extensions, but if you are on a Windows machine, you might consider adding .txt as the extension. Here's what the
  90. # above example might look like:
  91. #
  92. # web_sites/google
  93. # web_sites/yahoo.txt
  94. # web_sites/ruby-on-rails
  95. #
  96. # The file format of a standard fixture is simple. Each line is a property (or column in db speak) and has the syntax
  97. # of "name => value". Here's an example of the ruby-on-rails fixture above:
  98. #
  99. # id => 1
  100. # name => Ruby on Rails
  101. # url => http://www.rubyonrails.org
  102. #
  103. # = Using Fixtures
  104. #
  105. # Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the
  106. # fixtures, but first let's take a look at a sample unit test found:
  107. #
  108. # require 'web_site'
  109. #
  110. # class WebSiteTest < Test::Unit::TestCase
  111. # def test_web_site_count
  112. # assert_equal 2, WebSite.count
  113. # end
  114. # end
  115. #
  116. # As it stands, unless we pre-load the web_site table in our database with two records, this test will fail. Here's the
  117. # easiest way to add fixtures to the database:
  118. #
  119. # ...
  120. # class WebSiteTest < Test::Unit::TestCase
  121. # fixtures :web_sites # add more by separating the symbols with commas
  122. # ...
  123. #
  124. # By adding a "fixtures" method to the test case and passing it a list of symbols (only one is shown here tho), we trigger
  125. # the testing environment to automatically load the appropriate fixtures into the database before each test.
  126. # To ensure consistent data, the environment deletes the fixtures before running the load.
  127. #
  128. # In addition to being available in the database, the fixtures are also loaded into a hash stored in an instance variable
  129. # of the test case. It is named after the symbol... so, in our example, there would be a hash available called
  130. # @web_sites. This is where the "fixture name" comes into play.
  131. #
  132. # On top of that, each record is automatically "found" (using Model.find(id)) and placed in the instance variable of its name.
  133. # So for the YAML fixtures, we'd get @rubyonrails and @google, which could be interrogated using regular Active Record semantics:
  134. #
  135. # # test if the object created from the fixture data has the same attributes as the data itself
  136. # def test_find
  137. # assert_equal @web_sites["rubyonrails"]["name"], @rubyonrails.name
  138. # end
  139. #
  140. # As seen above, the data hash created from the YAML fixtures would have @web_sites["rubyonrails"]["url"] return
  141. # "http://www.rubyonrails.org" and @web_sites["google"]["name"] would return "Google". The same fixtures, but loaded
  142. # from a CSV fixture file, would be accessible via @web_sites["web_site_1"]["name"] == "Ruby on Rails" and have the individual
  143. # fixtures available as instance variables @web_site_1 and @web_site_2.
  144. #
  145. # If you do not wish to use instantiated fixtures (usually for performance reasons) there are two options.
  146. #
  147. # - to completely disable instantiated fixtures:
  148. # self.use_instantiated_fixtures = false
  149. #
  150. # - to keep the fixture instance (@web_sites) available, but do not automatically 'find' each instance:
  151. # self.use_instantiated_fixtures = :no_instances
  152. #
  153. # Even if auto-instantiated fixtures are disabled, you can still access them
  154. # by name via special dynamic methods. Each method has the same name as the
  155. # model, and accepts the name of the fixture to instantiate:
  156. #
  157. # fixtures :web_sites
  158. #
  159. # def test_find
  160. # assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
  161. # end
  162. #
  163. # = Dynamic fixtures with ERb
  164. #
  165. # 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
  166. # mix ERb in with your YAML or CSV fixtures to create a bunch of fixtures for load testing, like:
  167. #
  168. # <% for i in 1..1000 %>
  169. # fix_<%= i %>:
  170. # id: <%= i %>
  171. # name: guy_<%= 1 %>
  172. # <% end %>
  173. #
  174. # This will create 1000 very simple YAML fixtures.
  175. #
  176. # Using ERb, you can also inject dynamic values into your fixtures with inserts like <%= Date.today.strftime("%Y-%m-%d") %>.
  177. # This is however a feature to be used with some caution. The point of fixtures are that they're stable units of predictable
  178. # sample data. If you feel that you need to inject dynamic values, then perhaps you should reexamine whether your application
  179. # is properly testable. Hence, dynamic values in fixtures are to be considered a code smell.
  180. #
  181. # = Transactional fixtures
  182. #
  183. # TestCases can use begin+rollback to isolate their changes to the database instead of having to delete+insert for every test case.
  184. # They can also turn off auto-instantiation of fixture data since the feature is costly and often unused.
  185. #
  186. # class FooTest < Test::Unit::TestCase
  187. # self.use_transactional_fixtures = true
  188. # self.use_instantiated_fixtures = false
  189. #
  190. # fixtures :foos
  191. #
  192. # def test_godzilla
  193. # assert !Foo.find(:all).empty?
  194. # Foo.destroy_all
  195. # assert Foo.find(:all).empty?
  196. # end
  197. #
  198. # def test_godzilla_aftermath
  199. # assert !Foo.find(:all).empty?
  200. # end
  201. # end
  202. #
  203. # If you preload your test database with all fixture data (probably in the Rakefile task) and use transactional fixtures,
  204. # then you may omit all fixtures declarations in your test cases since all the data's already there and every case rolls back its changes.
  205. #
  206. # In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to true. This will provide
  207. # access to fixture data for every table that has been loaded through fixtures (depending on the value of +use_instantiated_fixtures+)
  208. #
  209. # When *not* to use transactional fixtures:
  210. # 1. You're testing whether a transaction works correctly. Nested transactions don't commit until all parent transactions commit,
  211. # particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won't be able to verify
  212. # the results of your transaction until Active Record supports nested transactions or savepoints (in progress.)
  213. # 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM.
  214. # Use InnoDB, MaxDB, or NDB instead.
  215. class Fixtures < YAML::Omap
  216. DEFAULT_FILTER_RE = /\.ya?ml$/
  217. def self.instantiate_fixtures(object, table_name, fixtures, load_instances=true)
  218. object.instance_variable_set "@#{table_name.to_s.gsub('.','_')}", fixtures
  219. if load_instances
  220. ActiveRecord::Base.silence do
  221. fixtures.each do |name, fixture|
  222. begin
  223. object.instance_variable_set "@#{name}", fixture.find
  224. rescue FixtureClassNotFound
  225. nil
  226. end
  227. end
  228. end
  229. end
  230. end
  231. def self.instantiate_all_loaded_fixtures(object, load_instances=true)
  232. all_loaded_fixtures.each do |table_name, fixtures|
  233. Fixtures.instantiate_fixtures(object, table_name, fixtures, load_instances)
  234. end
  235. end
  236. cattr_accessor :all_loaded_fixtures
  237. self.all_loaded_fixtures = {}
  238. def self.create_fixtures(fixtures_directory, table_names, class_names = {})
  239. table_names = [table_names].flatten.map { |n| n.to_s }
  240. connection = block_given? ? yield : ActiveRecord::Base.connection
  241. ActiveRecord::Base.silence do
  242. fixtures_map = {}
  243. fixtures = table_names.map do |table_name|
  244. fixtures_map[table_name] = Fixtures.new(connection, File.split(table_name.to_s).last, class_names[table_name.to_sym], File.join(fixtures_directory, table_name.to_s))
  245. end
  246. all_loaded_fixtures.merge! fixtures_map
  247. connection.transaction(Thread.current['open_transactions'] == 0) do
  248. fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures }
  249. fixtures.each { |fixture| fixture.insert_fixtures }
  250. # Cap primary key sequences to max(pk).
  251. if connection.respond_to?(:reset_pk_sequence!)
  252. table_names.each do |table_name|
  253. connection.reset_pk_sequence!(table_name)
  254. end
  255. end
  256. end
  257. return fixtures.size > 1 ? fixtures : fixtures.first
  258. end
  259. end
  260. attr_reader :table_name
  261. def initialize(connection, table_name, class_name, fixture_path, file_filter = DEFAULT_FILTER_RE)
  262. @connection, @table_name, @fixture_path, @file_filter = connection, table_name, fixture_path, file_filter
  263. @class_name = class_name ||
  264. (ActiveRecord::Base.pluralize_table_names ? @table_name.singularize.camelize : @table_name.camelize)
  265. @table_name = ActiveRecord::Base.table_name_prefix + @table_name + ActiveRecord::Base.table_name_suffix
  266. @table_name = class_name.table_name if class_name.respond_to?(:table_name)
  267. @connection = class_name.connection if class_name.respond_to?(:connection)
  268. read_fixture_files
  269. end
  270. def delete_existing_fixtures
  271. @connection.delete "DELETE FROM #{@table_name}", 'Fixture Delete'
  272. end
  273. def insert_fixtures
  274. values.each do |fixture|
  275. @connection.execute "INSERT INTO #{@table_name} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
  276. end
  277. end
  278. private
  279. def read_fixture_files
  280. if File.file?(yaml_file_path)
  281. # YAML fixtures
  282. yaml_string = ""
  283. Dir["#{@fixture_path}/**/*.yml"].select {|f| test(?f,f) }.each do |subfixture_path|
  284. yaml_string << IO.read(subfixture_path)
  285. end
  286. yaml_string << IO.read(yaml_file_path)
  287. begin
  288. yaml = YAML::load(erb_render(yaml_string))
  289. rescue Exception=>boom
  290. raise Fixture::FormatError, "a YAML error occurred parsing #{yaml_file_path}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{boom.class}: #{boom}"
  291. end
  292. if yaml
  293. # If the file is an ordered map, extract its children.
  294. yaml_value =
  295. if yaml.respond_to?(:type_id) && yaml.respond_to?(:value)
  296. yaml.value
  297. else
  298. [yaml]
  299. end
  300. yaml_value.each do |fixture|
  301. fixture.each do |name, data|
  302. unless data
  303. raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{name} (nil)"
  304. end
  305. self[name] = Fixture.new(data, @class_name)
  306. end
  307. end
  308. end
  309. elsif File.file?(csv_file_path)
  310. # CSV fixtures
  311. reader = CSV::Reader.create(erb_render(IO.read(csv_file_path)))
  312. header = reader.shift
  313. i = 0
  314. reader.each do |row|
  315. data = {}
  316. row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.to_s.strip }
  317. self["#{Inflector::underscore(@class_name)}_#{i+=1}"]= Fixture.new(data, @class_name)
  318. end
  319. elsif File.file?(deprecated_yaml_file_path)
  320. raise Fixture::FormatError, ".yml extension required: rename #{deprecated_yaml_file_path} to #{yaml_file_path}"
  321. else
  322. # Standard fixtures
  323. Dir.entries(@fixture_path).each do |file|
  324. path = File.join(@fixture_path, file)
  325. if File.file?(path) and file !~ @file_filter
  326. self[file] = Fixture.new(path, @class_name)
  327. end
  328. end
  329. end
  330. end
  331. def yaml_file_path
  332. "#{@fixture_path}.yml"
  333. end
  334. def deprecated_yaml_file_path
  335. "#{@fixture_path}.yaml"
  336. end
  337. def csv_file_path
  338. @fixture_path + ".csv"
  339. end
  340. def yaml_fixtures_key(path)
  341. File.basename(@fixture_path).split(".").first
  342. end
  343. def erb_render(fixture_content)
  344. ERB.new(fixture_content).result
  345. end
  346. end
  347. class Fixture #:nodoc:
  348. include Enumerable
  349. class FixtureError < StandardError#:nodoc:
  350. end
  351. class FormatError < FixtureError#:nodoc:
  352. end
  353. def initialize(fixture, class_name)
  354. case fixture
  355. when Hash, YAML::Omap
  356. @fixture = fixture
  357. when String
  358. @fixture = read_fixture_file(fixture)
  359. else
  360. raise ArgumentError, "Bad fixture argument #{fixture.inspect} during creation of #{class_name} fixture"
  361. end
  362. @class_name = class_name
  363. end
  364. def each
  365. @fixture.each { |item| yield item }
  366. end
  367. def [](key)
  368. @fixture[key]
  369. end
  370. def to_hash
  371. @fixture
  372. end
  373. def key_list
  374. columns = @fixture.keys.collect{ |column_name| ActiveRecord::Base.connection.quote_column_name(column_name) }
  375. columns.join(", ")
  376. end
  377. def value_list
  378. klass = @class_name.constantize rescue nil
  379. list = @fixture.inject([]) do |fixtures, (key, value)|
  380. col = klass.columns_hash[key] if klass.kind_of?(ActiveRecord::Base)
  381. fixtures << ActiveRecord::Base.connection.quote(value, col).gsub('[^\]\\n', "\n").gsub('[^\]\\r', "\r")
  382. end
  383. list * ', '
  384. end
  385. def find
  386. klass = @class_name.is_a?(Class) ? @class_name : Object.const_get(@class_name) rescue nil
  387. if klass
  388. klass.find(self[klass.primary_key])
  389. else
  390. raise FixtureClassNotFound, "The class #{@class_name.inspect} was not found."
  391. end
  392. end
  393. private
  394. def read_fixture_file(fixture_file_path)
  395. IO.readlines(fixture_file_path).inject({}) do |fixture, line|
  396. # Mercifully skip empty lines.
  397. next if line =~ /^\s*$/
  398. # Use the same regular expression for attributes as Active Record.
  399. unless md = /^\s*([a-zA-Z][-_\w]*)\s*=>\s*(.+)\s*$/.match(line)
  400. raise FormatError, "#{fixture_file_path}: fixture format error at '#{line}'. Expecting 'key => value'."
  401. end
  402. key, value = md.captures
  403. # Disallow duplicate keys to catch typos.
  404. raise FormatError, "#{fixture_file_path}: duplicate '#{key}' in fixture." if fixture[key]
  405. fixture[key] = value.strip
  406. fixture
  407. end
  408. end
  409. end
  410. module Test #:nodoc:
  411. module Unit #:nodoc:
  412. class TestCase #:nodoc:
  413. cattr_accessor :fixture_path
  414. class_inheritable_accessor :fixture_table_names
  415. class_inheritable_accessor :fixture_class_names
  416. class_inheritable_accessor :use_transactional_fixtures
  417. class_inheritable_accessor :use_instantiated_fixtures # true, false, or :no_instances
  418. class_inheritable_accessor :pre_loaded_fixtures
  419. self.fixture_table_names = []
  420. self.use_transactional_fixtures = false
  421. self.use_instantiated_fixtures = true
  422. self.pre_loaded_fixtures = false
  423. self.fixture_class_names = {}
  424. @@already_loaded_fixtures = {}
  425. self.fixture_class_names = {}
  426. def self.set_fixture_class(class_names = {})
  427. self.fixture_class_names = self.fixture_class_names.merge(class_names)
  428. end
  429. def self.fixtures(*table_names)
  430. table_names = table_names.flatten.map { |n| n.to_s }
  431. self.fixture_table_names |= table_names
  432. require_fixture_classes(table_names)
  433. setup_fixture_accessors(table_names)
  434. end
  435. def self.require_fixture_classes(table_names=nil)
  436. (table_names || fixture_table_names).each do |table_name|
  437. file_name = table_name.to_s
  438. file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
  439. begin
  440. require_dependency file_name
  441. rescue LoadError
  442. # Let's hope the developer has included it himself
  443. end
  444. end
  445. end
  446. def self.setup_fixture_accessors(table_names=nil)
  447. (table_names || fixture_table_names).each do |table_name|
  448. table_name = table_name.to_s.tr('.','_')
  449. define_method(table_name) do |fixture, *optionals|
  450. force_reload = optionals.shift
  451. @fixture_cache[table_name] ||= Hash.new
  452. @fixture_cache[table_name][fixture] = nil if force_reload
  453. if @loaded_fixtures[table_name][fixture.to_s]
  454. @fixture_cache[table_name][fixture] ||= @loaded_fixtures[table_name][fixture.to_s].find
  455. else
  456. raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
  457. end
  458. end
  459. end
  460. end
  461. def self.uses_transaction(*methods)
  462. @uses_transaction = [] unless defined?(@uses_transaction)
  463. @uses_transaction.concat methods.map(&:to_s)
  464. end
  465. def self.uses_transaction?(method)
  466. @uses_transaction = [] unless defined?(@uses_transaction)
  467. @uses_transaction.include?(method.to_s)
  468. end
  469. def use_transactional_fixtures?
  470. use_transactional_fixtures &&
  471. !self.class.uses_transaction?(method_name)
  472. end
  473. def setup_with_fixtures
  474. return unless defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
  475. if pre_loaded_fixtures && !use_transactional_fixtures
  476. raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
  477. end
  478. @fixture_cache = Hash.new
  479. # Load fixtures once and begin transaction.
  480. if use_transactional_fixtures?
  481. if @@already_loaded_fixtures[self.class]
  482. @loaded_fixtures = @@already_loaded_fixtures[self.class]
  483. else
  484. load_fixtures
  485. @@already_loaded_fixtures[self.class] = @loaded_fixtures
  486. end
  487. ActiveRecord::Base.send :increment_open_transactions
  488. ActiveRecord::Base.connection.begin_db_transaction
  489. # Load fixtures for every test.
  490. else
  491. @@already_loaded_fixtures[self.class] = nil
  492. load_fixtures
  493. end
  494. # Instantiate fixtures for every test if requested.
  495. instantiate_fixtures if use_instantiated_fixtures
  496. end
  497. alias_method :setup, :setup_with_fixtures
  498. def teardown_with_fixtures
  499. return unless defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
  500. # Rollback changes if a transaction is active.
  501. if use_transactional_fixtures? && Thread.current['open_transactions'] != 0
  502. ActiveRecord::Base.connection.rollback_db_transaction
  503. Thread.current['open_transactions'] = 0
  504. end
  505. ActiveRecord::Base.verify_active_connections!
  506. end
  507. alias_method :teardown, :teardown_with_fixtures
  508. def self.method_added(method)
  509. case method.to_s
  510. when 'setup'
  511. unless method_defined?(:setup_without_fixtures)
  512. alias_method :setup_without_fixtures, :setup
  513. define_method(:setup) do
  514. setup_with_fixtures
  515. setup_without_fixtures
  516. end
  517. end
  518. when 'teardown'
  519. unless method_defined?(:teardown_without_fixtures)
  520. alias_method :teardown_without_fixtures, :teardown
  521. define_method(:teardown) do
  522. teardown_without_fixtures
  523. teardown_with_fixtures
  524. end
  525. end
  526. end
  527. end
  528. private
  529. def load_fixtures
  530. @loaded_fixtures = {}
  531. fixtures = Fixtures.create_fixtures(fixture_path, fixture_table_names, fixture_class_names)
  532. unless fixtures.nil?
  533. if fixtures.instance_of?(Fixtures)
  534. @loaded_fixtures[fixtures.table_name] = fixtures
  535. else
  536. fixtures.each { |f| @loaded_fixtures[f.table_name] = f }
  537. end
  538. end
  539. end
  540. # for pre_loaded_fixtures, only require the classes once. huge speed improvement
  541. @@required_fixture_classes = false
  542. def instantiate_fixtures
  543. if pre_loaded_fixtures
  544. raise RuntimeError, 'Load fixtures before instantiating them.' if Fixtures.all_loaded_fixtures.empty?
  545. unless @@required_fixture_classes
  546. self.class.require_fixture_classes Fixtures.all_loaded_fixtures.keys
  547. @@required_fixture_classes = true
  548. end
  549. Fixtures.instantiate_all_loaded_fixtures(self, load_instances?)
  550. else
  551. raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
  552. @loaded_fixtures.each do |table_name, fixtures|
  553. Fixtures.instantiate_fixtures(self, table_name, fixtures, load_instances?)
  554. end
  555. end
  556. end
  557. def load_instances?
  558. use_instantiated_fixtures != :no_instances
  559. end
  560. end
  561. end
  562. end