[ANN] assert_latest{} detects new model objects

Railsers:

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')
          end

 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:

O'Reilly Media - Technology and Business Training

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
production_code_that_props_and_chats()
end
end
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')
        end

 assert{ p.name      == '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')
         end

 assert{ p.name == '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://rubyforge.org/var/svn/efficient-sql/
vendor/plugins/efficient-sql

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

–
Phlip
http://assert2.rubyforge.org/