myronmarston-factory_data_preloader 0.3.2 → 0.4.0

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/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 3
4
- :patch: 2
3
+ :minor: 4
4
+ :patch: 0
@@ -17,7 +17,7 @@ module FactoryDataPreloader
17
17
  attr_accessor :definition_file_paths
18
18
 
19
19
  def preload(model_type, options = {}, &proc)
20
- raise PreloaderAlreadyDefinedError.new, "You have already defined the preloader for #{model_type.to_s}" if PreloaderCollection.instance.map(&:model_type).include?(model_type)
20
+ raise PreloaderAlreadyDefinedError.new, "You have already defined the preloader for #{model_type.to_s}" if AllPreloaders.instance.map(&:model_type).include?(model_type)
21
21
 
22
22
  model_class = options[:model_class] || model_type.to_s.singularize.classify.constantize
23
23
  depends_on = [options[:depends_on]].compact.flatten
@@ -35,7 +35,7 @@ module FactoryDataPreloader
35
35
  return unless @@preloaded_data_deleted.nil?
36
36
 
37
37
  # Delete them in the reverse order of the dependencies, to handle foreign keys
38
- PreloaderCollection.instance.dependency_order.reverse.each do |preloader|
38
+ FactoryDataPreloader.requested_preloaders.reverse.each do |preloader|
39
39
  preloader.model_class.delete_all
40
40
  end
41
41
 
@@ -46,7 +46,7 @@ module FactoryDataPreloader
46
46
  return unless @@preloaded_cache.nil? # make sure the data is only preloaded once.
47
47
  @@preloaded_cache = {}
48
48
 
49
- PreloaderCollection.instance.dependency_order.each do |preloader|
49
+ FactoryDataPreloader.requested_preloaders.dependency_order.each do |preloader|
50
50
  cache = @@preloaded_cache[preloader.model_type] ||= {}
51
51
  preloader.data.each do |key, record|
52
52
  if record.new_record? && !record.save
@@ -1,49 +1,61 @@
1
1
  module FactoryDataPreloader
2
2
  class PreloaderNotDefinedError < StandardError; end
3
3
 
4
+ mattr_accessor :preload_all
5
+ self.preload_all = true
6
+
7
+ mattr_accessor :preload_types
8
+ self.preload_types = []
9
+
10
+ class << self
11
+ alias :preload_all? :preload_all
12
+
13
+ def requested_preloaders
14
+ @requested_preloaders ||= begin
15
+ if preload_all?
16
+ AllPreloaders.instance
17
+ else
18
+ preloaders = self.preload_types.collect { |type| AllPreloaders.instance.from_symbol(type) }
19
+ preloaders += (preloaders.collect { |p| p.all_dependencies }).flatten
20
+ preloaders.uniq!
21
+ PreloaderCollection.new(preloaders)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
4
27
  class Preloader
5
28
  attr_accessor :model_type, :model_class, :proc, :depends_on
6
29
 
7
30
  def initialize(model_type, model_class, proc, depends_on)
8
31
  @model_type, @model_class, @proc, @depends_on = model_type, model_class, proc, depends_on || []
9
- PreloaderCollection.instance << self
32
+ AllPreloaders.instance << self
10
33
  end
11
34
 
12
35
  def data
13
36
  @data ||= begin
14
- data = {}
15
- self.proc.try(:call, data)
37
+ data = PreloaderDataHash.new
38
+ print "Preloading #{model_type}:"
39
+ benchmark_measurement = Benchmark.measure { self.proc.try(:call, data) }
40
+ print "(#{format('%.3f', benchmark_measurement.real)} secs)\n"
16
41
  data
17
42
  end
18
43
  end
19
44
 
20
45
  def dependencies
21
- @dependencies ||= begin
22
- self.depends_on.collect do |dependency|
23
- preloader = PreloaderCollection.instance.detect { |p| p.model_type == dependency }
24
- raise PreloaderNotDefinedError, "The preloader for :#{dependency} has not been defined." unless preloader
25
- preloader
26
- end
27
- end
46
+ @dependencies ||= self.depends_on.collect { |dependency| AllPreloaders.instance.from_symbol(dependency) }
28
47
  end
29
- end
30
48
 
31
- class PreloaderCollection < Array
32
- include Singleton
33
-
34
- def dependency_order
35
- unordered_preloaders = Array.new(self) # rather than using self.dup since singleton doesn't allow duping.
36
- ordered_preloaders = []
37
-
38
- until unordered_preloaders.empty?
39
- unordered_preloaders.each do |preloader|
40
- if preloader.dependencies.all? { |dependency| ordered_preloaders.include?(dependency) }
41
- ordered_preloaders << unordered_preloaders.delete(preloader)
42
- end
43
- end
44
- end
49
+ def all_dependencies
50
+ @all_dependencies ||= (self.dependencies + (self.dependencies.collect { |d| d.all_dependencies }).flatten).uniq
51
+ end
52
+ end
45
53
 
46
- ordered_preloaders
54
+ class PreloaderDataHash < Hash
55
+ def []=(key, value)
56
+ print "."
57
+ super
47
58
  end
48
59
  end
60
+
49
61
  end
@@ -0,0 +1,30 @@
1
+ module FactoryDataPreloader
2
+ class PreloaderCollection < Array
3
+ def dependency_order
4
+ unordered_preloaders = Array.new(self) # rather than using self.dup since singleton doesn't allow duping.
5
+ ordered_preloaders = []
6
+
7
+ until unordered_preloaders.empty?
8
+ unordered_preloaders.each do |preloader|
9
+ if preloader.dependencies.all? { |dependency| ordered_preloaders.include?(dependency) }
10
+ ordered_preloaders << unordered_preloaders.delete(preloader)
11
+ end
12
+ end
13
+ end
14
+
15
+ ordered_preloaders
16
+ end
17
+
18
+ def from_symbol(symbol)
19
+ unless preloader = self.detect { |p| p.model_type == symbol }
20
+ raise PreloaderNotDefinedError, "The preloader for :#{symbol} has not been defined."
21
+ end
22
+ preloader
23
+ end
24
+ end
25
+
26
+ class AllPreloaders < PreloaderCollection
27
+ include Singleton
28
+ end
29
+
30
+ end
@@ -30,4 +30,10 @@ class Fixtures
30
30
  end
31
31
 
32
32
  alias_method_chain :delete_existing_fixtures, :preloaded_factory_data
33
+ end
34
+
35
+ class ActiveSupport::TestCase
36
+ def self.preload_factory_data(*types)
37
+ types.each { |t| FactoryDataPreloader.preload_types << t }
38
+ end
33
39
  end
@@ -13,6 +13,7 @@ require 'active_record/fixtures'
13
13
 
14
14
  require 'factory_data_preloader/core_ext'
15
15
  require 'factory_data_preloader/preloader'
16
+ require 'factory_data_preloader/preloader_collection'
16
17
  require 'factory_data_preloader/factory_data'
17
18
  require 'factory_data_preloader/rails_core_ext'
18
19
 
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class FactoryDataTest < Test::Unit::TestCase
4
4
  def setup
5
- FactoryData.reset!
5
+ FactoryDataPreloader.reset!
6
6
  end
7
7
 
8
8
  context 'Calling FactoryData.preload(:users)' do
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class PreloaderTest < Test::Unit::TestCase
4
4
  def setup
5
- FactoryDataPreloader::PreloaderCollection.instance.clear
5
+ FactoryDataPreloader.reset!
6
6
  end
7
7
 
8
8
  context 'A new preloader' do
@@ -21,7 +21,7 @@ class PreloaderTest < Test::Unit::TestCase
21
21
  end
22
22
 
23
23
  should 'be automatically added to the PreloaderCollection' do
24
- assert_equal [@preloader], FactoryDataPreloader::PreloaderCollection.instance
24
+ assert_equal [@preloader], FactoryDataPreloader::AllPreloaders.instance
25
25
  end
26
26
  end
27
27
 
@@ -59,7 +59,44 @@ class PreloaderTest < Test::Unit::TestCase
59
59
 
60
60
  should 'sort correctly for PreloaderCollection.instance.dependency_order' do
61
61
  expected = [@ip_addresses, @users, @posts, @post_images, @post_image_ratings]
62
- assert_equal expected.map(&:model_type), FactoryDataPreloader::PreloaderCollection.instance.dependency_order.map(&:model_type)
62
+ assert_equal expected.map(&:model_type), FactoryDataPreloader::AllPreloaders.instance.dependency_order.map(&:model_type)
63
+ end
64
+
65
+ should 'return the correct preloader objects for #all_dependencies' do
66
+ assert_same_elements [@post_images, @posts, @users], @post_image_ratings.all_dependencies
67
+ assert_same_elements [@posts, @users], @post_images.all_dependencies
68
+ assert_same_elements [], @ip_addresses.all_dependencies
69
+ assert_same_elements [@users], @posts.all_dependencies
70
+ assert_same_elements [], @users.all_dependencies
71
+ end
72
+
73
+ context 'when FactoryDataPreloader.preload_all = true' do
74
+ setup do
75
+ FactoryDataPreloader.preload_all = true
76
+ end
77
+
78
+ should 'return all preloaders for FactoryDataPreloader.requested_preloaders' do
79
+ expected = [@ip_addresses, @users, @posts, @post_images, @post_image_ratings]
80
+ assert_equal expected.map(&:model_type), FactoryDataPreloader.requested_preloaders.dependency_order.map(&:model_type)
81
+ end
82
+ end
83
+
84
+ context 'when FactoryDataPreloader.preload_all = false' do
85
+ setup do
86
+ FactoryDataPreloader.preload_all = false
87
+ end
88
+
89
+ should 'return no preloaders when for FactoryDataPreloader.requested_preloaders when preload_types is empty' do
90
+ assert_equal [], FactoryDataPreloader.preload_types
91
+ assert_equal [], FactoryDataPreloader.requested_preloaders
92
+ end
93
+
94
+ should 'return just the requested preloaders for FactoryDataPreloader.requested_preloaders' do
95
+ FactoryDataPreloader.preload_types << :post_images
96
+ FactoryDataPreloader.preload_types << :ip_addresses
97
+ expected = [@ip_addresses, @users, @posts, @post_images]
98
+ assert_equal expected.map(&:model_type), FactoryDataPreloader.requested_preloaders.dependency_order.map(&:model_type)
99
+ end
63
100
  end
64
101
  end
65
102
  end
data/test/test_helper.rb CHANGED
@@ -38,23 +38,32 @@ module OutputCapturer
38
38
  end
39
39
  end
40
40
 
41
- class FactoryDataPreloader::FactoryData
42
- # helper method to reset the factory data between test runs.
41
+ module FactoryDataPreloader
43
42
  def self.reset!
44
- FactoryDataPreloader::PreloaderCollection.instance.dependency_order.reverse.each do |preloader|
45
- class << self; self; end.class_eval do
46
- remove_method(preloader.model_type)
47
- end
43
+ self.preload_all = true
44
+ self.preload_types = []
45
+ @requested_preloaders = nil
46
+ FactoryData.reset!
47
+ end
48
+
49
+ class FactoryData
50
+ # helper method to reset the factory data between test runs.
51
+ def self.reset!
52
+ FactoryDataPreloader::AllPreloaders.instance.each do |preloader|
53
+ class << self; self; end.class_eval do
54
+ remove_method(preloader.model_type) if method_defined?(preloader.model_type)
55
+ end
48
56
 
49
- unless @@preloaded_cache.nil?
50
- preloader.model_class.delete_all(:id => (@@preloaded_cache[preloader.model_type] || {}).values)
57
+ unless @@preloaded_cache.nil?
58
+ preloader.model_class.delete_all(:id => (@@preloaded_cache[preloader.model_type] || {}).values)
59
+ end
51
60
  end
52
- end
53
61
 
54
- @@preloaded_cache = nil
55
- @@preloaded_data_deleted = nil
56
- @@single_test_cache = {}
57
- FactoryDataPreloader::PreloaderCollection.instance.clear
62
+ @@preloaded_cache = nil
63
+ @@preloaded_data_deleted = nil
64
+ @@single_test_cache = {}
65
+ FactoryDataPreloader::AllPreloaders.instance.clear
66
+ end
58
67
  end
59
68
  end
60
69
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: myronmarston-factory_data_preloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Myron Marston
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-07 00:00:00 -07:00
12
+ date: 2009-06-01 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -29,6 +29,7 @@ files:
29
29
  - lib/factory_data_preloader/core_ext.rb
30
30
  - lib/factory_data_preloader/factory_data.rb
31
31
  - lib/factory_data_preloader/preloader.rb
32
+ - lib/factory_data_preloader/preloader_collection.rb
32
33
  - lib/factory_data_preloader/rails_core_ext.rb
33
34
  - lib/factory_data_preloader.rb
34
35
  - test/factory_data_test.rb