Repository: grosser/test_after_commit
Branch: master
Commit: a3cbb3624b0e
Files: 17
Total size: 19.6 KB
Directory structure:
gitextract_de18ncmi/
├── .travis.yml
├── Gemfile
├── MIT-LICENSE
├── Rakefile
├── Readme.md
├── gemfiles/
│ ├── 32.gemfile
│ ├── 40.gemfile
│ ├── 41.gemfile
│ └── 42.gemfile
├── lib/
│ ├── test_after_commit/
│ │ ├── database_statements.rb
│ │ ├── version.rb
│ │ └── with_transaction_state.rb
│ └── test_after_commit.rb
├── spec/
│ ├── database.rb
│ ├── spec_helper.rb
│ └── test_after_commit_spec.rb
└── test_after_commit.gemspec
================================================
FILE CONTENTS
================================================
================================================
FILE: .travis.yml
================================================
language: ruby
sudo: false
cache: bundler
bundler_args: '--path vendor/bundle'
gemfile:
- gemfiles/32.gemfile
- gemfiles/40.gemfile
- gemfiles/41.gemfile
- gemfiles/42.gemfile
rvm:
- 2.0.0
- 2.1.8
- 2.2.4
env:
- REAL=1
- TEST=1
script: bundle exec rake spec
================================================
FILE: Gemfile
================================================
source "https://rubygems.org"
gemspec
gem 'rails-observers'
================================================
FILE: MIT-LICENSE
================================================
Copyright (c) 2014 Michael Grosser <michael@grosser.it>
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: Rakefile
================================================
require 'bundler/setup'
require 'bundler/gem_tasks'
require 'bump/tasks'
require 'wwtd/tasks'
task :spec do
sh "rspec spec/"
end
task :default => "wwtd:local"
================================================
FILE: Readme.md
================================================
Make after_commit callbacks fire in tests for Rails 3+ with transactional_fixtures = true.
**Deprecation** this is no longer needed on rails 5.0+ https://github.com/rails/rails/pull/18458
Install
=======
gem install test_after_commit
# Gemfile (never include in :development !)
gem 'test_after_commit', :group => :test
Usage
=====
Test that the methods get called or the side-effect of the methods, something like:
```Ruby
class Car < ActiveRecord::Base
after_commit :foo, :on => :update
def foo
$foo = 1
end
end
...
it "sets $foo on commit" do
$foo.should == nil
car.save!
$foo.should == 1
end
```
### Temporary disable after commit hooks
In your test_helper, you can specify the default
```
TestAfterCommit.enabled = true
```
Then use blocks in your tests to change the behavior:
```
TestAfterCommit.with_commits(true) do
my_tests
end
TestAfterCommit.with_commits(false) do
my_tests
end
```
TIPS
====
- hooks do not re-raise errors (with or without this gem) use [after_commit_exception_notification](https://github.com/grosser/after_commit_exception_notification)
Author
======
Inspired by https://gist.github.com/1305285
### [Contributors](https://github.com/grosser/test_after_commit/contributors)
- [James Le Cuirot](https://github.com/chewi)
- [emirose](https://github.com/emirose)
- [Brad Gessler](https://github.com/bradgessler)
- [Rohan McGovern](https://github.com/rohanpm)
- [lsylvester](https://github.com/lsylvester)
- [Tony Novak](https://github.com/afn)
- [Brian Palmer](https://github.com/codekitchen)
- [Oleg Dashevskii](https://github.com/be9)
- [Jonathan Spies](https://github.com/jspies)
- [Nick Sieger](https://github.com/nicksieger)
[Michael Grosser](http://grosser.it)<br/>
michael@grosser.it<br/>
License: MIT<br/>
[](https://travis-ci.org/grosser/test_after_commit)
================================================
FILE: gemfiles/32.gemfile
================================================
source "https://rubygems.org"
gemspec :path=>"../"
gem "activerecord", "~> 3.2.18"
gem "i18n", "~> 0.6.9" # 0.7 does not support 1.9
gem "bump", "0.5.2" # after that it's 1.9.3 only
================================================
FILE: gemfiles/40.gemfile
================================================
source "https://rubygems.org"
gemspec :path=>"../"
gem "activerecord", "~> 4.0.6"
gem "rails-observers"
================================================
FILE: gemfiles/41.gemfile
================================================
source "https://rubygems.org"
gemspec :path=>"../"
gem "activerecord", "~> 4.1.2"
gem "rails-observers"
================================================
FILE: gemfiles/42.gemfile
================================================
source "https://rubygems.org"
gemspec :path=>"../"
gem "activerecord", "~> 4.2.0.beta1"
gem "rails-observers"
================================================
FILE: lib/test_after_commit/database_statements.rb
================================================
module TestAfterCommit::DatabaseStatements
def transaction(*)
@test_open_transactions ||= 0
skip_emulation = ActiveRecord::Base.connection.open_transactions.zero?
run_callbacks = false
result = nil
rolled_back = false
super do
begin
@test_open_transactions += 1
if ActiveRecord::VERSION::MAJOR == 3
@_current_transaction_records.push([]) if @_current_transaction_records.empty?
end
result = yield
rescue Exception
rolled_back = true
raise
ensure
@test_open_transactions -= 1
if @test_open_transactions == 0 && !rolled_back && !skip_emulation
if TestAfterCommit.enabled
run_callbacks = true
elsif ActiveRecord::VERSION::MAJOR == 3
@_current_transaction_records.clear
end
end
end
end
ensure
test_commit_records if run_callbacks
result
end
def test_commit_records
if ActiveRecord::VERSION::MAJOR == 3
commit_transaction_records
else
# To avoid an infinite loop, we need to copy the transaction locally, and clear out
# `records` on the copy that stays in the AR stack. Otherwise new
# transactions inside a commit callback will cause an infinite loop.
#
# This is because we're re-using the transaction on the stack, before
# it's been popped off and re-created by the AR code.
original = @transaction || @transaction_manager.current_transaction
return unless original.respond_to?(:records)
transaction = original.dup
transaction.instance_variable_set(:@records, transaction.records.dup) # deep clone of records array
original.records.clear # so that this clear doesn't clear out both copies
transaction.commit_records
end
end
end
================================================
FILE: lib/test_after_commit/version.rb
================================================
module TestAfterCommit
VERSION = '1.2.2'
end
================================================
FILE: lib/test_after_commit/with_transaction_state.rb
================================================
# disable parts of the sync code that starts looping
module TestAfterCommit
module WithTransactionState
def sync_with_transaction_state
@reflects_state ||= []
@reflects_state[0] = true
super
end
end
end
================================================
FILE: lib/test_after_commit.rb
================================================
require 'test_after_commit/version'
if ActiveRecord::VERSION::MAJOR >= 5
raise 'after_commit testing is baked into rails 5, you no longer need test_after_commit gem'
end
if ActiveRecord::VERSION::MAJOR >= 4
require 'test_after_commit/with_transaction_state'
ActiveRecord::Base.send(:prepend, TestAfterCommit::WithTransactionState)
end
require 'test_after_commit/database_statements'
ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:prepend, TestAfterCommit::DatabaseStatements)
module TestAfterCommit
@enabled = true
class << self
attr_accessor :enabled
def with_commits(value = true)
old = enabled
self.enabled = value
yield
ensure
self.enabled = old
end
end
end
================================================
FILE: spec/database.rb
================================================
# setup database
require 'active_record'
if ActiveRecord::VERSION::MAJOR > 3
require "rails/observers/activerecord/active_record"
end
if ActiveRecord::VERSION::STRING >= "4.2.0"
ActiveRecord::Base.raise_in_transactional_callbacks = true
end
ActiveRecord::Base.establish_connection(
:adapter => 'sqlite3',
:database => ':memory:'
)
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define(:version => 1) do
create_table "cars", :force => true do |t|
t.integer :counter, :default => 0, :null => false
t.integer :car_id
t.timestamps :null => false
end
create_table "addresses", :force => true do |t|
t.integer :number_of_residents, :default => 0, :null => false
t.timestamps :null => false
end
create_table "people", :force => true do |t|
t.belongs_to :address
t.timestamps :null => false
end
create_table "fu_bears", :force => true do |t|
t.string :name
t.timestamps :null => false
end
end
module Called
def called(x=nil)
@called ||= []
if x
@called << x
else
@called
end
end
end
class Car < ActiveRecord::Base
extend Called
has_many :cars
after_commit :simple_after_commit
after_commit :simple_after_commit_on_create, :on => :create
after_commit :save_once, :on => :create, :if => :do_after_create_save
after_commit :simple_after_commit_on_update, :on => :update
after_commit :maybe_raise_errors
after_commit :save_open_transactions_count
after_save :trigger_rollback
attr_accessor :make_rollback, :raise_error, :do_after_create_save
def trigger_rollback
raise ActiveRecord::Rollback if make_rollback
end
def self.returning_method_with_transaction
Car.transaction do
return Car.create
end
end
attr_reader :open_transactions
private
def save_open_transactions_count
@open_transactions = ActiveRecord::Base.connection.open_transactions
end
def save_once
update_attributes(:counter => 3) unless counter == 3
self.class.called :save_once
end
def maybe_raise_errors
if raise_error
# puts "MAYBE RAISE" # just debugging, but it really does not work ...
raise "Expected error"
end
end
def simple_after_commit
self.class.called :always
end
def simple_after_commit_on_create
self.class.called :create
end
def simple_after_commit_on_update
self.class.called :update
end
end
class CarObserver < ActiveRecord::Observer
cattr_accessor :recording
cattr_accessor :callback
[:after_commit, :after_rollback].each do |action|
define_method action do |record|
return unless recording
Car.called << "observed_#{action}".to_sym
Untracked.create!
callback.call() if callback
end
end
end
Car.observers = :car_observer
Car.instantiate_observers
class Bar < ActiveRecord::Base
self.table_name = "cars"
has_many :bars, :foreign_key => :car_id
end
class MultiBar < ActiveRecord::Base
extend Called
self.table_name = "cars"
after_commit :one, :on => :create
after_commit :two, :on => :create
def one
self.class.called << :one
end
def two
self.class.called << :two
end
end
class Address < ActiveRecord::Base
has_many :people
after_commit :create_residents, :on => :create
def create_residents
if ActiveRecord::VERSION::MAJOR == 3
# stupid hack because nested after_commit is broken on rails 3 and loops
return if @create_residents
@create_residents = true
end
Person.create!(:address => self)
Person.create!(:address => self)
end
end
class Person < ActiveRecord::Base
belongs_to :address
after_commit :update_number_of_residents_on_address, :on => :create
def update_number_of_residents_on_address
address.update_attributes(:number_of_residents => address.number_of_residents + 1)
end
end
class Untracked < ActiveRecord::Base
self.table_name = "cars"
end
class FuBear < ActiveRecord::Base
extend Called
self.table_name = "fu_bears"
validates_presence_of :name
after_commit :simple_after_commit
def simple_after_commit
self.class.called :always
end
end
================================================
FILE: spec/spec_helper.rb
================================================
require 'bundler/setup'
require File.expand_path '../database', __FILE__
I18n.enforce_available_locales = false
def rails3?
ActiveRecord::VERSION::MAJOR == 3
end
def rails4?
ActiveRecord::VERSION::MAJOR >= 4
end
def rails42?
rails4? && ActiveRecord::VERSION::MINOR >= 2
end
require 'test_after_commit'
if ENV['REAL']
puts 'using real transactions'
TestAfterCommit.enabled = false
end
module ConnectionFinder
def connection
@connection ||=
if rails4?
ActiveRecord::Base.connection_handler.connection_pool_list.map(&:connection).first
else
ActiveRecord::Base.connection_handler.connection_pools.values.map(&:connection).first
end
end
end
RSpec.configure do |config|
config.include ConnectionFinder
unless ENV['REAL']
config.around do |example|
# open a transaction without using .transaction as activerecord use_transactional_fixtures does
if ActiveRecord::VERSION::MAJOR > 3
connection.begin_transaction :joinable => false
else
connection.increment_open_transactions
connection.transaction_joinable = false
connection.begin_db_transaction
end
example.call
connection.rollback_db_transaction
if ActiveRecord::VERSION::MAJOR == 3
connection.decrement_open_transactions
end
end
end
config.expect_with(:rspec) { |c| c.syntax = :should }
config.mock_with(:rspec) { |c| c.syntax = :should }
end
================================================
FILE: spec/test_after_commit_spec.rb
================================================
require 'spec_helper'
describe TestAfterCommit do
before do
CarObserver.recording = false
Car.called.clear
end
after do
TestAfterCommit.enabled = true unless ENV["REAL"]
end
it "has a VERSION" do
TestAfterCommit::VERSION.should =~ /^[\.\da-z]+$/
end
it "fires on create" do
Car.create
Car.called.should == [:create, :always]
end
it "runs callback outside of transaction" do
car = Car.create
car.open_transactions.should == ActiveRecord::Base.connection.open_transactions
end
it "works outside of transaction" do
car = described_class.with_commits(true) { Car.create }
car.destroy
end if ENV["REAL"]
it "fires on update" do
car = Car.create
Car.called.clear
car.save!
Car.called.should == [:update, :always]
end
it "fires on update_attribute" do
car = Car.create
Car.called.clear
car.update_attribute :counter, 123
Car.called.should == [:update, :always]
end
it "does not fire on rollback" do
car = Car.new
car.make_rollback = true
car.save.should == nil
Car.called.should == []
end
it "does not fire on ActiveRecord::RecordInvalid" do
lambda {
FuBear.create!
}.should raise_exception(ActiveRecord::RecordInvalid)
FuBear.called.should == []
end
it "does not fire multiple times in nested transactions" do
Car.transaction do
Car.transaction do
Car.create!
Car.called.should == []
end
Car.called.should == []
end
Car.called.should == [:create, :always]
end
it "fires when transaction block returns from method" do
Car.returning_method_with_transaction
Car.called.should == [:create, :always]
end
if rails42?
it "raises errors" do
car = Car.new
car.raise_error = true
lambda { car.save! }.should raise_error(RuntimeError)
end
else
it "does not raises errors" do
car = Car.new
car.raise_error = true
car.save!
end
end
if rails42?
context "with config.active_record.raise_in_transactional_callbacks" do
around do |test|
old = ActiveRecord::Base.raise_in_transactional_callbacks
ActiveRecord::Base.raise_in_transactional_callbacks = true
begin
test.call
ensure
ActiveRecord::Base.raise_in_transactional_callbacks = old
end
end
it "keeps working after an exception is raised" do
car = Car.new
car.raise_error = true
lambda { car.save! }.should raise_error(RuntimeError)
car = Car.new
car.save!
Car.called.should include(:always)
end
end
end
it "can do 1 save in after_commit" do
car = Car.new
car.do_after_create_save = true
car.save!
expected = if rails4?
[:save_once, :create, :always, :save_once, :always]
else
[:save_once, :create, :always, :save_once, :create, :always]
end
Car.called.should == expected
car.counter.should == 3
end
it "returns on create and on create of associations" do
Car.create!.class.should == Car
Car.create!.cars.create.class.should == Car unless rails4?
end
it "returns on create and on create of associations without after_commit" do
Bar.create!.class.should == Bar
Bar.create!.bars.create.class.should == Bar unless rails4?
end
it "calls callbacks in correct order" do
MultiBar.create!
MultiBar.called.should == [:two, :one]
end
context "Observer" do
before do
CarObserver.recording = true
end
it "should record commits" do
Car.transaction do
Car.create
end
Car.called.should == [:observed_after_commit, :create, :always]
end
it "should record rollbacks caused by ActiveRecord::Rollback" do
Car.transaction do
Car.create
raise ActiveRecord::Rollback
end
Car.called.should == [:observed_after_rollback]
end
it "should record rollbacks caused by any type of exception" do
begin
Car.transaction do
car = Car.create
raise Exception, 'simulated error'
end
rescue Exception => e
e.message.should == 'simulated error'
end
Car.called.should == [:observed_after_rollback]
end
it "should see the correct number of open transactions during callbacks" do
skip if ENV["REAL"]
begin
open_txn = nil
CarObserver.callback = proc { open_txn = Car.connection.instance_variable_get(:@test_open_transactions) }
Car.transaction do
Car.create
end
open_txn.should == 0
ensure
CarObserver.callback = nil
end
end
end
context "block behavior" do
it "does not fire if turned off" do
TestAfterCommit.enabled = false
Car.create
Car.called.should == []
end
it "always fires with when enabled by a block" do
TestAfterCommit.enabled = false
TestAfterCommit.with_commits(true) do
Car.create
Car.called.should == [:create, :always]
end
end
it "defaults to with commits" do
TestAfterCommit.with_commits do
Car.create
Car.called.should == [:create, :always]
end
end
it "does not fire with without commits" do
TestAfterCommit.with_commits(false) do
Car.create
Car.called.should == []
end
end
end unless ENV["REAL"]
context "nested after_commit" do
it 'is executed' do
skip if rails4? # infinite loop in REAL and fails in TEST and lots of noise when left as pending
@address = Address.create!
lambda {
Person.create!(:address => @address)
}.should change(@address, :number_of_residents).by(1)
# one from the line above and two from the after_commit
@address.people.count.should == 3
@address.number_of_residents.should == 3
end
end
end
if rails3? && !ENV["REAL"]
describe TestAfterCommit, "with mixed TAC enabled specs" do
before do
TestAfterCommit.enabled = false
Car.called.clear
end
context "and a test with TAC disabled" do
it "creates a record" do
Car.new.save!
Car.called.should == []
end
it "verifies that records are empty before each test 1" do
connection.instance_variable_get(:@_current_transaction_records).should be_empty
end
end
context "and a test with TAC enabled" do
before { TestAfterCommit.enabled = true }
it "creates a record and fires commit callbacks" do
Car.new.save!
Car.called.should == [:create, :always]
end
it "verifies that records are empty before each test 2" do
connection.instance_variable_get(:@_current_transaction_records).should be_empty
end
end
end
end
================================================
FILE: test_after_commit.gemspec
================================================
name = "test_after_commit"
require "./lib/#{name}/version"
Gem::Specification.new name, TestAfterCommit::VERSION do |s|
s.summary = "makes after_commit callbacks testable in Rails 3+ with transactional_fixtures"
s.authors = ["Michael Grosser"]
s.email = "michael@grosser.it"
s.homepage = "https://github.com/grosser/#{name}"
s.files = `git ls-files lib Readme.md MIT-LICENSE`.split("\n")
s.license = 'MIT'
s.required_ruby_version = '>= 2.0.0'
s.add_runtime_dependency "activerecord", [">= 3.2", "< 5.0"]
s.add_development_dependency "wwtd"
s.add_development_dependency "bump"
s.add_development_dependency "rake"
s.add_development_dependency "sqlite3"
s.add_development_dependency "rspec"
end
gitextract_de18ncmi/ ├── .travis.yml ├── Gemfile ├── MIT-LICENSE ├── Rakefile ├── Readme.md ├── gemfiles/ │ ├── 32.gemfile │ ├── 40.gemfile │ ├── 41.gemfile │ └── 42.gemfile ├── lib/ │ ├── test_after_commit/ │ │ ├── database_statements.rb │ │ ├── version.rb │ │ └── with_transaction_state.rb │ └── test_after_commit.rb ├── spec/ │ ├── database.rb │ ├── spec_helper.rb │ └── test_after_commit_spec.rb └── test_after_commit.gemspec
SYMBOL INDEX (37 symbols across 6 files)
FILE: lib/test_after_commit.rb
type TestAfterCommit (line 15) | module TestAfterCommit
function with_commits (line 20) | def with_commits(value = true)
FILE: lib/test_after_commit/database_statements.rb
type TestAfterCommit::DatabaseStatements (line 1) | module TestAfterCommit::DatabaseStatements
function transaction (line 2) | def transaction(*)
function test_commit_records (line 35) | def test_commit_records
FILE: lib/test_after_commit/version.rb
type TestAfterCommit (line 1) | module TestAfterCommit
FILE: lib/test_after_commit/with_transaction_state.rb
type TestAfterCommit (line 2) | module TestAfterCommit
type WithTransactionState (line 3) | module WithTransactionState
function sync_with_transaction_state (line 4) | def sync_with_transaction_state
FILE: spec/database.rb
type Called (line 42) | module Called
function called (line 43) | def called(x=nil)
class Car (line 53) | class Car < ActiveRecord::Base
method trigger_rollback (line 69) | def trigger_rollback
method returning_method_with_transaction (line 73) | def self.returning_method_with_transaction
method save_open_transactions_count (line 83) | def save_open_transactions_count
method save_once (line 87) | def save_once
method maybe_raise_errors (line 92) | def maybe_raise_errors
method simple_after_commit (line 99) | def simple_after_commit
method simple_after_commit_on_create (line 103) | def simple_after_commit_on_create
method simple_after_commit_on_update (line 107) | def simple_after_commit_on_update
class CarObserver (line 112) | class CarObserver < ActiveRecord::Observer
class Bar (line 129) | class Bar < ActiveRecord::Base
class MultiBar (line 134) | class MultiBar < ActiveRecord::Base
method one (line 142) | def one
method two (line 146) | def two
class Address (line 151) | class Address < ActiveRecord::Base
method create_residents (line 156) | def create_residents
class Person (line 168) | class Person < ActiveRecord::Base
method update_number_of_residents_on_address (line 173) | def update_number_of_residents_on_address
class Untracked (line 178) | class Untracked < ActiveRecord::Base
class FuBear (line 182) | class FuBear < ActiveRecord::Base
method simple_after_commit (line 190) | def simple_after_commit
FILE: spec/spec_helper.rb
function rails3? (line 5) | def rails3?
function rails4? (line 9) | def rails4?
function rails42? (line 13) | def rails42?
type ConnectionFinder (line 23) | module ConnectionFinder
function connection (line 24) | def connection
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (22K chars).
[
{
"path": ".travis.yml",
"chars": 276,
"preview": "language: ruby\nsudo: false\ncache: bundler\nbundler_args: '--path vendor/bundle'\ngemfile:\n - gemfiles/32.gemfile\n - gemf"
},
{
"path": "Gemfile",
"chars": 61,
"preview": "source \"https://rubygems.org\"\ngemspec\n\ngem 'rails-observers'\n"
},
{
"path": "MIT-LICENSE",
"chars": 1093,
"preview": "Copyright (c) 2014 Michael Grosser <michael@grosser.it>\n\nMIT License\n\nPermission is hereby granted, free of charge, to a"
},
{
"path": "Rakefile",
"chars": 163,
"preview": "require 'bundler/setup'\nrequire 'bundler/gem_tasks'\nrequire 'bump/tasks'\nrequire 'wwtd/tasks'\n\ntask :spec do\n sh \"rspec"
},
{
"path": "Readme.md",
"chars": 1923,
"preview": "Make after_commit callbacks fire in tests for Rails 3+ with transactional_fixtures = true.\n\n**Deprecation** this is no l"
},
{
"path": "gemfiles/32.gemfile",
"chars": 184,
"preview": "source \"https://rubygems.org\"\n\ngemspec :path=>\"../\"\n\ngem \"activerecord\", \"~> 3.2.18\"\ngem \"i18n\", \"~> 0.6.9\" # 0.7 does n"
},
{
"path": "gemfiles/40.gemfile",
"chars": 106,
"preview": "source \"https://rubygems.org\"\n\ngemspec :path=>\"../\"\n\ngem \"activerecord\", \"~> 4.0.6\"\ngem \"rails-observers\"\n"
},
{
"path": "gemfiles/41.gemfile",
"chars": 106,
"preview": "source \"https://rubygems.org\"\n\ngemspec :path=>\"../\"\n\ngem \"activerecord\", \"~> 4.1.2\"\ngem \"rails-observers\"\n"
},
{
"path": "gemfiles/42.gemfile",
"chars": 112,
"preview": "source \"https://rubygems.org\"\n\ngemspec :path=>\"../\"\n\ngem \"activerecord\", \"~> 4.2.0.beta1\"\ngem \"rails-observers\"\n"
},
{
"path": "lib/test_after_commit/database_statements.rb",
"chars": 1875,
"preview": "module TestAfterCommit::DatabaseStatements\n def transaction(*)\n @test_open_transactions ||= 0\n skip_emulation = A"
},
{
"path": "lib/test_after_commit/version.rb",
"chars": 47,
"preview": "module TestAfterCommit\n VERSION = '1.2.2'\nend\n"
},
{
"path": "lib/test_after_commit/with_transaction_state.rb",
"chars": 233,
"preview": "# disable parts of the sync code that starts looping\nmodule TestAfterCommit\n module WithTransactionState\n def sync_w"
},
{
"path": "lib/test_after_commit.rb",
"chars": 728,
"preview": "require 'test_after_commit/version'\n\nif ActiveRecord::VERSION::MAJOR >= 5\n raise 'after_commit testing is baked into ra"
},
{
"path": "spec/database.rb",
"chars": 4129,
"preview": "# setup database\nrequire 'active_record'\n\nif ActiveRecord::VERSION::MAJOR > 3\n require \"rails/observers/activerecord/ac"
},
{
"path": "spec/spec_helper.rb",
"chars": 1456,
"preview": "require 'bundler/setup'\nrequire File.expand_path '../database', __FILE__\nI18n.enforce_available_locales = false\n\ndef rai"
},
{
"path": "spec/test_after_commit_spec.rb",
"chars": 6819,
"preview": "require 'spec_helper'\n\ndescribe TestAfterCommit do\n before do\n CarObserver.recording = false\n Car.called.clear\n "
},
{
"path": "test_after_commit.gemspec",
"chars": 723,
"preview": "name = \"test_after_commit\"\nrequire \"./lib/#{name}/version\"\n\nGem::Specification.new name, TestAfterCommit::VERSION do |s|"
}
]
About this extraction
This page contains the full source code of the grosser/test_after_commit GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (19.6 KB), approximately 5.6k tokens, and a symbol index with 37 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.