Flipper 1.0

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/README ADDED
@@ -0,0 +1,77 @@
1
+
2
+ = Flipper
3
+
4
+ "Switch your database on the fly"
5
+
6
+
7
+ == Introduction
8
+
9
+ When doing integration and acceptance testing you typically need to:
10
+
11
+ * Change and manage application state.
12
+ * Guarantee test case isolation, even for those that change the application state.
13
+
14
+ 9 times out of 10, all you need to do to achieve this for a Rails application is:
15
+
16
+ * Have direct access to the database.
17
+ * Ensure that tests running in parallel access a different database schema.
18
+
19
+ So if you are driving your tests at the HTTP layer (e.g. Selenium tests) you could use a
20
+ single Mongrel cluster to run a lot of tests in parallel, a long as you can change your
21
+ database on the fly for each HTTP requests. This is what Flipper does.
22
+
23
+ == Status
24
+
25
+ The current status is quite good. Flipper is currently used on a daily basis on commercial projects.
26
+
27
+
28
+ == Installation
29
+
30
+ The easiest way to install is via RubyGems. On the command line enter:
31
+
32
+ > gem install flipper
33
+
34
+ == Usage
35
+
36
+ To use flipper just include the <code>Flipper</code> module and add a before filter in <code>application.rb</code>:
37
+
38
+ class ApplicationController < ActionController::Base
39
+ include Flipper
40
+
41
+ before_filter :switch_database
42
+
43
+ ...
44
+ end
45
+
46
+ == License
47
+
48
+ The collection PER COLLECTION is licensed as follows:
49
+
50
+ Ruby Facets
51
+ Copyright (c) 2004-2006 Thomas Sawyer
52
+
53
+ Distributed under the terms of the Ruby license.
54
+
55
+ The Ruby license is a dual license that also provides for use of the GPL.
56
+ Complete texts of both licenses accompany this document (see doc/COPYING).
57
+
58
+ This program is free software; you can redistribute it and/or modify
59
+ it under the terms of the GNU General Public License as published by
60
+ the Free Software Foundation; either version 2 of the License, or
61
+ (at your option) any later version.
62
+
63
+ This program is distributed in the hope that it will be useful,
64
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
65
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
66
+ GNU General Public License for more details.
67
+
68
+ You should have received a copy of the GNU General Public License
69
+ along with this program; if not, write to the Free Software
70
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
71
+
72
+ Acknowledgments and Copyrights for particular snippets of borrowed code
73
+ are given in their respective source. All licenses are either compatible
74
+ with the Ruby license (namely the GPL) or the original author has given
75
+ permission for inclusion of their code under such lincense.
76
+
77
+
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/contrib/sshpublisher'
6
+
7
+
8
+ desc 'Default: run unit tests.'
9
+ task :default => :test
10
+
11
+ desc 'Test the flipper plugin.'
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'lib'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = true
16
+ end
17
+
18
+ desc 'Generate documentation for the flipper plugin.'
19
+ Rake::RDocTask.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'Flipper'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+ Gem::manage_gems
28
+
29
+ specification = Gem::Specification.new do |s|
30
+ s.name = "Flipper"
31
+ s.summary = "Switch your Rails database on the fly for each HTTP request. Useful for integration and acceptance testing (test isolation & state management)."
32
+ s.version = "1.0"
33
+ s.author = 'Philippe Hanrigou & Dan Manges'
34
+ s.description = s.summary
35
+ s.email = 'flipper-developer@rubyforge.org'
36
+ s.homepage = 'http://flipper.rubyforge.org'
37
+ s.rubyforge_project = 'flipper'
38
+
39
+ s.has_rdoc = true
40
+ s.extra_rdoc_files = ['README']
41
+ s.rdoc_options << '--title' << 'Flipper' << '--main' << 'README' << '--line-numbers'
42
+
43
+ s.autorequire = 'flipper'
44
+ s.files = FileList['{lib,test}/**/*.rb', '[A-Z]*$', 'Rakefile'].to_a
45
+ s.test_file = "test/all_tests.rb"
46
+ end
47
+
48
+ Rake::GemPackageTask.new(specification) do |package|
49
+ package.need_zip = false
50
+ package.need_tar = false
51
+ end
data/lib/flipper.rb ADDED
@@ -0,0 +1,37 @@
1
+ #
2
+ # Include this module in your Rails controller to change database schema on each HTTP request:
3
+ #
4
+ # class ApplicationController < ActionController::Base
5
+ # include Flipper
6
+ #
7
+ # before_filter :switch_database # if RAILS_ENV == "selenium"
8
+ #
9
+ # ...
10
+ # end
11
+ module Flipper
12
+
13
+ #
14
+ # Switch current database based on <code>flipper_db_config</code> HTTP parameter, if any,
15
+ # and store database configuration in session.
16
+ #
17
+ # If there is no <code>flipper_db_config</code> parameter, switch to the database configuration
18
+ # stored in session.
19
+ #
20
+ # If anything goes wrong while switching database, attempts to rollback to the previous database configuration
21
+ # before raising an exception.
22
+ def switch_database
23
+ database_configuration = params[:flipper_db_config] || session[:flipper_db_config]
24
+ return unless database_configuration
25
+
26
+ prior_configuration = ActiveRecord::Base.connection.instance_variable_get(:@config)
27
+ ActiveRecord::Base.clear_active_connections!
28
+ begin
29
+ ActiveRecord::Base.establish_connection database_configuration
30
+ session[:flipper_db_config] = database_configuration
31
+ rescue => ex
32
+ ActiveRecord::Base.establish_connection prior_configuration
33
+ raise
34
+ end
35
+ end
36
+
37
+ end
data/test/all_tests.rb ADDED
@@ -0,0 +1 @@
1
+ Dir["#{File.dirname __FILE__}/*_test.rb"].each { |test_case| require test_case }
@@ -0,0 +1,78 @@
1
+ require "rubygems"
2
+ require "dust"
3
+ require "mocha"
4
+ require 'test/unit'
5
+
6
+ unless defined?(ActiveRecord)
7
+ module ActiveRecord
8
+ class Base; end
9
+ end
10
+ end
11
+
12
+ require File.dirname(__FILE__) + "/../lib/flipper"
13
+
14
+ unit_tests do
15
+
16
+ def setup
17
+ @controller = Class.new { include Flipper }.new
18
+ end
19
+
20
+ test "controller establishes new db connection and clears active connection when receiving database_connection from params" do
21
+ @controller.stubs(:session).returns({})
22
+ @controller.stubs(:params).returns(:flipper_db_config => :connection_hash)
23
+ ActiveRecord::Base.stubs(:connection).returns(stub_everything)
24
+ ActiveRecord::Base.expects(:clear_active_connections!)
25
+ ActiveRecord::Base.expects(:establish_connection).with(:connection_hash)
26
+ @controller.send(:switch_database)
27
+ end
28
+
29
+ test "controller establishes new db connection and clears active connection when receiving database_connection from session" do
30
+ @controller.stubs(:session).returns(:flipper_db_config => :connection_hash)
31
+ @controller.stubs(:params).returns(:flipper_db_config => nil)
32
+ ActiveRecord::Base.stubs(:connection).returns(stub_everything)
33
+ ActiveRecord::Base.expects(:clear_active_connections!)
34
+ ActiveRecord::Base.expects(:establish_connection).with(:connection_hash)
35
+ @controller.send(:switch_database)
36
+ end
37
+
38
+ test "controller checks for database configuration in params before session" do
39
+ @controller.stubs(:session).returns(:flipper_db_config => :session_connection_hash)
40
+ @controller.stubs(:params).returns(:flipper_db_config => :params_connection_hash)
41
+ ActiveRecord::Base.stubs(:connection).returns(stub_everything)
42
+ ActiveRecord::Base.expects(:clear_active_connections!)
43
+ ActiveRecord::Base.expects(:establish_connection).with(:params_connection_hash)
44
+ @controller.send(:switch_database)
45
+ end
46
+
47
+ test "controller does not establish a new db connection nor clears active connection when there is no database_connection neither in params nor in session" do
48
+ @controller.stubs(:session).returns({})
49
+ @controller.stubs(:params).returns(:flipper_db_config => nil)
50
+ ActiveRecord::Base.stubs(:connection).returns(stub_everything)
51
+ ActiveRecord::Base.expects(:clear_active_connections!).never
52
+ ActiveRecord::Base.expects(:establish_connection).never
53
+ @controller.send(:switch_database)
54
+ end
55
+
56
+ test "database configuration is stored in session after passed in through params" do
57
+ @controller.stubs(:session).returns(session = {})
58
+ @controller.stubs(:params).returns(:flipper_db_config => :connection_hash)
59
+ ActiveRecord::Base.stubs(:connection).returns(stub_everything)
60
+ ActiveRecord::Base.stubs(:clear_active_connections!)
61
+ ActiveRecord::Base.stubs(:establish_connection)
62
+ @controller.send(:switch_database)
63
+ assert_equal :connection_hash, session[:flipper_db_config]
64
+ end
65
+
66
+ test "controller restores original db connection and raises exception when establishing a new database_connection fails" do
67
+ @controller.stubs(:session).returns({})
68
+ @controller.stubs(:params).returns(:flipper_db_config => :connection_hash)
69
+ ActiveRecord::Base.stubs(:connection).returns(connection = stub)
70
+ connection.instance_variable_set "@config", :old_configuration
71
+ ActiveRecord::Base.expects(:clear_active_connections!)
72
+ exception = RuntimeError.new("will be raised if new connection cannot be established")
73
+ ActiveRecord::Base.expects(:establish_connection).with(:connection_hash).raises(exception)
74
+ ActiveRecord::Base.expects(:establish_connection).with(:old_configuration)
75
+ assert_raises(RuntimeError) { @controller.send(:switch_database) }
76
+ end
77
+
78
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: Flipper
5
+ version: !ruby/object:Gem::Version
6
+ version: "1.0"
7
+ date: 2007-09-15 00:00:00 -04:00
8
+ summary: Switch your Rails database on the fly for each HTTP request. Useful for integration and acceptance testing (test isolation & state management).
9
+ require_paths:
10
+ - lib
11
+ email: flipper-developer@rubyforge.org
12
+ homepage: http://flipper.rubyforge.org
13
+ rubyforge_project: flipper
14
+ description: Switch your Rails database on the fly for each HTTP request. Useful for integration and acceptance testing (test isolation & state management).
15
+ autorequire: flipper
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Philippe Hanrigou & Dan Manges
31
+ files:
32
+ - lib/flipper.rb
33
+ - test/flipper_test.rb
34
+ - test/all_tests.rb
35
+ - Rakefile
36
+ - README
37
+ test_files:
38
+ - test/all_tests.rb
39
+ rdoc_options:
40
+ - --title
41
+ - Flipper
42
+ - --main
43
+ - README
44
+ - --line-numbers
45
+ extra_rdoc_files:
46
+ - README
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ requirements: []
52
+
53
+ dependencies: []
54
+