database_cleaner 0.6.0 → 0.6.1.rc

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.
data/History.txt CHANGED
@@ -1,4 +1,14 @@
1
- == 0.6.x (In Git)
1
+ == 0.6.1 (in git)
2
+
3
+ === New Features
4
+ * Default strategies for all ORM libs are defined. (GH-36, GH-38 Prem Sichanugrist)
5
+ * Add a NullStrategy. (GH-6 Ben Mabey)
6
+
7
+ === Bugfixes
8
+ * Exclude database views from tables_to_truncate, if the connection adapter
9
+ supports reading from the ANSI standard information_schema views. (GH-25 Samer Abukhait)
10
+ * ORM types can be specified in string format and not mysteriously blowup. (GH-26 Ben Mabey)
11
+ * Do not remove MongoDB reserved system collections. (GH-24 Ches Martin)
2
12
 
3
13
  == 0.6.0 2010-10-25 - The Multi-ORM/Connection Release
4
14
 
data/README.textile CHANGED
@@ -10,16 +10,21 @@ ActiveRecord, DataMapper, MongoMapper, Mongoid, and CouchPotato are supported.
10
10
  Here is an overview of the strategies supported for each library:
11
11
 
12
12
  |_. ORM |_. Truncation |_. Transaction |_. Deletion |
13
- | ActiveRecord | Yes | Yes | Yes |
14
- | DataMapper | Yes | Yes | No |
15
- | CouchPotato | Yes | No | No |
16
- | MongoMapper | Yes | No | No |
17
- | Mongiod | Yes | No | No |
13
+ | ActiveRecord | Yes | **Yes** | Yes |
14
+ | DataMapper | Yes | **Yes** | No |
15
+ | CouchPotato | **Yes** | No | No |
16
+ | MongoMapper | **Yes** | No | No |
17
+ | Mongoid | **Yes** | No | No |
18
+
19
+ (Default strategy for each library is denoted in bold)
18
20
 
19
21
  The ActiveRecord @:deletion@ strategy is only useful for when the @:truncation@ strategy causes
20
22
  locks (as reported by some Oracle DB users). The @:truncation@ strategy is the preferred option
21
23
  since it is much faster.
22
24
 
25
+ Database Cleaner also includes a @null@ strategy (that does no cleaning at all) which can be used
26
+ with any ORM library. You can also explicitly use it by setting your strategy to @nil@.
27
+
23
28
  h2. How to use
24
29
 
25
30
  <pre>
data/VERSION.yml CHANGED
@@ -1,6 +1,6 @@
1
- ---
1
+ ---
2
2
  :minor: 6
3
- :patch: 0
4
- :build:
3
+ :patch: 1
4
+ :build:
5
5
  :major: 0
6
6
 
@@ -0,0 +1,7 @@
1
+ ---
2
+ two:
3
+ adapter: sqlite3
4
+ database: /Users/bmabey/Programming/ruby/database_cleaner/examples/features/support/../../db/activerecord_two.db
5
+ one:
6
+ adapter: sqlite3
7
+ database: /Users/bmabey/Programming/ruby/database_cleaner/examples/features/support/../../db/activerecord_one.db
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -54,9 +54,9 @@ if orm && strategy
54
54
  DatabaseCleaner[ orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym ].strategy = strategy.to_sym
55
55
  DatabaseCleaner[ another_orm.gsub(/(.)([A-Z]+)/,'\1_\2').downcase.to_sym ].strategy = strategy.to_sym
56
56
  else
57
- DatabaseCleaner.strategy = strategy.to_sym
57
+ DatabaseCleaner.strategy = strategy.to_sym unless strategy == "default"
58
58
  end
59
59
 
60
60
  else
61
- raise "Run 'ORM=ActiveRecord|DataMapper|MongoMapper|CouchPotato [ANOTHER_ORM=...] [MULTIPLE_DBS=true] STRATEGY=transaction|truncation cucumber examples/features'"
61
+ raise "Run 'ORM=ActiveRecord|DataMapper|MongoMapper|CouchPotato [ANOTHER_ORM=...] [MULTIPLE_DBS=true] STRATEGY=transaction|truncation|default cucumber examples/features'"
62
62
  end
@@ -0,0 +1,19 @@
1
+ Feature: database cleaning
2
+ In order to ease example and feature writing
3
+ As a developer
4
+ I want to have my database in a clean state with default strategy
5
+
6
+ Scenario Outline: ruby app
7
+ Given I am using <ORM>
8
+ And the default cleaning strategy
9
+
10
+ When I run my scenarios that rely on a clean database
11
+ Then I should see all green
12
+
13
+ Examples:
14
+ | ORM |
15
+ | ActiveRecord |
16
+ | DataMapper |
17
+ | MongoMapper |
18
+ | Mongoid |
19
+ | CouchPotato |
@@ -7,9 +7,13 @@ module DatabaseCleaner
7
7
  def self.available_strategies
8
8
  %w[truncation transaction deletion]
9
9
  end
10
+
11
+ def self.config_file_location=(path)
12
+ @config_file_location = path
13
+ end
10
14
 
11
15
  def self.config_file_location
12
- "#{DatabaseCleaner.app_root}/config/database.yml"
16
+ @config_file_location ||= "#{DatabaseCleaner.app_root}/config/database.yml"
13
17
  end
14
18
 
15
19
  module Base
@@ -27,8 +31,10 @@ module DatabaseCleaner
27
31
  end
28
32
 
29
33
  def load_config
30
- connection_details = YAML::load(ERB.new(IO.read(ActiveRecord.config_file_location)).result)
31
- self.connection_hash = connection_details[self.db.to_s]
34
+ if File.file?(ActiveRecord.config_file_location)
35
+ connection_details = YAML::load(ERB.new(IO.read(ActiveRecord.config_file_location)).result)
36
+ self.connection_hash = connection_details[self.db.to_s]
37
+ end
32
38
  end
33
39
 
34
40
  def create_connection_klass
@@ -9,6 +9,9 @@ module ActiveRecord
9
9
  USE_ARJDBC_WORKAROUND = defined?(ArJdbc)
10
10
 
11
11
  class AbstractAdapter
12
+ def views
13
+ @views ||= select_values("select table_name from information_schema.views where table_schema = '#{current_database}'") rescue []
14
+ end
12
15
  end
13
16
 
14
17
  unless USE_ARJDBC_WORKAROUND
@@ -99,7 +102,7 @@ module DatabaseCleaner::ActiveRecord
99
102
  private
100
103
 
101
104
  def tables_to_truncate
102
- (@only || connection.tables) - @tables_to_exclude
105
+ (@only || connection.tables) - @tables_to_exclude - connection.views
103
106
  end
104
107
 
105
108
  def connection
@@ -1,13 +1,15 @@
1
+ require 'database_cleaner/null_strategy'
1
2
  module DatabaseCleaner
2
3
  class Base
3
4
 
4
5
  def initialize(desired_orm = nil,opts = {})
5
- if desired_orm == :autodetect || desired_orm.nil?
6
+ if [:autodetect, nil, "autodetect"].include?(desired_orm)
6
7
  autodetect
7
8
  else
8
9
  self.orm = desired_orm
9
10
  end
10
11
  self.db = opts[:connection] if opts.has_key? :connection
12
+ set_default_orm_strategy
11
13
  end
12
14
 
13
15
  def db=(desired_db)
@@ -21,9 +23,6 @@ module DatabaseCleaner
21
23
  elsif desired_db!= :default
22
24
  raise ArgumentError, "You must provide a strategy object that supports non default databases when you specify a database"
23
25
  end
24
- rescue NoStrategySetError
25
- #handle NoStrategySetError by doing nothing at all
26
- desired_db
27
26
  end
28
27
 
29
28
  def db
@@ -59,12 +58,11 @@ module DatabaseCleaner
59
58
  end
60
59
 
61
60
  def strategy
62
- return @strategy if @strategy
63
- raise NoStrategySetError, "Please set a strategy with DatabaseCleaner.strategy=."
61
+ @strategy || NullStrategy
64
62
  end
65
63
 
66
64
  def orm=(desired_orm)
67
- @orm = desired_orm
65
+ @orm = desired_orm.to_sym
68
66
  end
69
67
 
70
68
  def orm
@@ -125,5 +123,14 @@ module DatabaseCleaner
125
123
  end
126
124
  end
127
125
  end
126
+
127
+ def set_default_orm_strategy
128
+ case orm
129
+ when :active_record, :data_mapper
130
+ self.strategy = :transaction
131
+ when :mongo_mapper, :mongoid, :couch_potato
132
+ self.strategy = :truncation
133
+ end
134
+ end
128
135
  end
129
136
  end
@@ -2,7 +2,6 @@ require 'database_cleaner/base'
2
2
 
3
3
  module DatabaseCleaner
4
4
 
5
- class NoStrategySetError < StandardError; end
6
5
  class NoORMDetected < StandardError; end
7
6
  class UnknownStrategySpecified < ArgumentError; end
8
7
 
@@ -25,7 +25,7 @@ module DatabaseCleaner
25
25
  end
26
26
 
27
27
  def collections
28
- connection.db(database).collections
28
+ connection.db(database).collections.select { |c| c.name !~ /^system/ }
29
29
  end
30
30
 
31
31
  def database
@@ -19,7 +19,7 @@ module DatabaseCleaner
19
19
  private
20
20
 
21
21
  def collections
22
- ::Mongoid.database.collections
22
+ ::Mongoid.database.collections.select { |c| c.name !~ /^system/ }
23
23
  end
24
24
 
25
25
  end
@@ -0,0 +1,15 @@
1
+ module DatabaseCleaner
2
+ class NullStrategy
3
+ def self.start
4
+ # no-op
5
+ end
6
+
7
+ def self.db=(connection)
8
+ # no-op
9
+ end
10
+
11
+ def self.clean
12
+ # no-op
13
+ end
14
+ end
15
+ end
@@ -11,6 +11,7 @@ module DatabaseCleaner
11
11
  subject { ActiveRecord.config_file_location }
12
12
 
13
13
  it "should default to DatabaseCleaner.root / config / database.yml" do
14
+ ActiveRecord.config_file_location=nil
14
15
  DatabaseCleaner.should_receive(:app_root).and_return("/path/to")
15
16
  subject.should == '/path/to/config/database.yml'
16
17
  end
@@ -24,8 +25,11 @@ module DatabaseCleaner
24
25
  end
25
26
 
26
27
  describe ExampleStrategy do
28
+ let :config_location do
29
+ '/path/to/config/database.yml'
30
+ end
27
31
 
28
- before { ::DatabaseCleaner::ActiveRecord.stub(:config_file_location).and_return('/path/to/config/database.yml') }
32
+ before { ::DatabaseCleaner::ActiveRecord.stub(:config_file_location).and_return(config_location) }
29
33
 
30
34
  it_should_behave_like "a generic strategy"
31
35
 
@@ -58,7 +62,8 @@ module DatabaseCleaner
58
62
  my_db:
59
63
  database: <%= "ONE".downcase %>
60
64
  Y
61
- IO.stub(:read).with('/path/to/config/database.yml').and_return(yaml)
65
+ File.stub(:file?).with(config_location).and_return(true)
66
+ IO.stub(:read).with(config_location).and_return(yaml)
62
67
  end
63
68
 
64
69
  it "should parse the config" do
@@ -80,6 +85,12 @@ my_db:
80
85
  subject.load_config
81
86
  subject.connection_hash.should == {"database" => "one"}
82
87
  end
88
+
89
+ it "should skip config if config file is not available" do
90
+ File.should_receive(:file?).with(config_location).and_return(false)
91
+ subject.load_config
92
+ subject.connection_hash.should be_blank
93
+ end
83
94
  end
84
95
 
85
96
  describe "connection_hash" do
@@ -22,6 +22,7 @@ module DatabaseCleaner
22
22
 
23
23
  before(:each) do
24
24
  connection.stub!(:disable_referential_integrity).and_yield
25
+ connection.stub!(:views).and_return([])
25
26
  ::ActiveRecord::Base.stub!(:connection).and_return(connection)
26
27
  end
27
28
 
@@ -62,6 +63,17 @@ module DatabaseCleaner
62
63
  it "should raise an error when invalid options are provided" do
63
64
  running { Truncation.new(:foo => 'bar') }.should raise_error(ArgumentError)
64
65
  end
66
+
67
+ it "should not truncate views" do
68
+ connection.stub!(:tables).and_return(%w[widgets dogs])
69
+ connection.stub!(:views).and_return(["widgets"])
70
+
71
+ connection.should_receive(:truncate_table).with('dogs')
72
+ connection.should_not_receive(:truncate_table).with('widgets')
73
+
74
+ Truncation.new.clean
75
+ end
76
+
65
77
  end
66
78
  end
67
79
  end
@@ -1,6 +1,9 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require 'database_cleaner/active_record/transaction'
3
3
  require 'database_cleaner/data_mapper/transaction'
4
+ require 'database_cleaner/mongo_mapper/truncation'
5
+ require 'database_cleaner/mongoid/truncation'
6
+ require 'database_cleaner/couch_potato/truncation'
4
7
 
5
8
  module DatabaseCleaner
6
9
  describe Base do
@@ -138,13 +141,18 @@ module DatabaseCleaner
138
141
  cleaner.orm.should == :a_orm
139
142
  end
140
143
 
141
- it "should be autodetected if orm is nil" do
144
+ it "converts string to symbols" do
145
+ cleaner = ::DatabaseCleaner::Base.new "mongoid"
146
+ cleaner.orm.should == :mongoid
147
+ end
148
+
149
+ it "is autodetected if orm is not provided" do
142
150
  cleaner = ::DatabaseCleaner::Base.new
143
151
  cleaner.should be_auto_detected
144
152
  end
145
153
 
146
- it "should autodetect if you specify :autodetect" do
147
- cleaner = ::DatabaseCleaner::Base.new :autodetect
154
+ it "is autodetected if you specify :autodetect" do
155
+ cleaner = ::DatabaseCleaner::Base.new "autodetect"
148
156
  cleaner.should be_auto_detected
149
157
  end
150
158
 
@@ -305,12 +313,14 @@ module DatabaseCleaner
305
313
  end
306
314
 
307
315
  describe "strategy" do
308
- it "should raise NoStrategySetError if strategy is nil" do
316
+ subject { ::DatabaseCleaner::Base.new :a_orm }
317
+
318
+ it "returns a null strategy when strategy no set and undetectable" do
309
319
  subject.instance_values["@strategy"] = nil
310
- expect{ subject.strategy }.to raise_error NoStrategySetError
320
+ subject.strategy.should == DatabaseCleaner::NullStrategy
311
321
  end
312
322
 
313
- it "should return @strategy if @strategy is present" do
323
+ it "returns the set strategy" do
314
324
  strategum = mock("strategy")
315
325
  subject.strategy = strategum
316
326
  subject.strategy.should == strategum
@@ -437,5 +447,32 @@ module DatabaseCleaner
437
447
 
438
448
  end
439
449
 
450
+ describe 'set_default_orm_strategy' do
451
+ it 'sets strategy to :transaction for ActiveRecord' do
452
+ cleaner = DatabaseCleaner::Base.new(:active_record)
453
+ cleaner.strategy.should be_instance_of DatabaseCleaner::ActiveRecord::Transaction
454
+ end
455
+
456
+ it 'sets strategy to :transaction for DataMapper' do
457
+ cleaner = DatabaseCleaner::Base.new(:data_mapper)
458
+ cleaner.strategy.should be_instance_of DatabaseCleaner::DataMapper::Transaction
459
+ end
460
+
461
+ it 'sets strategy to :truncation for MongoMapper' do
462
+ cleaner = DatabaseCleaner::Base.new(:mongo_mapper)
463
+ cleaner.strategy.should be_instance_of DatabaseCleaner::MongoMapper::Truncation
464
+ end
465
+
466
+ it 'sets strategy to :truncation for Mongoid' do
467
+ cleaner = DatabaseCleaner::Base.new(:mongoid)
468
+ cleaner.strategy.should be_instance_of DatabaseCleaner::Mongoid::Truncation
469
+ end
470
+
471
+ it 'sets strategy to :truncation for CouchPotato' do
472
+ cleaner = DatabaseCleaner::Base.new(:couch_potato)
473
+ cleaner.strategy.should be_instance_of DatabaseCleaner::CouchPotato::Truncation
474
+ end
475
+ end
476
+
440
477
  end
441
478
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: database_cleaner
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease: false
4
+ hash: 7712046
5
+ prerelease: true
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 0
10
- version: 0.6.0
9
+ - 1
10
+ - rc
11
+ version: 0.6.1.rc
11
12
  platform: ruby
12
13
  authors:
13
14
  - Ben Mabey
@@ -15,7 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-10-25 00:00:00 -06:00
19
+ date: 2011-01-16 00:00:00 -07:00
19
20
  default_executable:
20
21
  dependencies: []
21
22
 
@@ -38,7 +39,13 @@ files:
38
39
  - cucumber.yml
39
40
  - examples/Gemfile
40
41
  - examples/Gemfile.lock
42
+ - examples/config/database.yml
41
43
  - examples/config/database.yml.example
44
+ - examples/db/activerecord_one.db
45
+ - examples/db/activerecord_two.db
46
+ - examples/db/datamapper_default.db
47
+ - examples/db/datamapper_one.db
48
+ - examples/db/datamapper_two.db
42
49
  - examples/db/sqlite_databases_go_here
43
50
  - examples/features/example.feature
44
51
  - examples/features/example_multiple_db.feature
@@ -56,6 +63,7 @@ files:
56
63
  - examples/lib/mongoid_models.rb
57
64
  - examples/lib/mongomapper_models.rb
58
65
  - features/cleaning.feature
66
+ - features/cleaning_default_strategy.feature
59
67
  - features/cleaning_multiple_dbs.feature
60
68
  - features/cleaning_multiple_orms.feature
61
69
  - features/step_definitions/database_cleaner_steps.rb
@@ -80,6 +88,7 @@ files:
80
88
  - lib/database_cleaner/mongo_mapper/truncation.rb
81
89
  - lib/database_cleaner/mongoid/base.rb
82
90
  - lib/database_cleaner/mongoid/truncation.rb
91
+ - lib/database_cleaner/null_strategy.rb
83
92
  - spec/database_cleaner/active_record/base_spec.rb
84
93
  - spec/database_cleaner/active_record/transaction_spec.rb
85
94
  - spec/database_cleaner/active_record/truncation_spec.rb