database_rewinder 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/MIT_LICENSE +22 -0
- data/README.md +60 -0
- data/Rakefile +8 -0
- data/database_rewinder.gemspec +25 -0
- data/lib/database_rewinder.rb +77 -0
- data/lib/database_rewinder/active_record_monkey.rb +17 -0
- data/lib/database_rewinder/cleaner.rb +54 -0
- data/lib/database_rewinder/railtie.rb +12 -0
- data/spec/active_record_monkey_spec.rb +13 -0
- data/spec/config/database.yml +5 -0
- data/spec/database_rewinder_spec.rb +26 -0
- data/spec/fake_app.rb +26 -0
- data/spec/spec_helper.rb +14 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b7eb09a5bfe857d34118e354730f3f49cb4a6fb4
|
4
|
+
data.tar.gz: 4c49a5891c8585ae6896b0137f34a05e397aeb9b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aaf1352df853e3894d2cb777ebf4fd90bab61659e94577f61afce4eac41585df825fdfa22df10c5bf971b5d854e81851793a63cdc18139fe8ac377f6558684fd
|
7
|
+
data.tar.gz: 31f04525cdb310b9bfe303f38578a94749f9a61ad7d22344460401804e2c6269bd5d032b62262610160f30dca220614f687ae37387be32a759a7a18c56287300
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT_LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Akira Matsuda
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# DatabaseRewinder
|
2
|
+
|
3
|
+
database\_rewinder is a minimalist's tiny and ultra-fast database cleaner.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
* Cleans up tables via DELETE SQL. No other strategies are implemented ATM
|
8
|
+
* Supports multiple databases
|
9
|
+
* Runs extremely fast :dash:
|
10
|
+
|
11
|
+
## Why is it fast?
|
12
|
+
|
13
|
+
database\_rewinder memorizes every table name into which `INSERT` SQL was performed during each test case.
|
14
|
+
Then it executes `DELETE` SQL only against these tables when cleaning.
|
15
|
+
So, the more you have number of tables in your database, the more benefit you will get.
|
16
|
+
|
17
|
+
## Supported versions
|
18
|
+
|
19
|
+
* ActiveRecord 3.2, 4.0, 4.1
|
20
|
+
|
21
|
+
* Ruby 2.0, 2.1
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Add this line to your Gemfile's `:test` group:
|
26
|
+
|
27
|
+
gem 'database_rewinder'
|
28
|
+
|
29
|
+
And then execute:
|
30
|
+
|
31
|
+
$ bundle
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
Do `clean_all` in `before(:suite)`, and `clean` in `after(:each)`.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
RSpec.configure do |config|
|
39
|
+
config.before :suite do
|
40
|
+
DatabaseRewinder.clean_all
|
41
|
+
end
|
42
|
+
|
43
|
+
config.after :each do
|
44
|
+
DatabaseRewinder.clean
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
### Pro Tip
|
50
|
+
|
51
|
+
database\_rewinder is designed to be almost compatible with database\_cleaner.
|
52
|
+
So the following code will probably let your existing app work under database\_rewinder without making any change on your cofiguration.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
DatabaseCleaner = DatabaseRewinder
|
56
|
+
```
|
57
|
+
|
58
|
+
## Contributing
|
59
|
+
|
60
|
+
Send me your pull requests.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "database_rewinder"
|
7
|
+
spec.version = '0.0.1'
|
8
|
+
spec.authors = ["Akira Matsuda"]
|
9
|
+
spec.email = ["ronnie@dio.jp"]
|
10
|
+
spec.description = "A minimalist's tiny and ultra-fast database cleaner"
|
11
|
+
spec.summary = "A minimalist's tiny and ultra-fast database cleaner"
|
12
|
+
spec.homepage = 'https://github.com/amatsuda/database_rewinder'
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency 'rspec'
|
23
|
+
spec.add_development_dependency 'rails'
|
24
|
+
spec.add_development_dependency 'sqlite3'
|
25
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative 'database_rewinder/cleaner'
|
2
|
+
require_relative 'database_rewinder/railtie'
|
3
|
+
|
4
|
+
module DatabaseRewinder
|
5
|
+
VERSION = Gem.loaded_specs['database_rewinder'].version.to_s
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def init
|
9
|
+
@cleaners, @table_names_cache, @clean_all, @only, @except = [], {}, false
|
10
|
+
@db_config = YAML::load(ERB.new(IO.read(Rails.root.join 'config/database.yml')).result)
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_cleaner(connection_name)
|
14
|
+
config = @db_config[connection_name] or raise %Q[Database configuration named "#{connection_name}" is not configured.]
|
15
|
+
|
16
|
+
Cleaner.new(db: config['database'], connection_name: connection_name, only: @only, except: @except).tap {|c| @cleaners << c}
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](_orm, connection: nil, **)
|
20
|
+
if (cl = @cleaners.detect {|c| c.connection_name == connection})
|
21
|
+
return cl
|
22
|
+
end
|
23
|
+
|
24
|
+
create_cleaner connection
|
25
|
+
end
|
26
|
+
|
27
|
+
def all=(v)
|
28
|
+
@clean_all = v
|
29
|
+
end
|
30
|
+
|
31
|
+
def cleaners
|
32
|
+
create_cleaner 'test' if @cleaners.empty?
|
33
|
+
@cleaners
|
34
|
+
end
|
35
|
+
|
36
|
+
def record_inserted_table(connection, sql)
|
37
|
+
database = connection.instance_variable_get(:'@config')[:database]
|
38
|
+
cleaner = cleaners.detect {|c| c.db == database} or return
|
39
|
+
|
40
|
+
match = sql.match(/\AINSERT INTO [`"]?([^\s`"]+)[`"]?/)
|
41
|
+
table = match[1] if match
|
42
|
+
if table
|
43
|
+
cleaner.inserted_tables << table unless cleaner.inserted_tables.include? table
|
44
|
+
cleaner.pool ||= connection.pool
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def clean
|
49
|
+
if @clean_all
|
50
|
+
clean_all
|
51
|
+
else
|
52
|
+
cleaners.each {|c| c.clean}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def clean_all
|
57
|
+
cleaners.each {|c| c.clean_all}
|
58
|
+
end
|
59
|
+
|
60
|
+
# for database_cleaner compat
|
61
|
+
def clean_with(*args)
|
62
|
+
cleaners.each {|c| c.clean_with *args}
|
63
|
+
end
|
64
|
+
|
65
|
+
# for database_cleaner compat
|
66
|
+
def start; end
|
67
|
+
def strategy=(_strategy, only: nil, except: nil, **)
|
68
|
+
@only, @except = only, except
|
69
|
+
end
|
70
|
+
|
71
|
+
# cache AR connection.tables
|
72
|
+
def all_table_names(connection)
|
73
|
+
db = connection.instance_variable_get(:'@config')[:database]
|
74
|
+
@table_names_cache[db] ||= connection.tables
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DatabaseRewinder
|
2
|
+
module InsertRecorder
|
3
|
+
def execute(sql, *)
|
4
|
+
DatabaseRewinder.record_inserted_table self, sql
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
def exec_query(sql, *)
|
9
|
+
DatabaseRewinder.record_inserted_table self, sql
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
::ActiveRecord::ConnectionAdapters::SQLite3Adapter.send :prepend, DatabaseRewinder::InsertRecorder if defined? ::ActiveRecord::ConnectionAdapters::SQLite3Adapter
|
16
|
+
::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :prepend, DatabaseRewinder::InsertRecorder if defined? ::ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
|
17
|
+
::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.send :prepend, DatabaseRewinder::InsertRecorder if defined? ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module DatabaseRewinder
|
2
|
+
class Cleaner
|
3
|
+
attr_accessor :db, :connection_name, :inserted_tables, :pool
|
4
|
+
|
5
|
+
def initialize(db: nil, connection_name: nil, only: nil, except: nil)
|
6
|
+
@db, @connection_name, @only, @except = db, connection_name, Array(only), Array(except)
|
7
|
+
reset
|
8
|
+
end
|
9
|
+
|
10
|
+
def clean
|
11
|
+
return unless pool
|
12
|
+
return if inserted_tables.empty?
|
13
|
+
|
14
|
+
delete_all (ar_conn = pool.connection), DatabaseRewinder.all_table_names(ar_conn) & inserted_tables
|
15
|
+
reset
|
16
|
+
end
|
17
|
+
|
18
|
+
def clean_all
|
19
|
+
return unless pool
|
20
|
+
|
21
|
+
delete_all (ar_conn = pool.connection), DatabaseRewinder.all_table_names(ar_conn)
|
22
|
+
reset
|
23
|
+
end
|
24
|
+
|
25
|
+
def clean_with(_strategy, only: nil, except: nil, **)
|
26
|
+
@only += Array(only) unless only.blank?
|
27
|
+
@except += Array(except) unless except.blank?
|
28
|
+
clean_all
|
29
|
+
end
|
30
|
+
|
31
|
+
# for database_cleaner compat
|
32
|
+
def strategy=(_strategy, only: nil, except: nil, **)
|
33
|
+
@only += Array(only) unless only.blank?
|
34
|
+
@except += Array(except) unless except.blank?
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def delete_all(ar_conn, tables)
|
39
|
+
tables = tables & @only if @only.any?
|
40
|
+
tables -= @except if @except.any?
|
41
|
+
return if tables.empty?
|
42
|
+
|
43
|
+
ar_conn.disable_referential_integrity do
|
44
|
+
tables.each do |table_name|
|
45
|
+
ar_conn.execute "DELETE FROM #{ar_conn.quote_table_name(table_name)};"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def reset
|
51
|
+
@inserted_tables = []
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module DatabaseRewinder
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
initializer 'database_rewinder', after: 'active_record.initialize_database' do
|
6
|
+
ActiveSupport.on_load :active_record do
|
7
|
+
DatabaseRewinder.init
|
8
|
+
require_relative 'active_record_monkey'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'DatabaseRewinder::InsertRecorder#execute' do
|
4
|
+
before do
|
5
|
+
DatabaseRewinder.init
|
6
|
+
Foo.create! name: 'foo1'
|
7
|
+
Bar.create! name: 'bar1'
|
8
|
+
DatabaseRewinder.cleaners
|
9
|
+
end
|
10
|
+
subject { DatabaseRewinder.instance_variable_get(:'@cleaners').detect {|c| c.db == ':memory:'} }
|
11
|
+
its(:inserted_tables) { should == %w(foos bars) }
|
12
|
+
its(:pool) { should be }
|
13
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DatabaseRewinder do
|
4
|
+
before { DatabaseRewinder.init }
|
5
|
+
|
6
|
+
describe '.[]' do
|
7
|
+
before do
|
8
|
+
DatabaseRewinder.instance_variable_set :'@db_config', {'foo' => {'adapter' => 'sqlite3', 'database' => ':memory:'}}
|
9
|
+
DatabaseRewinder[:aho, connection: 'foo']
|
10
|
+
end
|
11
|
+
subject { DatabaseRewinder.instance_variable_get(:'@cleaners').map {|c| c.connection_name} }
|
12
|
+
it { should == ['foo'] }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.clean' do
|
16
|
+
before do
|
17
|
+
Foo.create! name: 'foo1'
|
18
|
+
Bar.create! name: 'bar1'
|
19
|
+
DatabaseRewinder.clean
|
20
|
+
end
|
21
|
+
it 'should clean' do
|
22
|
+
Foo.count.should == 0
|
23
|
+
Bar.count.should == 0
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/fake_app.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_record/railtie'
|
2
|
+
|
3
|
+
module DatabaseRewinderTestApp
|
4
|
+
Application = Class.new(Rails::Application) do
|
5
|
+
# Rais.root
|
6
|
+
config.root = __dir__
|
7
|
+
|
8
|
+
config.eager_load = false
|
9
|
+
config.active_support.deprecation = :log
|
10
|
+
end.initialize!
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
# models
|
15
|
+
class Foo < ActiveRecord::Base; end
|
16
|
+
class Bar < ActiveRecord::Base; end
|
17
|
+
class Baz < ActiveRecord::Base; end
|
18
|
+
|
19
|
+
# migrations
|
20
|
+
class CreateAllTables < ActiveRecord::Migration
|
21
|
+
def self.up
|
22
|
+
create_table(:foos) {|t| t.string :name }
|
23
|
+
create_table(:bars) {|t| t.string :name }
|
24
|
+
create_table(:bazs) {|t| t.string :name }
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
ENV['RAILS_ENV'] ||= 'test'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.join(__dir__, '..', 'lib'))
|
4
|
+
$LOAD_PATH.unshift(__dir__)
|
5
|
+
|
6
|
+
require 'rails'
|
7
|
+
require 'database_rewinder'
|
8
|
+
require 'fake_app'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.before :all do
|
12
|
+
CreateAllTables.up unless ActiveRecord::Base.connection.table_exists? 'foos'
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: database_rewinder
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Akira Matsuda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: A minimalist's tiny and ultra-fast database cleaner
|
84
|
+
email:
|
85
|
+
- ronnie@dio.jp
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- Gemfile
|
92
|
+
- MIT_LICENSE
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- database_rewinder.gemspec
|
96
|
+
- lib/database_rewinder.rb
|
97
|
+
- lib/database_rewinder/active_record_monkey.rb
|
98
|
+
- lib/database_rewinder/cleaner.rb
|
99
|
+
- lib/database_rewinder/railtie.rb
|
100
|
+
- spec/active_record_monkey_spec.rb
|
101
|
+
- spec/config/database.yml
|
102
|
+
- spec/database_rewinder_spec.rb
|
103
|
+
- spec/fake_app.rb
|
104
|
+
- spec/spec_helper.rb
|
105
|
+
homepage: https://github.com/amatsuda/database_rewinder
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.0.3
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: A minimalist's tiny and ultra-fast database cleaner
|
129
|
+
test_files:
|
130
|
+
- spec/active_record_monkey_spec.rb
|
131
|
+
- spec/config/database.yml
|
132
|
+
- spec/database_rewinder_spec.rb
|
133
|
+
- spec/fake_app.rb
|
134
|
+
- spec/spec_helper.rb
|