assert_latest{} detects new model objects


This simple test shows assert_latest{} in action:

     c1, c2 = assert_latest Chat do
                Chat.create(:user => aaron, :utterance => 'foo')
                Chat.create(:user => becky, :utterance => 'bar')

     assert{ c1.utterance == 'foo' }
     assert{ c2.utterance == 'bar' }

assert_latest{} sampled the maximum Chat id before yielding to its block. Then it returned any records found with an id greater than that maximum. This helps us write more elaborate production code, which might not return its new objects to its callers.

This blog describes assert_latest's rationale and original functionality:

The latest and greatest version of assert_latest{} contains some new features.

Firstly, the assertion now takes any number of model types. That prevents this icky situation:

   chat = nil
   prop = assert_latest Prop do
     chat = assert_latest Chat do
   assert{ chat.user == prop.user }

The nested blocks interfered with chat's scope, forcing un-Ruby-like contortions when you need to compare the two returned objects. And assert_latest{} is not DRY - it appears twice!

To reduce duplication, you may now pass both models into one assert_latest call. You can also drop in a diagnostic string:

     p, c = assert_latest Prop, Chat, 'diagnostic' do
              Prop.create(:name => 'foo', :price => 42)
              Chat.create(:user => aaron, :utterance => 'bar')

     assert{ == 'foo' }
     assert{ c.utterance == 'bar' }

The returned objects can be individual items, or arrays of returned items:

     p, cz = assert_latest Prop, Chat do
               Prop.create(:name => 'foo', :price => 42)
               Chat.create(:user => aaron, :utterance => 'foo')
               Chat.create(:user => aaron, :utterance => 'bar')

     assert{ == 'foo' }
     assert{ cz.first.utterance == 'foo' }
     assert{ cz. last.utterance == 'bar' }

Ruby lets you unroll those returned arrays. This allows you to check your returned count implicitly:

     p, (c1, c2) = assert_latest Prop, Chat do

I added assert_latest{} (and its evil twin, deny_latest{}) to the assert_efficient_sql package, because they both require ActiveRecord. Get them all, on the usual channels, with Piston:

   piston import svn:// \

Oh, one more feature. When assert_latest fails, it reflects its called block's source into its diagnostic. That requires the RubyReflector module that
assert{ 2.0 } uses, so you will need that too:

   gem install assert2