saimonmoore-database_cleaner 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/History.txt +81 -0
  2. data/LICENSE +20 -0
  3. data/README.textile +127 -0
  4. data/Rakefile +46 -0
  5. data/TODO +0 -0
  6. data/VERSION.yml +5 -0
  7. data/cucumber.yml +1 -0
  8. data/examples/features/example.feature +11 -0
  9. data/examples/features/step_definitions/example_steps.rb +8 -0
  10. data/examples/features/support/env.rb +23 -0
  11. data/examples/lib/activerecord_models.rb +12 -0
  12. data/examples/lib/couchpotato_models.rb +21 -0
  13. data/examples/lib/couchrest_models.rb +23 -0
  14. data/examples/lib/datamapper_models.rb +16 -0
  15. data/examples/lib/mongomapper_models.rb +17 -0
  16. data/features/cleaning.feature +21 -0
  17. data/features/step_definitions/database_cleaner_steps.rb +25 -0
  18. data/features/support/env.rb +7 -0
  19. data/lib/database_cleaner.rb +3 -0
  20. data/lib/database_cleaner/active_record/transaction.rb +26 -0
  21. data/lib/database_cleaner/active_record/truncation.rb +79 -0
  22. data/lib/database_cleaner/configuration.rb +128 -0
  23. data/lib/database_cleaner/couch_potato/truncation.rb +26 -0
  24. data/lib/database_cleaner/couchrest/compatibility.rb +12 -0
  25. data/lib/database_cleaner/couchrest/truncation.rb +28 -0
  26. data/lib/database_cleaner/cucumber.rb +8 -0
  27. data/lib/database_cleaner/data_mapper/transaction.rb +23 -0
  28. data/lib/database_cleaner/data_mapper/truncation.rb +142 -0
  29. data/lib/database_cleaner/mongo_mapper/truncation.rb +30 -0
  30. data/lib/database_cleaner/truncation_base.rb +41 -0
  31. data/spec/database_cleaner/active_record/truncation_spec.rb +66 -0
  32. data/spec/database_cleaner/configuration_spec.rb +104 -0
  33. data/spec/database_cleaner/couch_potato/truncation_spec.rb +40 -0
  34. data/spec/database_cleaner/couchrest/truncation_spec.rb +56 -0
  35. data/spec/database_cleaner/mongo_mapper/truncation_spec.rb +81 -0
  36. data/spec/spec.opts +6 -0
  37. data/spec/spec_helper.rb +12 -0
  38. metadata +104 -0
@@ -0,0 +1,81 @@
1
+ 0.5.x (In Git)
2
+
3
+ === New features
4
+ * clean and clean_with methods are now aliased to clean! and clean_with!. (Ben Mabey)
5
+
6
+ == 0.5.0 2010-02-22 - The CouchPotato Release
7
+
8
+ === New features
9
+ * Basic truncation support for CouchPotato / CouchDB. (Martin Rehfeld)
10
+ * SQLite3 on JRuby will fall back to delete if truncate doesn't work. (Darrin Holst)
11
+ * JDBC is used for ActiveRecord automaticaly when JRuby is detected. (Darrin Holst)
12
+
13
+ === Bufixes
14
+ * MongoMapper truncation strategy now works with :only and :except options. (Ben Mabey)
15
+
16
+ == 0.4.3 2010-01-17
17
+
18
+ === New features
19
+ * Truncation for ActiveRecord oracle_enhanced adapter. (Edgars Beigarts)
20
+
21
+ == 0.4.2 2010-01-12
22
+
23
+ === Bufixes
24
+ * Datamapper truncation now uses 'select' instead of deprecated the 'query' method. (Steve Tooke)
25
+
26
+ == 0.4.1 2010-01-07
27
+
28
+ === Bufixes
29
+ * Postgres tables with FKs now truncate (added TRUNCADE CASCADE) using Datamapper. (Ben Mabey)
30
+
31
+ == 0.4.0 2009-12-23 (The MongoMapper Edition)
32
+
33
+ === New features
34
+ * MongoMapper support for the truncation strategy. (Aubrey Holland)
35
+
36
+ == 0.3.0 2009-12-20
37
+
38
+ === New features
39
+ * DataMapper 0.10.0 Compatible. (Martin Gamsjaeger)
40
+ === Bufixes
41
+ * Postgres tables with FKs now truncate (added TRUNCADE CASCADE). (Vika - yozhyk on github)
42
+
43
+ == 0.2.3 2009-05-30
44
+
45
+ === New features
46
+ * Support for SQL Server truncation (Adam Meehan)
47
+
48
+ == 0.2.2 2009-05-08
49
+ === Bufixes
50
+ * Added proper gemspec description and summary. (Ben Mabey, thanks to Martin Gamsjaeger)
51
+
52
+ === New features
53
+
54
+ == 0.2.1 2009-05-08
55
+ === Bufixes
56
+ * Removed extraneous TruncationBase class definition. (Ben Mabey)
57
+
58
+ == 0.2.0 2009-05-08 - The Datamapper Release
59
+
60
+ === New features
61
+ * DataMapper strategies (Martin Gamsjaeger)
62
+ * Transaction
63
+ * Truncation - working SQLite3, MySQL adapters. Experimental Postgres adapter (not tested).
64
+
65
+ == 0.1.3 2009-04-30
66
+
67
+ === New features
68
+ * PostgresSQLAdapter for AR to support the truncation strategy. (Alberto Perdomo)
69
+ === Bufixes
70
+ * Added missing quotes around table names in truncation calls. (Michael MacDonald)
71
+
72
+ == 0.1.2 2009-03-05
73
+ === New features
74
+ * JDBC Adapter to enable AR truncation strategy to work. (Kamal Fariz Mahyuddin)
75
+
76
+ == 0.1.1 2009-03-04 - Initial Release (Ben Mabey)
77
+ * Basic infrastructure
78
+ * Features, RSpec code examples
79
+ * ActiveRecord strategies
80
+ * Truncation - with MySQL, and SQLite3 adapters.
81
+ * Transaction - wrap your modifications and roll them back.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Ben Mabey
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,127 @@
1
+ h1. Database Cleaner
2
+
3
+ Database Cleaner is a set of strategies for cleaning your database in Ruby.
4
+ The original use case was to ensure a clean state during tests. Each strategy
5
+ is a small amount of code but is code that is usually needed in any ruby app
6
+ that is testing with a database.
7
+
8
+ ActiveRecord, DataMapper, MongoMapper, CouchRest and CouchPotato are supported.
9
+
10
+ h2. How to use
11
+
12
+ <pre>
13
+ require 'database_cleaner'
14
+ DatabaseCleaner.strategy = :truncation
15
+
16
+ # then, whenever you need to clean the DB
17
+ DatabaseCleaner.clean
18
+ </pre>
19
+
20
+ With the :truncation strategy you can also pass in options, for example:
21
+ <pre>
22
+ DatabaseCleaner.strategy = :truncation, {:only => %w[widgets dogs some_other_table]}
23
+ </pre>
24
+
25
+ <pre>
26
+ DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
27
+ </pre>
28
+
29
+ (I should point out the truncation strategy will never truncate your schema_migrations table.)
30
+
31
+
32
+ Some strategies require that you call DatabaseCleaner.start before calling clean
33
+ (for example the :transaction one needs to know to open up a transaction). So
34
+ you would have:
35
+
36
+ <pre>
37
+ require 'database_cleaner'
38
+ DatabaseCleaner.strategy = :transaction
39
+
40
+ DatabaseCleaner.start # usually this is called in setup of a test
41
+ dirty_the_db
42
+ DatabaseCleaner.clean # cleanup of the test
43
+ </pre>
44
+
45
+ At times you may want to do a single clean with one strategy. For example, you may want
46
+ to start the process by truncating all the tables, but then use the faster transaction
47
+ strategy the remaining time. To accomplish this you can say:
48
+
49
+ <pre>
50
+ require 'database_cleaner'
51
+ DatabaseCleaner.clean_with :truncation
52
+ DatabaseCleaner.strategy = :transaction
53
+ # then make the DatabaseCleaner.start and DatabaseCleaner.clean calls appropriately
54
+ </pre>
55
+
56
+ Example usage with RSpec:
57
+
58
+ <pre>
59
+ Spec::Runner.configure do |config|
60
+
61
+ config.before(:suite) do
62
+ DatabaseCleaner.strategy = :transaction
63
+ DatabaseCleaner.clean_with(:truncation)
64
+ end
65
+
66
+ config.before(:each) do
67
+ DatabaseCleaner.start
68
+ end
69
+
70
+ config.after(:each) do
71
+ DatabaseCleaner.clean
72
+ end
73
+
74
+ end
75
+ </pre>
76
+
77
+ For use in Cucumber please see the section below.
78
+
79
+
80
+
81
+ h2. Why?
82
+
83
+ One of my motivations for writing this library was to have an easy way to
84
+ turn on what Rails calls "transactional_fixtures" in my non-rails
85
+ ActiveRecord projects. For example, Cucumber ships with a Rails world that
86
+ will wrap each scenario in a transaction. This is great, but what if you are
87
+ using ActiveRecord in a non-rails project? You used to have to copy-and-paste
88
+ the needed code, but with DatabaseCleaner you can now say:
89
+
90
+ <pre>
91
+ #env.rb
92
+ require 'database_cleaner'
93
+ require 'database_cleaner/cucumber'
94
+ DatabaseCleaner.strategy = :transaction
95
+ </pre>
96
+
97
+ Now lets say you are running your features and it requires that another process be
98
+ involved (i.e. Selenium running against your app's server.) You can simply change
99
+ your strategy type:
100
+
101
+ <pre>
102
+ #env.rb
103
+ require 'database_cleaner'
104
+ require 'database_cleaner/cucumber'
105
+ DatabaseCleaner.strategy = :truncation
106
+ </pre>
107
+
108
+ You can have the best of both worlds and use the best one for the job:
109
+ <pre>
110
+ #env.rb
111
+ require 'database_cleaner'
112
+ require 'database_cleaner/cucumber'
113
+ DatabaseCleaner.strategy = (ENV['SELENIUM'] == 'true') ? :truncation : :transaction
114
+ </pre>
115
+
116
+ h2. CouchRest
117
+ Due to the fact that couchrest does not have the concept of a global attribute for
118
+ storing the default database name when using with database_cleaner you must:
119
+ <pre>
120
+ require 'database_cleaner/couchrest/compatibility'
121
+ ::CouchRest.default_database_name = 'dbname_or_url'
122
+ </pre>
123
+ before actually calling DatabaseCleaner.clean
124
+
125
+ he. COPYRIGHT
126
+
127
+ Copyright (c) 2009 Ben Mabey. See LICENSE for details.
@@ -0,0 +1,46 @@
1
+ require 'rake'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |s|
6
+ s.name = "database_cleaner"
7
+ s.summary = %Q{Strategies for cleaning databases. Can be used to ensure a clean state for testing.}
8
+ s.email = "ben@benmabey.com"
9
+ s.homepage = "http://github.com/bmabey/database_cleaner"
10
+ s.description = "Strategies for cleaning databases. Can be used to ensure a clean state for testing."
11
+ s.files = FileList["[A-Z]*.*", "{examples,lib,features,spec}/**/*", "Rakefile", "cucumber.yml"]
12
+ s.authors = ["Ben Mabey"]
13
+ end
14
+ rescue LoadError
15
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
16
+ end
17
+
18
+ require 'rake/rdoctask'
19
+ Rake::RDocTask.new do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'database_cleaner'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README*')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+ require 'spec/rake/spectask'
28
+ Spec::Rake::SpecTask.new(:spec) do |t|
29
+ t.libs << 'lib' << 'spec'
30
+ t.spec_files = FileList['spec/**/*_spec.rb']
31
+ end
32
+
33
+ Spec::Rake::SpecTask.new(:rcov) do |t|
34
+ t.libs << 'lib' << 'spec'
35
+ t.spec_files = FileList['spec/**/*_spec.rb']
36
+ t.rcov = true
37
+ end
38
+
39
+ begin
40
+ require 'cucumber/rake/task'
41
+ Cucumber::Rake::Task.new(:features)
42
+ rescue LoadError
43
+ puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
44
+ end
45
+
46
+ task :default => [:spec, :features]
data/TODO ADDED
File without changes
@@ -0,0 +1,5 @@
1
+ ---
2
+ :minor: 5
3
+ :build:
4
+ :patch: 0
5
+ :major: 0
@@ -0,0 +1 @@
1
+ default: features
@@ -0,0 +1,11 @@
1
+ Feature: example
2
+ In order to test DataBase Cleaner
3
+ Here are some scenarios that rely on the DB being clean!
4
+
5
+ Scenario: dirty the db
6
+ When I create a widget
7
+ Then I should see 1 widget
8
+
9
+ Scenario: assume a clean db
10
+ When I create a widget
11
+ Then I should see 1 widget
@@ -0,0 +1,8 @@
1
+ When /^I create a widget$/ do
2
+ Widget.create!
3
+ end
4
+
5
+ Then /^I should see 1 widget$/ do
6
+ Widget.count.should == 1
7
+ end
8
+
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'spec/expectations'
3
+
4
+ orm = ENV['ORM']
5
+ strategy = ENV['STRATEGY']
6
+
7
+ if orm && strategy
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../../../lib')
10
+ require 'database_cleaner'
11
+ require 'database_cleaner/cucumber'
12
+
13
+ begin
14
+ require "#{File.dirname(__FILE__)}/../../lib/#{orm}_models"
15
+ rescue LoadError => error
16
+ raise "You don't have the #{orm} ORM installed error: #{error.message} #{error.backtrace.join("\n")}"
17
+ end
18
+
19
+ DatabaseCleaner.strategy = strategy.to_sym
20
+
21
+ else
22
+ raise "Run 'ORM=activerecord|datamapper|mongomapper|couchpotato|couchrest STRATEGY=transaction|truncation cucumber examples/features'"
23
+ end
@@ -0,0 +1,12 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(:adapter => "#{"jdbc" if defined?(JRUBY_VERSION)}sqlite3", :database => ":memory:")
4
+
5
+ ActiveRecord::Schema.define(:version => 1) do
6
+ create_table :widgets do |t|
7
+ t.string :name
8
+ end
9
+ end
10
+
11
+ class Widget < ActiveRecord::Base
12
+ end
@@ -0,0 +1,21 @@
1
+ require 'couch_potato'
2
+
3
+ ::CouchPotato::Config.database_name = 'couch_potato_test'
4
+
5
+ class Widget
6
+ include CouchPotato::Persistence
7
+
8
+ property :name
9
+ view :by_name, :key => :name
10
+
11
+
12
+ # mimic the AR interface used in example_steps
13
+
14
+ def self.create!(attrs = {})
15
+ CouchPotato.database.save(self.new)
16
+ end
17
+
18
+ def self.count
19
+ CouchPotato.database.view(::Widget.by_name).size
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ require 'couchrest'
2
+ require 'database_cleaner/couchrest/compatibility' #opens CouchRest module to add default_database_name accessor
3
+
4
+ DEFAULT_COUCHREST_DBNAME = 'couch_rest_test'
5
+ ::CouchRest.default_database_name= DEFAULT_COUCHREST_DBNAME
6
+
7
+ class Widget < CouchRest::ExtendedDocument
8
+ use_database ::CouchRest.database!(DEFAULT_COUCHREST_DBNAME)
9
+
10
+ property :name
11
+ view_by :name
12
+
13
+ def self.create!(options = {})
14
+ instance = new(options)
15
+ instance.create!
16
+ instance
17
+ end
18
+
19
+ # def self.count
20
+ # CouchPotato.database.view(::Widget.by_name).size
21
+ # end
22
+
23
+ end
@@ -0,0 +1,16 @@
1
+ require "dm-core"
2
+
3
+ # only to please activerecord API used in database_cleaner/examples/features/step_definitions
4
+ # yes, i know that's lazy ...
5
+ require "dm-validations"
6
+ require "dm-aggregates"
7
+
8
+ DataMapper.setup(:default, "sqlite3::memory:")
9
+
10
+ class Widget
11
+ include DataMapper::Resource
12
+ property :id, Serial
13
+ property :name, String
14
+ end
15
+
16
+ Widget.auto_migrate!
@@ -0,0 +1,17 @@
1
+ require 'mongomapper'
2
+
3
+ ::MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
4
+ ::MongoMapper.database = 'database_cleaner_test'
5
+
6
+ class Widget
7
+ include MongoMapper::Document
8
+ key :id, Integer
9
+ key :name, String
10
+
11
+ class << self
12
+ #mongomapper doesn't seem to provide this...
13
+ def create!(*args)
14
+ new(*args).save!
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
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
5
+
6
+ Scenario Outline: ruby app
7
+ Given I am using <ORM>
8
+ And the <Strategy> 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 | Strategy |
15
+ | ActiveRecord | transaction |
16
+ | ActiveRecord | truncation |
17
+ | DataMapper | transaction |
18
+ | DataMapper | truncation |
19
+ | MongoMapper | truncation |
20
+ | CouchPotato | truncation |
21
+ | CouchRest | truncation |