Skip to content

Commit

Permalink
Allow a preloader to be redefined. This should allow the preloaders t…
Browse files Browse the repository at this point in the history
…o be used with autotest.
  • Loading branch information
myronmarston committed Jul 7, 2009
1 parent 24974a2 commit 9637ad8
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 39 deletions.
4 changes: 3 additions & 1 deletion lib/factory_data_preloader/factory_data.rb
Expand Up @@ -22,7 +22,9 @@ class << self
attr_accessor :definition_file_paths

def preload(model_type, options = {}, &proc)
raise PreloaderAlreadyDefinedError.new, "You have already defined the preloader for #{model_type.to_s}" if AllPreloaders.instance.map(&:model_type).include?(model_type)
if existing_preloader = AllPreloaders.instance.from_symbol(model_type, false)
existing_preloader.remove!
end

FactoryDataPreloader::Preloader.new(model_type, options[:model_class], proc, options[:depends_on])

Expand Down
40 changes: 29 additions & 11 deletions lib/factory_data_preloader/preloader.rb
Expand Up @@ -13,15 +13,13 @@ class << self
alias :preload_all? :preload_all

def requested_preloaders
@requested_preloaders ||= begin
if preload_all?
AllPreloaders.instance
else
preloaders = self.preload_types.collect { |type| AllPreloaders.instance.from_symbol(type) }
preloaders += (preloaders.collect { |p| p.all_dependencies }).flatten
preloaders.uniq!
PreloaderCollection.new(preloaders)
end
if preload_all?
AllPreloaders.instance
else
preloaders = self.preload_types.collect { |type| AllPreloaders.instance.from_symbol(type) }
preloaders += (preloaders.collect { |p| p.all_dependencies }).flatten
preloaders.uniq!
PreloaderCollection.new(preloaders)
end
end
end
Expand All @@ -35,6 +33,12 @@ def initialize(model_type, model_class, proc, depends_on)

@model_type, @model_class, @proc, @depends_on = model_type, model_class, proc, [depends_on].compact.flatten
AllPreloaders.instance << self

DataMethods.class_eval do
define_method model_type do |key|
FactoryData.send(:get_record, model_type, key)
end
end
end

def preload!
Expand All @@ -49,11 +53,11 @@ def preloaded?
end

def dependencies
@dependencies ||= self.depends_on.collect { |dependency| AllPreloaders.instance.from_symbol(dependency) }
self.depends_on.collect { |dependency| AllPreloaders.instance.from_symbol(dependency) }
end

def all_dependencies
@all_dependencies ||= (self.dependencies + (self.dependencies.collect { |d| d.all_dependencies }).flatten).uniq
(self.dependencies + (self.dependencies.collect { |d| d.all_dependencies }).flatten).uniq
end

def get_record(key)
Expand All @@ -71,6 +75,20 @@ def get_record(key)

self.model_class.find_by_id(record_id_or_error)
end

def remove!
preloader = self
DataMethods.class_eval do
remove_method(preloader.model_type) if method_defined?(preloader.model_type)
end

if @data
self.model_class.delete_all(:id => @data.record_ids)
@data = nil
end

AllPreloaders.instance.delete(self)
end
end

end
4 changes: 2 additions & 2 deletions lib/factory_data_preloader/preloader_collection.rb
Expand Up @@ -15,9 +15,9 @@ def dependency_order
ordered_preloaders
end

def from_symbol(symbol)
def from_symbol(symbol, raise_error = true)
unless preloader = self.detect { |p| p.model_type == symbol }
raise PreloaderNotDefinedError, "The preloader for :#{symbol} has not been defined."
raise PreloaderNotDefinedError, "The preloader for :#{symbol} has not been defined." if raise_error
end
preloader
end
Expand Down
27 changes: 21 additions & 6 deletions test/factory_data_test.rb
Expand Up @@ -15,12 +15,6 @@ def setup
should_not_change 'User.count'
should_change "FactoryData.methods.include?('users')", :from => false, :to => true

should 'not allow it to be called again' do
assert_raise FactoryDataPreloader::PreloaderAlreadyDefinedError do
FactoryData.preload(:users)
end
end

context 'when there was a previous user record in the database' do
setup { User.create(:first_name => 'Barack', :last_name => 'Obama') }

Expand All @@ -39,6 +33,27 @@ def setup

should_change 'User.count', :by => 1

context 'and later re-defining the preloaders' do
setup do
FactoryData.preload(:users) do |data|
data.add(:thom) { User.create(:first_name => 'Thom', :last_name => 'York') }
data.add(:john) { User.create(:first_name => 'John', :last_name => 'Doe') }
end
end

should_change 'User.count', :by => -1

context 'and preloading the re-defined preloader' do
setup do
@out, @err = OutputCapturer.capture do
FactoryData.preload_data!
end
end

should_change 'User.count', :by => 2
end
end

context 'and later calling FactoryData.users(key)' do
setup { @user = FactoryData.users(:thom) }

Expand Down
24 changes: 5 additions & 19 deletions test/test_helper.rb
Expand Up @@ -42,27 +42,13 @@ module FactoryDataPreloader
def self.reset!
self.preload_all = true
self.preload_types = []
@requested_preloaders = nil
FactoryData.reset!
end

class FactoryData
# helper method to reset the factory data between test runs.
def self.reset!
FactoryDataPreloader::AllPreloaders.instance.each do |preloader|
DataMethods.class_eval do
remove_method(preloader.model_type) if method_defined?(preloader.model_type)
end

if preloader.data
preloader.model_class.delete_all(:id => preloader.data.record_ids)
preloader.instance_variable_set('@data', nil)
end
end

@@single_test_cache = {}
FactoryDataPreloader::AllPreloaders.instance.clear
preloaders = Array.new(FactoryDataPreloader::AllPreloaders.instance)
preloaders.each do |preloader|
preloader.remove!
end

FactoryData.reset_cache!
end
end

Expand Down

0 comments on commit 9637ad8

Please sign in to comment.