Permalink
Browse files

Fixed major bug with inheritance.

The only check for whether or not to re-load the exemplars was in .spawn, but .gather_exemplars would go up the inheritance chain to get generators from parent classes. This caused some problems if a parent class had already gathered exemplars and then a child class caused it to re-gather them. (It was fine if the child class happened first.)

Moved the check to .gather_exemplars, added/moved specs, un-protected .gather_exemplars.
  • Loading branch information...
ymendel committed Apr 17, 2008
1 parent d048dbc commit 582aca6712f34ca045a19dc573accee08d433962
Showing with 91 additions and 37 deletions.
  1. +5 −4 lib/object_daddy.rb
  2. +86 −33 spec/object_daddy_spec.rb
@@ -19,7 +19,7 @@ module ClassMethods
# create a valid instance of this class, using any known generators
def spawn(args = {})
gather_exemplars unless exemplars_generated
gather_exemplars
(generators || {}).each_pair do |handle, gen_data|
next if args[handle]
generator = gen_data[:generator]
@@ -88,9 +88,8 @@ def generator_for(handle, args = {}, &block)
end
end
protected
def gather_exemplars
return if exemplars_generated
if superclass.respond_to?(:gather_exemplars)
superclass.gather_exemplars
self.generators = (superclass.generators || {}).dup
@@ -100,7 +99,9 @@ def gather_exemplars
load(path) if File.exists?(path)
self.exemplars_generated = true
end
protected
# we define an underscore helper ourselves since the ActiveSupport isn't available if we're not using Rails
def underscore(string)
string.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
@@ -148,8 +148,8 @@
end
end
describe ObjectDaddy, "when spawning a class instance" do
before(:each) do
describe ObjectDaddy, 'when registering exemplars' do
before :each do
@class = Class.new(OpenStruct)
@class.send(:include, ObjectDaddy)
@file_path = File.join(File.dirname(__FILE__), 'tmp')
@@ -158,44 +158,97 @@
@class.stubs(:name).returns('Widget')
end
it "should register exemplars for the target class on the first attempt" do
@class.expects(:gather_exemplars)
@class.spawn
end
it "should not register exemplars for the target class after the first attempt" do
@class.spawn
@class.expects(:gather_exemplars).never
@class.spawn
end
it "should look for exemplars for the target class in the standard exemplar path" do
@class.expects(:exemplar_path).returns(@file_path)
@class.spawn
end
it "should look for an exemplar for the target class, based on the class's name" do
@class.expects(:name).returns('Widget')
@class.spawn
describe 'before exemplars have been registered' do
before :each do
@class.stubs(:exemplars_generated).returns(false)
end
it "should look for exemplars for the target class in the standard exemplar path" do
@class.expects(:exemplar_path).returns(@file_path)
@class.gather_exemplars
end
it "should look for an exemplar for the target class, based on the class's name" do
@class.expects(:name).returns('Widget')
@class.gather_exemplars
end
it "should register any generators found in the exemplar for the target class" do
# we are using the concrete Widget class here because otherwise it's difficult to have our exemplar file work in our class
begin
# a dummy class, useful for testing the actual loading of exemplar files
Widget = Class.new(OpenStruct) { include ObjectDaddy }
File.open(@file_name, 'w') {|f| f.puts "class Widget\ngenerator_for :foo\nend\n"}
Widget.stubs(:exemplar_path).returns(@file_path)
Widget.expects(:generator_for)
Widget.gather_exemplars
ensure
# clean up test data file
File.unlink(@file_name) if File.exists?(@file_name)
end
end
it 'should record that exemplars have been registered' do
@class.expects(:exemplars_generated=).with(true)
@class.gather_exemplars
end
end
it "should register any generators found in the exemplar for the target class" do
# we are using the concrete Widget class here because otherwise it's difficult to have our exemplar file work in our class
begin
# a dummy class, useful for testing the actual loading of exemplar files
Widget = Class.new(OpenStruct) { include ObjectDaddy }
File.open(@file_name, 'w') {|f| f.puts "class Widget\ngenerator_for :foo\nend\n"}
Widget.stubs(:exemplar_path).returns(@file_path)
Widget.expects(:generator_for)
Widget.spawn
ensure
# clean up test data file
File.unlink(@file_name) if File.exists?(@file_name)
describe 'after exemplars have been registered' do
before :each do
@class.stubs(:exemplars_generated).returns(true)
end
it "should not look for exemplars for the target class in the standard exemplar path" do
@class.expects(:exemplar_path).never
@class.gather_exemplars
end
it "should not look for an exemplar for the target class, based on the class's name" do
@class.expects(:name).never
@class.gather_exemplars
end
it 'should register no generators' do
# we are using the concrete Widget class here because otherwise it's difficult to have our exemplar file work in our class
begin
# a dummy class, useful for testing the actual loading of exemplar files
Widget = Class.new(OpenStruct) { include ObjectDaddy }
File.open(@file_name, 'w') {|f| f.puts "class Widget\ngenerator_for :foo\nend\n"}
Widget.stubs(:exemplar_path).returns(@file_path)
Widget.stubs(:exemplars_generated).returns(true)
Widget.expects(:generator_for).never
Widget.gather_exemplars
ensure
# clean up test data file
File.unlink(@file_name) if File.exists?(@file_name)
end
end
it 'should not record that exemplars have been registered' do
@class.expects(:exemplars_generated=).never
@class.gather_exemplars
end
end
it "should register no generators if no exemplar for the target class is available" do
@class.expects(:generator_for).never
@class.gather_exemplars
end
end
describe ObjectDaddy, "when spawning a class instance" do
before(:each) do
@class = Class.new(OpenStruct)
@class.send(:include, ObjectDaddy)
@file_path = File.join(File.dirname(__FILE__), 'tmp')
@file_name = File.join(@file_path, 'widget_exemplar.rb')
@class.stubs(:exemplar_path).returns(@file_path)
@class.stubs(:name).returns('Widget')
end
it "should register exemplars for the target class" do
@class.expects(:gather_exemplars)
@class.spawn
end

0 comments on commit 582aca6

Please sign in to comment.