We have a custom implementation of the Mother Object idea. It''s inside of a module, basically like this: module Factory %w(account friendship person invitation message asset email_address birth).each do |klass| eval <<-EOF def self.create_#{klass}(attributes = {}) default_attributes = valid_#{klass}_attributes #{klass.camelize}.create! default_attributes.merge(attributes) end EOF end def valid_message_attributes(options = {}) { #some message options } end #more valid_x_attributes methods end When I require this file in a spec file, Factory.create_person works fine. When I try to do it in a step file, Factory.create_person is defined, but it fails because valid_person_attributes is missing. If I''m in a debugger, and I do require ''model_factory'' followed by Factory.create_person, same deal. Do we have a blank slate being loaded somewhere, and why is it wiping out require files? Thanks James Deville http://devillecompanies.org james.deville at gmail.com rspec r3172 rspec_on_rails r3172 rails r8331
Your implementation looks so much like a ModelFactory my team implemented last week that it''s scary. Anyway ... Is it a typo that you show the "create_..." methods being def''d as module methods (i.e., "def self.create...") while the "valid_..._attribute" methods are instance methods? That would certainly cause NoMethodErrors (though it would affect specs as well as other contexts). -hume. On Jan 10, 2008 8:27 PM, James Deville <james.deville at gmail.com> wrote:> We have a custom implementation of the Mother Object idea. It''s inside > of a module, basically like this: > > module Factory > %w(account friendship person invitation message asset email_address > birth).each do |klass| > eval <<-EOF > def self.create_#{klass}(attributes = {}) > default_attributes = valid_#{klass}_attributes > #{klass.camelize}.create! default_attributes.merge(attributes) > end > EOF > end > > def valid_message_attributes(options = {}) > { > #some message options > } > end > > #more valid_x_attributes methods > end > > When I require this file in a spec file, Factory.create_person works > fine. When I try to do it in a step file, Factory.create_person is > defined, but it fails because valid_person_attributes is missing. If > I''m in a debugger, and I do require ''model_factory'' followed by > Factory.create_person, same deal. > > Do we have a blank slate being loaded somewhere, and why is it wiping > out require files? > > Thanks > > James Deville > http://devillecompanies.org > james.deville at gmail.com > rspec r3172 > rspec_on_rails r3172 > rails r8331 > > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
It''s not a typo. However, since I''m not the only one to think this, I might make a set of module methods, which can be called by the non- module methods to avoid breaking the current specs. Any idea why one works (specs) and the other doesn''t (stories)? James Deville http://devillecompanies.org james.deville at gmail.com rspec r3172 rspec_on_rails r3172 rails r8331 On Jan 10, 2008, at 7:42 PM, John D. Hume wrote:> Your implementation looks so much like a ModelFactory my team > implemented last week that it''s scary. Anyway ...> Is it a typo that you show the "create_..." methods being def''d as > module methods (i.e., "def self.create...") while the > "valid_..._attribute" methods are instance methods? That would > certainly cause NoMethodErrors (though it would affect specs as well > as other contexts). > > -hume. > > > On Jan 10, 2008 8:27 PM, James Deville <james.deville at gmail.com> > wrote: >> We have a custom implementation of the Mother Object idea. It''s >> inside >> of a module, basically like this: >> >> module Factory >> %w(account friendship person invitation message asset >> email_address >> birth).each do |klass| >> eval <<-EOF >> def self.create_#{klass}(attributes = {}) >> default_attributes = valid_#{klass}_attributes >> #{klass.camelize}.create! >> default_attributes.merge(attributes) >> end >> EOF >> end >> >> def valid_message_attributes(options = {}) >> { >> #some message options >> } >> end >> >> #more valid_x_attributes methods >> end >> >> When I require this file in a spec file, Factory.create_person works >> fine. When I try to do it in a step file, Factory.create_person is >> defined, but it fails because valid_person_attributes is missing. If >> I''m in a debugger, and I do require ''model_factory'' followed by >> Factory.create_person, same deal. >> >> Do we have a blank slate being loaded somewhere, and why is it wiping >> out require files? >> >> Thanks >> >> James Deville >> http://devillecompanies.org >> james.deville at gmail.com >> rspec r3172 >> rspec_on_rails r3172 >> rails r8331 >> >> >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
On Jan 10, 2008, at 8:27 PM, James Deville wrote:> We have a custom implementation of the Mother Object idea. It''s inside > of a module, basically like this: > > module Factory > %w(account friendship person invitation message asset email_address > birth).each do |klass| > eval <<-EOF > def self.create_#{klass}(attributes = {}) > default_attributes = valid_#{klass}_attributes > #{klass.camelize}.create! default_attributes.merge(attributes) > end > EOF > end > > def valid_message_attributes(options = {}) > { > #some message options > } > end > > #more valid_x_attributes methods > end > > When I require this file in a spec file, Factory.create_person works > fine. When I try to do it in a step file, Factory.create_person is > defined, but it fails because valid_person_attributes is missing. If > I''m in a debugger, and I do require ''model_factory'' followed by > Factory.create_person, same deal. > > Do we have a blank slate being loaded somewhere, and why is it wiping > out require files? >Yep - this pretty much looks like version 0.1 of FixutreReplacement: http://pastie.caboo.se/138084 Scott
On Jan 10, 2008, at 8:27 PM, James Deville wrote:> We have a custom implementation of the Mother Object idea. It''s inside > of a module, basically like this: > > module Factory > %w(account friendship person invitation message asset email_address > birth).each do |klass| > eval <<-EOF > def self.create_#{klass}(attributes = {}) > default_attributes = valid_#{klass}_attributes > #{klass.camelize}.create! default_attributes.merge(attributes) > end > EOF > end > > def valid_message_attributes(options = {}) > { > #some message options > } > end > > #more valid_x_attributes methods > end > > When I require this file in a spec file, Factory.create_person works > fine. When I try to do it in a step file, Factory.create_person is > defined, but it fails because valid_person_attributes is missing. If > I''m in a debugger, and I do require ''model_factory'' followed by > Factory.create_person, same deal. > > Do we have a blank slate being loaded somewhere, and why is it wiping > out require files?Actually, though, I think John D. Hume is right (and this is a current bug with FixtureReplacement, as well): your valid_* methods are not class methods, but instance methods. I bet the reason that it has worked in the past is because rspec does funny things with Module#include, and without having the time to look at the source, I''d bet that rspec ends up delegating to the class level (but story runner doesn''t) - giving you the appearance that your software works, but in fact is just taking advantage of rspec''s implementation. Prove me wrong, if you can. Best, Scott
On Jan 11, 2008, at 7:31 AM, Scott Taylor wrote:> > On Jan 10, 2008, at 8:27 PM, James Deville wrote: > >> We have a custom implementation of the Mother Object idea. It''s >> inside >> of a module, basically like this: >> >> module Factory >> %w(account friendship person invitation message asset email_address >> birth).each do |klass| >> eval <<-EOF >> def self.create_#{klass}(attributes = {}) >> default_attributes = valid_#{klass}_attributes >> #{klass.camelize}.create! default_attributes.merge(attributes) >> end >> EOF >> end >> >> def valid_message_attributes(options = {}) >> { >> #some message options >> } >> end >> >> #more valid_x_attributes methods >> end >> >> When I require this file in a spec file, Factory.create_person works >> fine. When I try to do it in a step file, Factory.create_person is >> defined, but it fails because valid_person_attributes is missing. If >> I''m in a debugger, and I do require ''model_factory'' followed by >> Factory.create_person, same deal. >> >> Do we have a blank slate being loaded somewhere, and why is it wiping >> out require files? > > Actually, though, I think John D. Hume is right (and this is a > current bug with FixtureReplacement, as well): your valid_* methods > are not class methods, but instance methods. > > I bet the reason that it has worked in the past is because rspec does > funny things with Module#include, and without having the time to look > at the source, I''d bet that rspec ends up delegating to the class > level (but story runner doesn''t) - giving you the appearance that > your software works, but in fact is just taking advantage of rspec''s > implementation. > > Prove me wrong, if you can. > > Best, > > Scott > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersI''ll probably just try to prove you right James Deville http://devillecompanies.org james.deville at gmail.com rspec r3172 rspec_on_rails r3172 rails r8331