database_cleaner 0.6.0 → 0.6.1.rc

Sign up to get free protection for your applications and to get access to all the features.
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