<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/nulldb_rspec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -23,11 +23,48 @@ RAILS_ROOT/db/schema.rb.  You can override that by setting the
   ActiveRecord::Base.establish_connection :adapter =&gt; :nulldb,
                                           :schema  =&gt; foo/myschema.rb
 
-There is a helper method included for configuring RSpec sessions to
-use NullDB.  Just put the following in your spec/spec_helper.rb:
+NullDB comes with RSpec integration.  To replace the database with
+NullDB in all of your specs, put the following in your
+spec/spec_helper:
 
-  Spec::Runner.configure do |config|
-    ::NullDB.insinuate_into_spec(config)
+  require 'nulldb_rspec'
+  include NullDB::RSpec::NullifiedDatabase
+
+Or if you just want to use NullDB in a specific spec context, you can
+include the same module inside a context:
+
+  require 'nulldb_rspec'
+
+  describe Employee, &quot;with access to the database&quot; do
+    fixtures :employees
+    # ...
+  end
+
+  describe Employee, &quot;with NullDB&quot; do
+    include NullDB::RSpec::NullifiedDatabase
+    # ...
+  end
+
+NullDB::Rspec provides some custom matcher support for verifying
+expectations about interactions with the database:
+
+  describe Employee do
+    include NullDB::RSpec::NullifiedDatabase
+
+    it &quot;should cause an insert statement to be executed&quot; do
+      Employee.create!
+      Employee.connection.should have_executed(:insert)
+    end
+  end
+
+UnitRecord-style verification that no database calls have been made at
+all can be achieved by using the special +:anything+ symbol:
+
+  describe &quot;stuff that shouldn't touch the database&quot; do
+    after :each do
+      Employee.connection.should_not have_executed(:anything)
+    end
+    # ...
   end
 
 You can also experiment with putting NullDB in your database.yml:</diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1 @@
-require 'active_record/connection_adapters/nulldb_adapter'
-
-::NullDB = ActiveRecord::ConnectionAdapters::NullDB
+#require 'active_record/connection_adapters/nulldb_adapter'</diff>
      <filename>init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,13 +6,35 @@ require 'active_record/connection_adapters/abstract_adapter'
 class ActiveRecord::Base
   # Instantiate a new NullDB connection.  Used by ActiveRecord internally.
   def self.nulldb_connection(config)
-    ActiveRecord::ConnectionAdapters::NullDB.new(config)
+    ActiveRecord::ConnectionAdapters::NullDBAdapter.new(config)
   end
 end
 
-class ActiveRecord::ConnectionAdapters::NullDB &lt;
+class ActiveRecord::ConnectionAdapters::NullDBAdapter &lt;
     ActiveRecord::ConnectionAdapters::AbstractAdapter
 
+  class Statement
+    attr_reader :entry_point, :content
+
+    def initialize(entry_point, content = &quot;&quot;)
+      @entry_point, @content = entry_point, content
+    end
+
+    def ==(other)
+      self.entry_point == other.entry_point
+    end
+  end
+
+  class Checkpoint &lt; Statement
+    def initialize
+      super(:checkpoint, &quot;&quot;)
+    end
+
+    def ==(other)
+      self.class == other.class
+    end
+  end
+
   TableDefinition = ActiveRecord::ConnectionAdapters::TableDefinition
 
   # A convenience method for integratinginto RSpec.  See README for example of
@@ -27,10 +49,6 @@ class ActiveRecord::ConnectionAdapters::NullDB &lt;
     end
   end
 
-  def self.execution_log
-    (@@execution_log ||= [])
-  end
-
   # Recognized options:
   #
   # [+:schema+] path to the schema file, relative to RAILS_ROOT
@@ -43,6 +61,25 @@ class ActiveRecord::ConnectionAdapters::NullDB &lt;
     super(nil, @logger)
   end
 
+  # A log of every statement that has been &quot;executed&quot; by this connection adapter
+  # instance.
+  def execution_log
+    (@execution_log ||= [])
+  end
+
+  # A log of every statement that has been &quot;executed&quot; since the last time
+  # #checkpoint! was called, or since the connection was created.
+  def execution_log_since_checkpoint
+    checkpoint_index = @execution_log.rindex(Checkpoint.new)
+    checkpoint_index = checkpoint_index ? checkpoint_index + 1 : 0
+    @execution_log[(checkpoint_index..-1)]
+  end
+
+  # Inserts a checkpoint in the log.  See also #execution_log_since_checkpoint.
+  def checkpoint!
+    self.execution_log &lt;&lt; Checkpoint.new
+  end
+
   def adapter_name
     &quot;NullDB&quot;
   end
@@ -62,10 +99,12 @@ class ActiveRecord::ConnectionAdapters::NullDB &lt;
     @tables[table_name] = table_definition
   end
 
+  # Retrieve the table names defined by the schema
   def tables
     @tables.keys.map(&amp;:to_s)
   end
 
+  # Retrieve table columns as defined by the schema
   def columns(table_name, name = nil)
     if @tables.size &lt;= 1
       ActiveRecord::Migration.verbose = false
@@ -81,16 +120,53 @@ class ActiveRecord::ConnectionAdapters::NullDB &lt;
   end
 
   def execute(statement, name = nil)
-    self.class.execution_log &lt;&lt; statement
+    self.execution_log &lt;&lt; Statement.new(entry_point, statement)
   end
 
-  def insert(statement, name, primary_key, object_id, *args)
-    execute(statement, name)
-    object_id || next_unique_id
+  def insert(statement, name, primary_key, object_id, sequence_name)
+    returning(object_id || next_unique_id) do
+      with_entry_point(:insert) do
+        super(statement, name, primary_key, object_id, sequence_name)
+      end
+    end
+  end
+
+  def update(statement, name=nil)
+    with_entry_point(:update) do
+      super(statement, name)
+    end
   end
 
+  def delete(statement, name=nil)
+    with_entry_point(:delete) do
+      super(statement, name)
+    end
+  end
+
+  def select_all(statement, name=nil)
+    with_entry_point(:select_all) do
+      super(statement, name)
+    end
+  end
+
+  def select_one(statement, name=nil)
+    with_entry_point(:select_one) do
+      super(statement, name)
+    end
+  end
+
+  def select_value(statement, name=nil)
+    with_entry_point(:select_value) do
+      super(statement, name)
+    end
+  end
+
+  protected
+
   def select(statement, name)
-    []
+    returning([]) do
+      self.execution_log &lt;&lt; Statement.new(entry_point, statement)
+    end
   end
 
   private
@@ -98,4 +174,28 @@ class ActiveRecord::ConnectionAdapters::NullDB &lt;
   def next_unique_id
     @last_unique_id += 1
   end
+
+  def with_entry_point(method)
+    if entry_point.nil?
+      with_thread_local_variable(:entry_point, method) do
+        yield
+      end
+    else
+      yield
+    end
+  end
+
+  def entry_point
+    Thread.current[:entry_point]
+  end
+
+  def with_thread_local_variable(name, value)
+    old_value = Thread.current[name]
+    Thread.current[name] = value
+    begin
+      yield
+    ensure
+      Thread.current[name] = old_value
+    end
+  end
 end</diff>
      <filename>lib/active_record/connection_adapters/nulldb_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,5 @@
 require 'rubygems'
+require 'spec'
 require 'active_record'
 $: &lt;&lt; File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;lib&quot;)
 
@@ -103,10 +104,10 @@ describe &quot;NullDB&quot; do
   end
 
   it &quot;should log executed SQL statements&quot; do
-    exec_count = ActiveRecord::ConnectionAdapters::NullDB.execution_log.size
+    cxn = @employee.connection
+    exec_count = cxn.execution_log.size
     @employee.save!
-    ActiveRecord::ConnectionAdapters::NullDB.execution_log.size.should ==
-      (exec_count + 1)
+    cxn.execution_log.size.should == (exec_count + 1)
   end
 
   it &quot;should have the adapter name 'NullDB'&quot; do
@@ -122,9 +123,57 @@ describe &quot;NullDB&quot; do
   end
 
   it &quot;should return an empty array from #select&quot; do
-    @employee.connection.select(&quot;who cares&quot;, &quot;blah&quot;).should == []
+    @employee.connection.select_all(&quot;who cares&quot;, &quot;blah&quot;).should == []
   end
 
+  it &quot;should provide a way to set log checkpoints&quot; do
+    cxn = @employee.connection
+    @employee.save!
+    cxn.execution_log_since_checkpoint.size.should &gt; 0
+    cxn.checkpoint!
+    cxn.execution_log_since_checkpoint.size.should == 0
+    @employee.save!
+    cxn.execution_log_since_checkpoint.size.should == 1
+  end
+
+  def should_contain_statement(cxn, entry_point)
+    cxn.execution_log_since_checkpoint.should \
+      include(ActiveRecord::ConnectionAdapters::NullDBAdapter::Statement.new(entry_point))
+  end
+
+  def should_not_contain_statement(cxn, entry_point)
+    cxn.execution_log_since_checkpoint.should_not \
+      include(ActiveRecord::ConnectionAdapters::NullDBAdapter::Statement.new(entry_point))
+  end
+
+  it &quot;should tag logged statements with their entry point&quot; do
+    cxn = @employee.connection
+
+    should_not_contain_statement(cxn, :insert)
+    @employee.save
+    should_contain_statement(cxn, :insert)
+
+    cxn.checkpoint!
+    should_not_contain_statement(cxn, :update)
+    @employee.save
+    should_contain_statement(cxn, :update)
+
+    cxn.checkpoint!
+    should_not_contain_statement(cxn, :delete)
+    @employee.destroy
+    should_contain_statement(cxn, :delete)
+
+    cxn.checkpoint!
+    should_not_contain_statement(cxn, :select_all)
+    Employee.find(:all)
+    should_contain_statement(cxn, :select_all)
+
+    cxn.checkpoint!
+    should_not_contain_statement(cxn, :select_value)
+    Employee.count_by_sql(&quot;frobozz&quot;)
+    should_contain_statement(cxn, :select_value)
+end
+
   def should_have_column(klass, col_name, col_type)
     col = klass.columns_hash[col_name.to_s]
     col.should_not be_nil</diff>
      <filename>spec/nulldb_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>e7f3e19904e25d26518956da1487e21f894a47bd</id>
    </parent>
  </parents>
  <author>
    <name>Avdi Grimm</name>
    <email>avdi@avdi.org</email>
  </author>
  <url>http://github.com/technicalpickles/nulldb/commit/fcca7980c3f70f6bce7d996aad11da118ac47369</url>
  <id>fcca7980c3f70f6bce7d996aad11da118ac47369</id>
  <committed-date>2008-02-21T15:15:14-08:00</committed-date>
  <authored-date>2008-02-21T15:15:14-08:00</authored-date>
  <message> * More RSpec integration
 * More documentation</message>
  <tree>417b3497cc660882306efe78ead23f9c0e7f83ad</tree>
  <committer>
    <name>Avdi Grimm</name>
    <email>avdi@avdi.org</email>
  </committer>
</commit>
