Hello-- I''m not sure if I''m pushing too far out of specing a given model, but here''s what I want to express: class A < AR::Base has_many :bs def okay(segment) end end class B < AR::Base belongs_to :a end it A, "should increase the vote count for a given segment if okayed" do @a = A.create(stuff) @a.okay(10) # okay segment 10 # here''s where I''m having trouble... # a.bs should have one row, and it should have a segment number of 10 and various other stuff should happen # subsequent @a.okay with different values should transform numbers in a predictable way. This is handled in # the A model because the transforms occur only in Bs that belong to a given A. @a.bs.find_by_segment_number(10).thingie.should be(1) # not too expressive @a.okay(9) @a.bs.find_by_segment_number(9).thingie.should be(1) # still not too expressive @a.bs. find_by_segment_number(9).transformed_thingie.should be(something_else) end This kind of spec smells to me, yet I am having trouble figuring out how to explain, using rspec, exactly what the behavior is to be in a multi-step sequence. Anybody have thoughts regarding how this might be done better? Thanks
On Sun, Jul 6, 2008 at 5:43 PM, s.ross <cwdinfo at gmail.com> wrote:> Hello-- > > I''m not sure if I''m pushing too far out of specing a given model, but here''s > what I want to express: > > class A < AR::Base > has_many :bs > > def okay(segment) > end > end > > class B < AR::Base > belongs_to :a > end > > it A, "should increase the vote count for a given segment if okayed" do > @a = A.create(stuff) > @a.okay(10) # okay segment 10 > # here''s where I''m having trouble... > # a.bs should have one row, and it should have a segment number of 10 and > various other stuff should happen > # subsequent @a.okay with different values should transform numbers in a > predictable way. This is handled in > # the A model because the transforms occur only in Bs that belong to a > given A. > @a.bs.find_by_segment_number(10).thingie.should be(1) # not too expressive > @a.okay(9) > @a.bs.find_by_segment_number(9).thingie.should be(1) # still not too > expressive > @a.bs. find_by_segment_number(9).transformed_thingie.should > be(something_else) > end > > This kind of spec smells to me, yet I am having trouble figuring out how to > explain, using rspec, exactly what the behavior is to be in a multi-step > sequence. > > Anybody have thoughts regarding how this might be done better?Hi, You could do lambda { @a.okay(9) }.should change { @a.bs.find_by_segment_number(9) }. from(nil).to(1) I do wonder if you might be able to make it a bit more behavior-oriented, maybe something like lambda { @a.okay(9) }.should change { @a.count_votes_for(9) }.by(1) I don''t know exactly what you''re trying to get at though, so I can''t be more specific. At any rate, does using "should change" make it more readable to you? Pat
On Jul 6, 2008, at 3:00 PM, Pat Maddox wrote:> On Sun, Jul 6, 2008 at 5:43 PM, s.ross <cwdinfo at gmail.com> wrote: >> Hello-- >> >> I''m not sure if I''m pushing too far out of specing a given model, >> but here''s >> what I want to express: >> >> class A < AR::Base >> has_many :bs >> >> def okay(segment) >> end >> end >> >> class B < AR::Base >> belongs_to :a >> end >> >> it A, "should increase the vote count for a given segment if >> okayed" do >> @a = A.create(stuff) >> @a.okay(10) # okay segment 10 >> # here''s where I''m having trouble... >> # a.bs should have one row, and it should have a segment number of >> 10 and >> various other stuff should happen >> # subsequent @a.okay with different values should transform numbers >> in a >> predictable way. This is handled in >> # the A model because the transforms occur only in Bs that belong >> to a >> given A. >> @a.bs.find_by_segment_number(10).thingie.should be(1) # not too >> expressive >> @a.okay(9) >> @a.bs.find_by_segment_number(9).thingie.should be(1) # still not too >> expressive >> @a.bs. find_by_segment_number(9).transformed_thingie.should >> be(something_else) >> end >> >> This kind of spec smells to me, yet I am having trouble figuring >> out how to >> explain, using rspec, exactly what the behavior is to be in a multi- >> step >> sequence. >> >> Anybody have thoughts regarding how this might be done better? > > Hi, > > You could do > > lambda { > @a.okay(9) > }.should change { @a.bs.find_by_segment_number(9) }. > from(nil).to(1) > > I do wonder if you might be able to make it a bit more > behavior-oriented, maybe something like > > lambda { > @a.okay(9) > }.should change { @a.count_votes_for(9) }.by(1) > > I don''t know exactly what you''re trying to get at though, so I can''t > be more specific. At any rate, does using "should change" make it > more readable to you?Great suggestion using from and to. I am already using the behavior- oriented lambda{something_or_other}.should change(B, :count).by(1) for the straightforward case. The more difficult case is that when that okay() happens, it may or may not add a row, but it does some transformations that cause updates to fields in all of the rows belonging to the A. Sorry I can''t be more specific than A''s and B''s :) And thanks again. Rspec rocks.