Closed arturaz closed 13 years ago
Can you give a more concrete example of its usage? I guess I'm just not understanding why you couldn't do
Factory.define :building, :class => Building::Mothership do |m|
m.x 0
m.x_end { |r, options| r.x + Building::Mothership.property('width') }
end
Imagine this:
# We define Building::Mothership here just for convenience.
# width is 6
Factory.define :building, :class => Building::Mothership do |m|
m.x 0
m.x_end { |r| r.x + r.instance_variable_get("@instance").class.property('width') }
end
# width is 3
Factory.define :building_barracks, :class => Building::Barracks, :parent => :building do |m|
end
# width is 2
Factory.define :building_solar_plant, :class => Building::SolarPlant, :parent => :building do |m|
end
And so on. If I use class name in my factory, i must write appropriate x_end and y_end factory methods, while if I can use @instance.class, I only need to define them once in the base.
Did I explain it clearly?
You did explain it clearly, and while I understand what you're saying, I feel like there are better ways to go about doing this. For example, if you know x and a building's width, you'd be able to calculate x_end on the superclass instead of setting it in the factory. Does that seem reasonable?
Yeah, I've done that with building, but sometimes I can't calculate them in superclass.
E.g.
Factory.define :technology, :class => Technology::TestTechnology do |m|
m.level 0
m.scientists do |r|
r.instance_variable_get("@instance").scientists_min(r.level + 1)
end
m.association :player
m.pause_remainder nil
m.pause_scientists nil
m.upgrade_ends_at nil
end
When actual code is used, user is supposed to provide value for scientists. In tests I only care that it would specify some condition, therefore I use the @instance hack.
Although it still feels wrong to me, you can get the @instance variable from the proxy object by calling proxy#result
. So, you could do:
Factory.define :user do |user|
user.age {|u| u.result.class.min_age + 5 }
end
Again, I just want to stress being careful about how much logic is contained in your factories; if the values REALLY matter, that logic shouldn't be replicated in your factories, it should be in your models.
You should probably add this #result thing to docs so that others would know too ;)
Thanks for your time!
Actually it's still wrong.
Calling #result tries to save the object, which is not valid in time of construction yet, so it fails with validation errors.
I'll post an example later.
Factory.define :building, :class => Building::Mothership do |m| m.x 0 m.x_end { |r| r.x + r.instance_variable_get("@instance").class.property('width') } end
It would be nice to just be able to
Factory.define :building, :class => Building::Mothership do |m| m.x 0 m.x_end { |r, options| r.x + options[:class].property('width') } end