database_cleaner-core 2.0.0.beta → 2.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/ADAPTERS.md +126 -0
- data/Gemfile +7 -0
- data/History.rdoc +52 -1
- data/README.markdown +9 -10
- data/Rakefile +3 -1
- data/database_cleaner-core.gemspec +6 -3
- data/database_cleaner.gemspec +6 -2
- data/lib/database_cleaner/{base.rb → cleaner.rb} +36 -13
- data/lib/database_cleaner/cleaners.rb +51 -0
- data/lib/database_cleaner/core.rb +5 -10
- data/lib/database_cleaner/null_strategy.rb +1 -1
- data/lib/database_cleaner/spec/database_helper.rb +9 -1
- data/lib/database_cleaner/spec/shared_examples.rb +3 -8
- data/lib/database_cleaner/strategy.rb +36 -0
- data/lib/database_cleaner/version.rb +1 -1
- metadata +62 -7
- data/lib/database_cleaner/configuration.rb +0 -86
- data/lib/database_cleaner/generic/base.rb +0 -29
- data/lib/database_cleaner/generic/transaction.rb +0 -11
- data/lib/database_cleaner/generic/truncation.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eacd8a1e863364bb678724f33c44ba361e1fbdc77066da69b4b92794e3528c14
|
4
|
+
data.tar.gz: 978fd0a42dd410ee1bb8282fdd29654582a88afe1a6709b4b23fa33c418ff0bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0eb27aff631629df80bcf9234c8fd923f8946727592688372233c101f9ae2c839b00d74c12dd3c847047d4fab95694a74d492378cc73aec1bb8cf55a5704fc04
|
7
|
+
data.tar.gz: aeb081d591c2619f37575b6b4e714cac728c0de01de73de416ecc641782e3ccf3a1b7d1abdf61a19983258cf95b47e719409154747a31a456ee5a6e85158567f
|
data/.travis.yml
CHANGED
data/ADAPTERS.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# WORK IN PROGRESS - PLEASE DO NOT FOLLOW THESE INSTRUCTIONS UNTIL v2.0.0 FINAL IS RELEASED!
|
2
|
+
|
3
|
+
## How to add a new adapter
|
4
|
+
|
5
|
+
_Note the following tutorial is for database_cleaner version 2 and above_
|
6
|
+
|
7
|
+
Every adapter is a separate gem, the first step in the creation of an adapter is to create a new gem.
|
8
|
+
|
9
|
+
### Naming
|
10
|
+
Please follow the [Rubygems convention for gem naming](https://guides.rubygems.org/name-your-gem/). The namespace you will be working within is `DatabaseCleaner::Namespace` where Namespace is the name of the ORM you are creation an adapter for.
|
11
|
+
For example, `database_cleaner-active_record` provides `DatabaseCleaner::ActiveRecord`, and `database_cleaner-redis` provides `DatabaseCleaner::Redis`, etc.
|
12
|
+
|
13
|
+
### Bootstrapping a gem
|
14
|
+
We will use `bundle` to bootstrap the new gem. This will produce all the initial files needed.
|
15
|
+
|
16
|
+
```
|
17
|
+
bundle gem database_cleaner-orm_name
|
18
|
+
```
|
19
|
+
#### Modifying .gemspec
|
20
|
+
You need to add a couple of dependecies to `.gemspec`:
|
21
|
+
* `database_cleaner-core`
|
22
|
+
* Adapter you're creating this gem for
|
23
|
+
|
24
|
+
```
|
25
|
+
spec.add_dependency "database_cleaner-core"
|
26
|
+
spec.add_dependency "orm_name", "some version if required"
|
27
|
+
```
|
28
|
+
|
29
|
+
####
|
30
|
+
|
31
|
+
### File structure
|
32
|
+
|
33
|
+
Inside the `lib/database_cleaner/orm_name` directory, you will need to create a few files:
|
34
|
+
|
35
|
+
* Separate files for each strategy you have
|
36
|
+
|
37
|
+
The file structure you end up with will look something like this
|
38
|
+
|
39
|
+
```
|
40
|
+
\-lib
|
41
|
+
\-database_cleaner
|
42
|
+
\- orm_name
|
43
|
+
\- truncation.rb
|
44
|
+
\- deletion.rb
|
45
|
+
\- transaction.rb
|
46
|
+
\- version.rb
|
47
|
+
\- orm_name.rb
|
48
|
+
```
|
49
|
+
|
50
|
+
#### orm_name.rb
|
51
|
+
|
52
|
+
File `orm_name.rb` **must** do the following:
|
53
|
+
* require `database_cleaner-core`
|
54
|
+
* require all the strategies
|
55
|
+
* configure `DatabaseCleaner` with the default strategy for the ORM.
|
56
|
+
|
57
|
+
So, in the end you will end up with a file that might look something like this:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# lib/database_cleaner/orm_name.rb
|
61
|
+
|
62
|
+
require 'database_cleaner/orm_name/version'
|
63
|
+
require 'database_cleaner/core'
|
64
|
+
require 'database_cleaner/orm_name/transaction'
|
65
|
+
require 'database_cleaner/orm_name/truncation'
|
66
|
+
require 'database_cleaner/orm_name/deletion'
|
67
|
+
|
68
|
+
DatabaseCleaner[:orm_name].strategy = :transaction
|
69
|
+
```
|
70
|
+
|
71
|
+
### Strategy classes
|
72
|
+
|
73
|
+
Each strategy class **must** inherit from `DatabaseCleaner::Strategy`.
|
74
|
+
|
75
|
+
Each strategy **must** have the following instance methods:
|
76
|
+
* `#clean` -- where the cleaning happens
|
77
|
+
|
78
|
+
Optionally, depending on how your strategy works you may also need to define
|
79
|
+
* `#start` -- if your strategy is transactional, this is where you would start the database transaction that `#clean` later rolls back.
|
80
|
+
|
81
|
+
Given that we're creating a strategy for truncation, you may end up with something like the following class:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
# lib/database_cleaner/orm_name/truncation.rb
|
85
|
+
|
86
|
+
require 'database_cleaner/strategy'
|
87
|
+
require 'orm'
|
88
|
+
|
89
|
+
module DatabaseCleaner
|
90
|
+
module OrmName
|
91
|
+
class Truncation < Strategy
|
92
|
+
def clean
|
93
|
+
# actual database cleaning code goes here
|
94
|
+
ORM.truncate_all_tables!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
That's about it for the code needed to create your own adapter!
|
102
|
+
|
103
|
+
### Testing
|
104
|
+
|
105
|
+
To make sure that your new adapter adheres to the Database Cleaner API, database_cleaner-core provides an RSpec shared example. This shared example only checks to make sure all the right methods exist. You will still want to write tests to verify that the cleaning actually works as you expect!
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
# spec/database_cleaner/orm_name_spec.rb
|
109
|
+
|
110
|
+
require 'database_cleaner/orm_name'
|
111
|
+
require 'database_cleaner/spec'
|
112
|
+
|
113
|
+
RSpec.describe DatabaseCleaner::OrmName do
|
114
|
+
it_should_behave_like "a database_cleaner adapter"
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
### What's next
|
119
|
+
|
120
|
+
Now you should be all set up with your very own database_cleaner ORM adapter!
|
121
|
+
Also, don't forget to take a look at the already created adapters, if you encounter any problems.
|
122
|
+
|
123
|
+
When you are done with your adapter gem, only a few things left to do
|
124
|
+
* Create a repository with your code
|
125
|
+
* Push code to rubygems
|
126
|
+
* Open a PR to add your adapter to the [list](https://github.com/DatabaseCleaner/database_cleaner#list-of-adapters)
|
data/Gemfile
CHANGED
@@ -3,3 +3,10 @@ source "https://rubygems.org"
|
|
3
3
|
gemspec name: "database_cleaner-core"
|
4
4
|
|
5
5
|
gem "byebug"
|
6
|
+
gem "database_cleaner-active_record", git: "https://github.com/DatabaseCleaner/database_cleaner-active_record"
|
7
|
+
gem "database_cleaner-redis", git: "https://github.com/DatabaseCleaner/database_cleaner-redis"
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem "simplecov", require: false
|
11
|
+
gem "codecov", require: false
|
12
|
+
end
|
data/History.rdoc
CHANGED
@@ -1,4 +1,55 @@
|
|
1
|
-
==
|
1
|
+
== 2.0.0.beta2 2020-05-30
|
2
|
+
|
3
|
+
=== Features
|
4
|
+
* New API for ORM Adapter gems: https://github.com/DatabaseCleaner/database_cleaner/pull/644
|
5
|
+
|
6
|
+
=== Breaking changes
|
7
|
+
* Rename :connection configuration option to :db for consistency: https://github.com/DatabaseCleaner/database_cleaner/pull/650
|
8
|
+
* Remove all #orm= setter methods: https://github.com/DatabaseCleaner/database_cleaner/pull/643/files
|
9
|
+
* drop support for Ruby 2.4 which is EOL as of 2020-03-31: https://github.com/DatabaseCleaner/database_cleaner/pull/635
|
10
|
+
|
11
|
+
== 2.0.0.beta 2020-04-05
|
12
|
+
|
13
|
+
=== Breaking changes
|
14
|
+
* Replace old shared RSpec examples with new "database_cleaner adapter" example: https://github.com/DatabaseCleaner/database_cleaner/pull/629
|
15
|
+
* split gem into database_cleaner-core and database_cleaner metagem.
|
16
|
+
* Support Ruby versions 2.4, 2.5, 2.6, and 2.7, and drop support for older Rubies.
|
17
|
+
* remove all deprecated code and get the specs passing again.
|
18
|
+
* Split off all adapter gems into their own repos: https://github.com/DatabaseCleaner/database_cleaner/pull/620
|
19
|
+
|
20
|
+
== 1.99.0.beta 2020-05-30
|
21
|
+
|
22
|
+
== Changes
|
23
|
+
* Remove unnecessary dependency on database_cleaner-mongo from database_cleaner-mongoid: @botandrose
|
24
|
+
* Enable the :cache_tables option for the mongo truncation strategy, and default to true: https://github.com/DatabaseCleaner/database_cleaner/pull/646"
|
25
|
+
* Introduce deletion aliases for truncation strategies for mongo, mongoid, and redis adapters. https://github.com/DatabaseCleaner/database_cleaner/pull/654
|
26
|
+
* Add new :db orm configuration key, for consistency with #db and #db=. https://github.com/DatabaseCleaner/database_cleaner/pull/649
|
27
|
+
|
28
|
+
== Deprecations
|
29
|
+
* Deprecate all #orm= setter methods: https://github.com/DatabaseCleaner/database_cleaner/pull/643
|
30
|
+
* Deprecate non-functional :reset_ids option in ActiveRecord truncation strategy: https://github.com/DatabaseCleaner/database_cleaner/issues/559
|
31
|
+
* Deprecate mongo truncation's `:cache_tables => true` option in favor of `false`, to prep for caching removal in v2.0: https://github.com/DatabaseCleaner/database_cleaner/pull/646"
|
32
|
+
* Deprecate redis truncation's #url method in favor of #db: @botandrose
|
33
|
+
* Deprecate mongo, mongoid, and redis truncation strategies in favor of deletion. https://github.com/DatabaseCleaner/database_cleaner/pull/654
|
34
|
+
* Deprecate :connection and :model configuration options in favor of :db for consistency: https://github.com/DatabaseCleaner/database_cleaner/pull/650
|
35
|
+
|
36
|
+
== Bugfixes
|
37
|
+
* Fix deprecation warning about `DatabaseCleaner.connections` to recommend a better alternative: https://github.com/DatabaseCleaner/database_cleaner/pull/656
|
38
|
+
|
39
|
+
== 1.8.5 2020-05-04
|
40
|
+
|
41
|
+
=== Bug Fixes
|
42
|
+
* Fix :mongo strategy: https://github.com/DatabaseCleaner/database_cleaner/pull/645
|
43
|
+
|
44
|
+
== 1.8.4 2020-04-02
|
45
|
+
|
46
|
+
=== Bug Fixes
|
47
|
+
* Fix false positive deprecation warnings on Windows: https://github.com/DatabaseCleaner/database_cleaner/pull/633
|
48
|
+
|
49
|
+
== 1.8.3 2020-02-18
|
50
|
+
|
51
|
+
=== Bug Fixes
|
52
|
+
* Fix performance issue of DatabaseCleaner::Base#orm_module: https://github.com/DatabaseCleaner/database_cleaner/pull/625
|
2
53
|
|
3
54
|
== 1.8.2 2020-02-01
|
4
55
|
|
data/README.markdown
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
**If you're viewing this at https://github.com/DatabaseCleaner/database_cleaner,
|
2
2
|
you're reading the documentation for the `master` branch.
|
3
3
|
[View documentation for the latest release
|
4
|
-
(1.8.
|
4
|
+
(1.8.5).](https://github.com/DatabaseCleaner/database_cleaner/blob/v1.8.5/README.markdown)**
|
5
5
|
|
6
6
|
# Database Cleaner
|
7
7
|
|
8
8
|
[![Build Status](https://travis-ci.org/DatabaseCleaner/database_cleaner.svg?branch=master)](https://travis-ci.org/DatabaseCleaner/database_cleaner)
|
9
9
|
[![Code Climate](https://codeclimate.com/github/DatabaseCleaner/database_cleaner/badges/gpa.svg)](https://codeclimate.com/github/DatabaseCleaner/database_cleaner)
|
10
|
+
[![codecov](https://codecov.io/gh/DatabaseCleaner/database_cleaner/branch/master/graph/badge.svg)](https://codecov.io/gh/DatabaseCleaner/database_cleaner)
|
10
11
|
![Gem Version](https://badge.fury.io/rb/database_cleaner.svg)
|
11
12
|
[![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=database_cleaner&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=database_cleaner&package-manager=bundler&version-scheme=semver)
|
12
13
|
|
@@ -51,21 +52,19 @@ MongoDB
|
|
51
52
|
Redis
|
52
53
|
* [database_cleaner-redis](https://github.com/DatabaseCleaner/database_cleaner-redis)
|
53
54
|
|
54
|
-
Neo4j
|
55
|
-
* [database_cleaner-neo4j](https://github.com/DatabaseCleaner/database_cleaner-neo4j)
|
56
|
-
|
57
55
|
More details on available configuration options can be found in the README for the specific adapter gem that you're using.
|
58
56
|
|
59
57
|
For support or to discuss development please use the [Google Group](https://groups.google.com/group/database_cleaner).
|
60
58
|
|
61
59
|
### Discontinued adapters
|
62
60
|
|
63
|
-
The following adapters have been discontinued
|
61
|
+
The following adapters have been discontinued. Please let us know on the [Google Group](https://groups.google.com/group/database_cleaner) if you think one of these should be resurrected!
|
64
62
|
|
65
63
|
* [database_cleaner-data_mapper](https://github.com/DatabaseCleaner/database_cleaner-data_mapper)
|
66
64
|
* [database_cleaner-couch_potato](https://github.com/DatabaseCleaner/database_cleaner-couch_potato)
|
67
65
|
* [database_cleaner-mongo_mapper](https://github.com/DatabaseCleaner/database_cleaner-mongo_mapper)
|
68
66
|
* [database_cleaner-moped](https://github.com/DatabaseCleaner/database_cleaner-moped)
|
67
|
+
* [database_cleaner-neo4j](https://github.com/DatabaseCleaner/database_cleaner-neo4j)
|
69
68
|
|
70
69
|
## How to use
|
71
70
|
|
@@ -295,7 +294,7 @@ For more examples see the section ["Why?"](#why).
|
|
295
294
|
|
296
295
|
Sometimes you need to use multiple ORMs in your application.
|
297
296
|
|
298
|
-
You can use DatabaseCleaner to clean multiple ORMs, and multiple
|
297
|
+
You can use DatabaseCleaner to clean multiple ORMs, and multiple databases for those ORMs.
|
299
298
|
|
300
299
|
```ruby
|
301
300
|
require 'database_cleaner/active_record'
|
@@ -305,14 +304,14 @@ require 'database_cleaner/mongo_mapper'
|
|
305
304
|
DatabaseCleaner[:active_record].strategy = :transaction
|
306
305
|
DatabaseCleaner[:mongo_mapper].strategy = :truncation
|
307
306
|
|
308
|
-
# How to specify particular
|
309
|
-
DatabaseCleaner[:active_record, { :
|
307
|
+
# How to specify particular databases
|
308
|
+
DatabaseCleaner[:active_record, { db: :two }]
|
310
309
|
|
311
310
|
# You may also pass in the model directly:
|
312
|
-
DatabaseCleaner[:active_record, { :
|
311
|
+
DatabaseCleaner[:active_record, { db: ModelWithDifferentConnection }]
|
313
312
|
```
|
314
313
|
|
315
|
-
Usage beyond that remains the same with `DatabaseCleaner.start` calling any setup on the different configured
|
314
|
+
Usage beyond that remains the same with `DatabaseCleaner.start` calling any setup on the different configured databases, and `DatabaseCleaner.clean` executing afterwards.
|
316
315
|
|
317
316
|
## Why?
|
318
317
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require "database_cleaner/version"
|
1
|
+
require_relative "./lib/database_cleaner/version"
|
4
2
|
|
5
3
|
Gem::Specification.new do |spec|
|
6
4
|
spec.name = "database_cleaner-core"
|
@@ -25,5 +23,10 @@ Gem::Specification.new do |spec|
|
|
25
23
|
spec.add_development_dependency 'guard-rspec'
|
26
24
|
spec.add_development_dependency "listen"
|
27
25
|
spec.add_development_dependency "rspec"
|
26
|
+
|
28
27
|
spec.add_development_dependency "cucumber"
|
28
|
+
spec.add_development_dependency "activesupport"
|
29
|
+
spec.add_development_dependency "database_cleaner-active_record"
|
30
|
+
spec.add_development_dependency "sqlite3"
|
31
|
+
spec.add_development_dependency "database_cleaner-redis"
|
29
32
|
end
|
data/database_cleaner.gemspec
CHANGED
@@ -2,7 +2,9 @@ require_relative "./lib/database_cleaner/version"
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "database_cleaner"
|
5
|
-
|
5
|
+
# FIXME temporarily hardcode to different version since core is at 2.0.0.beta2, but this gem only is at 2.0.0.beta
|
6
|
+
# spec.version = DatabaseCleaner::VERSION
|
7
|
+
spec.version = "2.0.0.beta"
|
6
8
|
spec.authors = ["Ben Mabey", "Ernesto Tagwerker", "Micah Geisel"]
|
7
9
|
spec.email = ["ernesto@ombulabs.com"]
|
8
10
|
|
@@ -11,8 +13,10 @@ Gem::Specification.new do |spec|
|
|
11
13
|
spec.homepage = "https://github.com/DatabaseCleaner/database_cleaner"
|
12
14
|
spec.license = "MIT"
|
13
15
|
|
16
|
+
spec.metadata["changelog_uri"] = "https://github.com/DatabaseCleaner/database_cleaner/blob/master/History.rdoc"
|
17
|
+
|
14
18
|
spec.files = ["lib/database_cleaner.rb"]
|
15
19
|
spec.require_paths = ["lib"]
|
16
20
|
|
17
|
-
spec.add_dependency "database_cleaner-active_record"
|
21
|
+
spec.add_dependency "database_cleaner-active_record", "~>2.0.0.beta2"
|
18
22
|
end
|
@@ -1,22 +1,38 @@
|
|
1
|
-
require 'database_cleaner/deprecation'
|
2
1
|
require 'database_cleaner/null_strategy'
|
3
2
|
require 'database_cleaner/safeguard'
|
3
|
+
require 'database_cleaner/strategy'
|
4
4
|
require 'forwardable'
|
5
5
|
|
6
6
|
module DatabaseCleaner
|
7
|
-
class
|
7
|
+
class UnknownStrategySpecified < ArgumentError; end
|
8
|
+
|
9
|
+
class Cleaner
|
10
|
+
def self.available_strategies(orm_module)
|
11
|
+
# introspect publically available constants for descendents of Strategy to get list of strategies
|
12
|
+
# ignore classes named Base, because its a common name for a shared base class that adds ORM access stuff to Strategy before being inherited by final concrete class
|
13
|
+
# if you're writing an adapter and this method is falsely returning an internal constant that isn't a valid strategy, consider making it private with Module#private_constant.
|
14
|
+
orm_module.constants.select do |constant_name|
|
15
|
+
ancestors = orm_module.const_get(constant_name).ancestors rescue []
|
16
|
+
ancestors.include?(DatabaseCleaner::Strategy)
|
17
|
+
end.map do |constant_name|
|
18
|
+
underscore(constant_name).to_sym
|
19
|
+
end - [:base]
|
20
|
+
end
|
21
|
+
|
8
22
|
include Comparable
|
9
23
|
|
10
24
|
def <=>(other)
|
11
25
|
[orm, db] <=> [other.orm, other.db]
|
12
26
|
end
|
13
27
|
|
14
|
-
def initialize(orm
|
15
|
-
|
16
|
-
self.db =
|
28
|
+
def initialize(orm, db: nil)
|
29
|
+
@orm = orm
|
30
|
+
self.db = db
|
17
31
|
Safeguard.new.run
|
18
32
|
end
|
19
33
|
|
34
|
+
attr_reader :orm
|
35
|
+
|
20
36
|
def db=(desired_db)
|
21
37
|
@db = self.strategy_db = desired_db
|
22
38
|
end
|
@@ -42,13 +58,6 @@ module DatabaseCleaner
|
|
42
58
|
@strategy ||= NullStrategy.new
|
43
59
|
end
|
44
60
|
|
45
|
-
attr_reader :orm
|
46
|
-
|
47
|
-
def orm= orm
|
48
|
-
raise ArgumentError if orm.nil?
|
49
|
-
@orm = orm.to_sym
|
50
|
-
end
|
51
|
-
|
52
61
|
extend Forwardable
|
53
62
|
delegate [:start, :clean, :cleaning] => :strategy
|
54
63
|
|
@@ -82,7 +91,8 @@ module DatabaseCleaner
|
|
82
91
|
strategy_module_name = strategy.to_s.capitalize
|
83
92
|
orm_module.const_get(strategy_module_name)
|
84
93
|
rescue NameError
|
85
|
-
|
94
|
+
available_strategies = self.class.available_strategies(orm_module)
|
95
|
+
raise UnknownStrategySpecified, "The '#{strategy}' strategy does not exist for the #{orm} ORM! Available strategies: #{available_strategies.join(', ')}"
|
86
96
|
end
|
87
97
|
|
88
98
|
def orm_module
|
@@ -90,6 +100,8 @@ module DatabaseCleaner
|
|
90
100
|
DatabaseCleaner.const_get(orm_module_name)
|
91
101
|
end
|
92
102
|
|
103
|
+
# copied from ActiveSupport to avoid adding it as a dependency
|
104
|
+
|
93
105
|
def camelize(term)
|
94
106
|
string = term.to_s
|
95
107
|
string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
|
@@ -97,5 +109,16 @@ module DatabaseCleaner
|
|
97
109
|
string.gsub!("/", "::")
|
98
110
|
string
|
99
111
|
end
|
112
|
+
|
113
|
+
def self.underscore(camel_cased_word)
|
114
|
+
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
115
|
+
word = camel_cased_word.to_s.gsub("::", "/")
|
116
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
117
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
118
|
+
word.tr!("-", "_")
|
119
|
+
word.downcase!
|
120
|
+
word
|
121
|
+
end
|
122
|
+
private_class_method :underscore
|
100
123
|
end
|
101
124
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'database_cleaner/cleaner'
|
2
|
+
|
3
|
+
module DatabaseCleaner
|
4
|
+
class Cleaners < Hash
|
5
|
+
def initialize hash={}
|
6
|
+
super.replace(hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
# FIXME this method conflates creation with lookup... both a command and a query. yuck.
|
10
|
+
def [](orm, opts = {})
|
11
|
+
raise ArgumentError if orm.nil?
|
12
|
+
fetch([orm, opts]) { add_cleaner(orm, opts) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def strategy=(strategy)
|
16
|
+
values.each { |cleaner| cleaner.strategy = strategy }
|
17
|
+
remove_duplicates
|
18
|
+
end
|
19
|
+
|
20
|
+
def start
|
21
|
+
values.each { |cleaner| cleaner.start }
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean
|
25
|
+
values.each { |cleaner| cleaner.clean }
|
26
|
+
end
|
27
|
+
|
28
|
+
def cleaning(&inner_block)
|
29
|
+
values.inject(inner_block) do |curr_block, cleaner|
|
30
|
+
proc { cleaner.cleaning(&curr_block) }
|
31
|
+
end.call
|
32
|
+
end
|
33
|
+
|
34
|
+
def clean_with(*args)
|
35
|
+
values.each { |cleaner| cleaner.clean_with(*args) }
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def add_cleaner(orm, opts = {})
|
41
|
+
self[[orm, opts]] = Cleaner.new(orm, opts)
|
42
|
+
end
|
43
|
+
|
44
|
+
def remove_duplicates
|
45
|
+
replace(reduce(Cleaners.new) do |cleaners, (key, value)|
|
46
|
+
cleaners[key] = value unless cleaners.values.include?(value)
|
47
|
+
cleaners
|
48
|
+
end)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'database_cleaner/version'
|
2
|
-
require 'database_cleaner/
|
3
|
-
require 'database_cleaner/deprecation'
|
2
|
+
require 'database_cleaner/cleaners'
|
4
3
|
require 'forwardable'
|
5
4
|
|
6
5
|
module DatabaseCleaner
|
@@ -8,22 +7,18 @@ module DatabaseCleaner
|
|
8
7
|
extend Forwardable
|
9
8
|
delegate [
|
10
9
|
:[],
|
11
|
-
:cleaners,
|
12
|
-
:cleaners=,
|
13
10
|
:strategy=,
|
14
|
-
:orm=,
|
15
11
|
:start,
|
16
12
|
:clean,
|
17
13
|
:clean_with,
|
18
14
|
:cleaning,
|
19
|
-
] => :
|
15
|
+
] => :cleaners
|
20
16
|
|
21
17
|
attr_accessor :allow_remote_database_url, :allow_production, :url_whitelist
|
22
18
|
|
23
|
-
|
24
|
-
|
25
|
-
def configuration
|
26
|
-
@configuration ||= Configuration.new
|
19
|
+
def cleaners
|
20
|
+
@cleaners ||= Cleaners.new
|
27
21
|
end
|
22
|
+
attr_writer :cleaners
|
28
23
|
end
|
29
24
|
end
|
@@ -40,9 +40,17 @@ module DatabaseCleaner
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def load_schema
|
43
|
+
id_column = case db
|
44
|
+
when :sqlite3
|
45
|
+
"id INTEGER PRIMARY KEY AUTOINCREMENT"
|
46
|
+
when :mysql2
|
47
|
+
"id INTEGER PRIMARY KEY AUTO_INCREMENT"
|
48
|
+
when :postgres
|
49
|
+
"id SERIAL PRIMARY KEY"
|
50
|
+
end
|
43
51
|
connection.execute <<-SQL
|
44
52
|
CREATE TABLE IF NOT EXISTS users (
|
45
|
-
|
53
|
+
#{id_column},
|
46
54
|
name INTEGER
|
47
55
|
);
|
48
56
|
SQL
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "database_cleaner/cleaner"
|
2
|
+
|
1
3
|
RSpec.shared_examples_for "a database_cleaner strategy" do
|
2
4
|
it { is_expected.to respond_to(:db) }
|
3
5
|
it { is_expected.to respond_to(:db=) }
|
@@ -7,15 +9,8 @@ RSpec.shared_examples_for "a database_cleaner strategy" do
|
|
7
9
|
end
|
8
10
|
|
9
11
|
RSpec.shared_examples_for "a database_cleaner adapter" do
|
10
|
-
it { expect(described_class).to respond_to(:available_strategies) }
|
11
|
-
it { expect(described_class).to respond_to(:default_strategy) }
|
12
|
-
|
13
|
-
it 'default_strategy should be part of available_strategies' do
|
14
|
-
expect(described_class.available_strategies).to include(described_class.default_strategy)
|
15
|
-
end
|
16
|
-
|
17
12
|
describe 'all strategies should adhere to a database_cleaner strategy interface' do
|
18
|
-
|
13
|
+
DatabaseCleaner::Cleaner.available_strategies(described_class).each do |strategy|
|
19
14
|
subject { described_class.const_get(strategy.to_s.capitalize).new }
|
20
15
|
|
21
16
|
it_behaves_like 'a database_cleaner strategy'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Abstract strategy class for orm adapter gems to subclass
|
2
|
+
|
3
|
+
module DatabaseCleaner
|
4
|
+
class Strategy
|
5
|
+
# Override this method if the strategy accepts options
|
6
|
+
def initialize(options=nil)
|
7
|
+
if options
|
8
|
+
name = self.class.name.sub("DatabaseCleaner::","").sub("::"," ") # e.g. "ActiveRecord Transaction"
|
9
|
+
raise ArgumentError, "No options are available for the #{name} strategy."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def db
|
14
|
+
@db ||= :default
|
15
|
+
end
|
16
|
+
attr_writer :db
|
17
|
+
|
18
|
+
# Override this method to start a database transaction if the strategy uses them
|
19
|
+
def start
|
20
|
+
end
|
21
|
+
|
22
|
+
# Override this method with the actual cleaning procedure. Its the only mandatory method implementation.
|
23
|
+
def clean
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
def cleaning(&block)
|
28
|
+
begin
|
29
|
+
start
|
30
|
+
yield
|
31
|
+
ensure
|
32
|
+
clean
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: database_cleaner-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Mabey
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -95,6 +95,62 @@ dependencies:
|
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: activesupport
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: database_cleaner-active_record
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: sqlite3
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: database_cleaner-redis
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
98
154
|
description: Strategies for cleaning databases. Can be used to ensure a clean slate
|
99
155
|
for testing.
|
100
156
|
email:
|
@@ -107,6 +163,7 @@ files:
|
|
107
163
|
- ".rspec"
|
108
164
|
- ".ruby-version.sample"
|
109
165
|
- ".travis.yml"
|
166
|
+
- ADAPTERS.md
|
110
167
|
- CONTRIBUTE.markdown
|
111
168
|
- Gemfile
|
112
169
|
- Guardfile
|
@@ -119,19 +176,17 @@ files:
|
|
119
176
|
- database_cleaner-core.gemspec
|
120
177
|
- database_cleaner.gemspec
|
121
178
|
- lib/database_cleaner-core.rb
|
122
|
-
- lib/database_cleaner/
|
123
|
-
- lib/database_cleaner/
|
179
|
+
- lib/database_cleaner/cleaner.rb
|
180
|
+
- lib/database_cleaner/cleaners.rb
|
124
181
|
- lib/database_cleaner/core.rb
|
125
182
|
- lib/database_cleaner/cucumber.rb
|
126
183
|
- lib/database_cleaner/deprecation.rb
|
127
|
-
- lib/database_cleaner/generic/base.rb
|
128
|
-
- lib/database_cleaner/generic/transaction.rb
|
129
|
-
- lib/database_cleaner/generic/truncation.rb
|
130
184
|
- lib/database_cleaner/null_strategy.rb
|
131
185
|
- lib/database_cleaner/safeguard.rb
|
132
186
|
- lib/database_cleaner/spec.rb
|
133
187
|
- lib/database_cleaner/spec/database_helper.rb
|
134
188
|
- lib/database_cleaner/spec/shared_examples.rb
|
189
|
+
- lib/database_cleaner/strategy.rb
|
135
190
|
- lib/database_cleaner/version.rb
|
136
191
|
- tmp/.keep
|
137
192
|
homepage: https://github.com/DatabaseCleaner/database_cleaner
|
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'database_cleaner/base'
|
2
|
-
require 'database_cleaner/deprecation'
|
3
|
-
require 'forwardable'
|
4
|
-
|
5
|
-
module DatabaseCleaner
|
6
|
-
|
7
|
-
class UnknownStrategySpecified < ArgumentError; end
|
8
|
-
|
9
|
-
class Cleaners < Hash
|
10
|
-
# FIXME this method conflates creation with lookup... both a command and a query. yuck.
|
11
|
-
def [](orm, opts = {})
|
12
|
-
raise ArgumentError if orm.nil?
|
13
|
-
fetch([orm, opts]) { add_cleaner(orm, opts) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def strategy=(strategy)
|
17
|
-
values.each { |cleaner| cleaner.strategy = strategy }
|
18
|
-
remove_duplicates
|
19
|
-
end
|
20
|
-
|
21
|
-
def orm=(orm)
|
22
|
-
values.each { |cleaner| cleaner.orm = orm }
|
23
|
-
remove_duplicates
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def add_cleaner(orm, opts = {})
|
29
|
-
self[[orm, opts]] = ::DatabaseCleaner::Base.new(orm, opts)
|
30
|
-
end
|
31
|
-
|
32
|
-
def remove_duplicates
|
33
|
-
replace(reduce(Cleaners.new) do |cleaners, (key, value)|
|
34
|
-
cleaners[key] = value unless cleaners.values.include?(value)
|
35
|
-
cleaners
|
36
|
-
end)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Configuration
|
41
|
-
def initialize
|
42
|
-
@cleaners ||= Cleaners.new
|
43
|
-
end
|
44
|
-
|
45
|
-
extend Forwardable
|
46
|
-
delegate [
|
47
|
-
:[],
|
48
|
-
:strategy=,
|
49
|
-
:orm=,
|
50
|
-
] => :cleaners
|
51
|
-
|
52
|
-
attr_accessor :cleaners
|
53
|
-
|
54
|
-
def start
|
55
|
-
connections.each { |connection| connection.start }
|
56
|
-
end
|
57
|
-
|
58
|
-
def clean
|
59
|
-
connections.each { |connection| connection.clean }
|
60
|
-
end
|
61
|
-
|
62
|
-
def cleaning(&inner_block)
|
63
|
-
connections.inject(inner_block) do |curr_block, connection|
|
64
|
-
proc { connection.cleaning(&curr_block) }
|
65
|
-
end.call
|
66
|
-
end
|
67
|
-
|
68
|
-
def clean_with(*args)
|
69
|
-
connections.each { |connection| connection.clean_with(*args) }
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def connections
|
75
|
-
@cleaners.values
|
76
|
-
end
|
77
|
-
|
78
|
-
def add_cleaner(orm, opts = {})
|
79
|
-
@cleaners.add_cleaner(orm, opts = {})
|
80
|
-
end
|
81
|
-
|
82
|
-
def remove_duplicates
|
83
|
-
@cleaners.remove_duplicates
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module ::DatabaseCleaner
|
2
|
-
module Generic
|
3
|
-
module Base
|
4
|
-
|
5
|
-
def self.included(base)
|
6
|
-
base.extend(ClassMethods)
|
7
|
-
end
|
8
|
-
|
9
|
-
def db
|
10
|
-
:default
|
11
|
-
end
|
12
|
-
|
13
|
-
def cleaning(&block)
|
14
|
-
begin
|
15
|
-
start
|
16
|
-
yield
|
17
|
-
ensure
|
18
|
-
clean
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module ClassMethods
|
23
|
-
def available_strategies
|
24
|
-
%W[]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module DatabaseCleaner
|
2
|
-
module Generic
|
3
|
-
module Truncation
|
4
|
-
def initialize(opts={})
|
5
|
-
if !opts.empty? && !(opts.keys - [:only, :except, :pre_count, :reset_ids, :cache_tables]).empty?
|
6
|
-
raise ArgumentError, "The only valid options are :only, :except, :pre_count, :reset_ids or :cache_tables. You specified #{opts.keys.join(',')}."
|
7
|
-
end
|
8
|
-
if opts.has_key?(:only) && opts.has_key?(:except)
|
9
|
-
raise ArgumentError, "You may only specify either :only or :except. Doing both doesn't really make sense does it?"
|
10
|
-
end
|
11
|
-
|
12
|
-
@only = opts[:only]
|
13
|
-
@tables_to_exclude = Array( (opts[:except] || []).dup ).flatten
|
14
|
-
@tables_to_exclude += migration_storage_names
|
15
|
-
@pre_count = opts[:pre_count]
|
16
|
-
@reset_ids = opts[:reset_ids]
|
17
|
-
@cache_tables = opts.has_key?(:cache_tables) ? !!opts[:cache_tables] : true
|
18
|
-
end
|
19
|
-
|
20
|
-
def start
|
21
|
-
#included for compatability reasons, do nothing if you don't need to
|
22
|
-
end
|
23
|
-
|
24
|
-
def clean
|
25
|
-
raise NotImplementedError
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
def tables_to_truncate
|
30
|
-
raise NotImplementedError
|
31
|
-
end
|
32
|
-
|
33
|
-
# overwrite in subclasses
|
34
|
-
# default implementation given because migration storage need not be present
|
35
|
-
def migration_storage_names
|
36
|
-
%w[]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|