nogo 1.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/README.md +75 -0
- data/Rakefile +2 -0
- data/lib/active_record/connection_adapters/nogo_adapter.rb +15 -0
- data/lib/active_record/import.rb +13 -0
- data/lib/nogo.rb +4 -0
- data/lib/nogo/abstract_method_overrides.rb +78 -0
- data/lib/nogo/connection.rb +47 -0
- data/lib/nogo/proxy_adapter.rb +90 -0
- data/lib/nogo/rspec.rb +4 -0
- data/lib/nogo/rspec/dsl.rb +31 -0
- data/lib/nogo/version.rb +3 -0
- data/nogo.gemspec +22 -0
- data/spec/active_record/connection_adapters/nogo_adapter_spec.rb +24 -0
- data/spec/nogo/connection_spec.rb +106 -0
- data/spec/nogo/proxy_adapter_spec.rb +352 -0
- data/spec/rspec/dsl_spec.rb +77 -0
- data/spec/spec_helper.rb +4 -0
- metadata +113 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
### NoGo is a library to find the places in your code which touch your database
|
2
|
+
NoGo's main objective is to help find and prevent code which accesses the database during testing. Disconnecting the database completely while running your test suite may be impractical, so NoGo take a different approach by proxying an estabished database connection. It is possible to enable and disable NoGo as well as change between ```:raise```, ```:warn``` and ```:pass_through``` strategies on the fly.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
Add nogo to your Gemfile
|
6
|
+
|
7
|
+
```gem 'nogo'```
|
8
|
+
|
9
|
+
Or install from the command line
|
10
|
+
|
11
|
+
```gem install nogo```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
NoGo can be used as a standalone library, but it does integrate with the RSpec 2 test framework.
|
16
|
+
|
17
|
+
### RSpec
|
18
|
+
Wrap any spec examples that should not use the database adapter inside a "nogo do" block.
|
19
|
+
|
20
|
+
<pre>
|
21
|
+
# In your specs
|
22
|
+
require 'nogo/rspec' # Automatically connects, so this should be included after the environment is loaded.
|
23
|
+
|
24
|
+
describe Klass do
|
25
|
+
it 'works without error' do
|
26
|
+
Klass.create
|
27
|
+
end
|
28
|
+
|
29
|
+
nogo do # Any access to the database inside this block will raise an exception
|
30
|
+
it 'raises error' do
|
31
|
+
expect{ Klass.create }.to raise_error
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'works without error' do
|
36
|
+
Klass.create
|
37
|
+
end
|
38
|
+
end
|
39
|
+
</pre>
|
40
|
+
|
41
|
+
### Globally enabling NoGo
|
42
|
+
By default NoGo will not check requests to the database, even after being connected. Here is an example of enabling NoGo.
|
43
|
+
|
44
|
+
<pre>
|
45
|
+
require 'nogo'
|
46
|
+
|
47
|
+
# Database adapter should already be connected
|
48
|
+
NoGo::Connection.connect!
|
49
|
+
|
50
|
+
ModelKlass.create # Works as expected
|
51
|
+
|
52
|
+
NoGo::Connection.enabled = true
|
53
|
+
ModelKlass.create # Raises exception
|
54
|
+
|
55
|
+
NoGo::Connection.enabled = false
|
56
|
+
ModelKlass.create # Works as expected
|
57
|
+
</pre>
|
58
|
+
|
59
|
+
## Platforms
|
60
|
+
Tested with:
|
61
|
+
|
62
|
+
RSpec 2.7.0, 2.8.0
|
63
|
+
ActiveRecord 3.1.3, 3.2.1.
|
64
|
+
|
65
|
+
##LICENSE
|
66
|
+
|
67
|
+
(The MIT License)
|
68
|
+
|
69
|
+
Copyright © 2012 Andy Ogzewalla
|
70
|
+
|
71
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
72
|
+
|
73
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
74
|
+
|
75
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Adds a connection method so that ActiveRecord recognizes the proxy adapter
|
2
|
+
module ActiveRecord
|
3
|
+
class Base
|
4
|
+
# returns an instance of <tt>NoGo::ProxyAdapter</tt> which proxies the adapter instance specified by <tt>config[:target_adapter]</tt>. This method will
|
5
|
+
# also attempt to reconnect the proxied adapter.
|
6
|
+
def self.nogo_connection(config)
|
7
|
+
proxy_adapter = NoGo::ProxyAdapter.new(config[:target_adapter])
|
8
|
+
proxy_adapter.proxied_adapter.send :connect # TODO: It would be nice if we could detect whether the adapter was connected before, but for now just attempt to reconnect it. ActiveRecord disconnects the adapter before calling <tt>::nogo_connection</tt> *
|
9
|
+
# TODO: This is probably where connection pool config should be set rather than in NoGo::Connection::connect! *
|
10
|
+
proxy_adapter
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'active_record/import'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
if defined?(ActiveRecord::Import)
|
2
|
+
ActiveRecord::Import.module_eval do
|
3
|
+
class << self # Lulz, I tried `module << self` which didn't work.
|
4
|
+
# Catch case where adapter is set to <tt>:nogo</tt>. Activerecord-import hijacks
|
5
|
+
# AR::Base#establish_connection, so there was no clean way to avoid having it attempt
|
6
|
+
# to require its own nogo adatper, which fails.
|
7
|
+
def require_adapter_with_nogo(adapter)
|
8
|
+
require_adapter_without_nogo(adapter) unless adapter==:nogo
|
9
|
+
end
|
10
|
+
alias_method_chain :require_adapter, :nogo
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/nogo.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
module NoGo
|
2
|
+
# Contains overrides for methods which are defined in ActiveRecord::ConnectionAdapters::AbstractAdapter and are
|
3
|
+
# ovenrridden here as a way to hook into ActiveRecord before requests access the database connection.
|
4
|
+
module AbstractMethodOverrides
|
5
|
+
|
6
|
+
def execute(sql, name = nil)
|
7
|
+
if sql.match /BEGIN|ROLLBACK|SAVEPOINT/ # TODO: There should be a better way to avoid transactions *
|
8
|
+
pass_through(:execute, sql, name)
|
9
|
+
else
|
10
|
+
raise_or_pass_through(:execute, sql, name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
15
|
+
raise_or_pass_through(:insert, sql, name, pk, id_value, sequence_name, binds)
|
16
|
+
end
|
17
|
+
|
18
|
+
def update(sql, name = nil, binds = [])
|
19
|
+
raise_or_pass_through(:update, sql, name, binds)
|
20
|
+
end
|
21
|
+
|
22
|
+
def delete(sql, name = nil, binds = [])
|
23
|
+
raise_or_pass_through(:delete, sql, name, binds)
|
24
|
+
end
|
25
|
+
|
26
|
+
def select_rows(sql, name = nil)
|
27
|
+
raise_or_pass_through(:select_rows, sql, name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def select(sql, name = nil)
|
31
|
+
raise_or_pass_through(:select, sql, name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def select_all(sql, name = nil, binds = [])
|
35
|
+
raise_or_pass_through(:select_all, sql, name, binds)
|
36
|
+
end
|
37
|
+
|
38
|
+
def select_one(sql, name = nil)
|
39
|
+
raise_or_pass_through(:select_one, sql, name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def select_value(sql, name = nil)
|
43
|
+
raise_or_pass_through(:select_value, sql, name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def select_values(sql, name = nil)
|
47
|
+
raise_or_pass_through(:select_values, sql, name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def exec_query(sql, name = nil, binds = [])
|
51
|
+
raise_or_pass_through(:exec_query, sql, name, binds)
|
52
|
+
end
|
53
|
+
|
54
|
+
def exec_insert(sql, name = nil, binds = [])
|
55
|
+
raise_or_pass_through(:exec_insert, sql, name, binds)
|
56
|
+
end
|
57
|
+
|
58
|
+
def exec_delete(sql, name = nil, binds = [])
|
59
|
+
raise_or_pass_through(:exec_delete, sql, name, binds)
|
60
|
+
end
|
61
|
+
|
62
|
+
def exec_update(sql, name = nil, binds = [])
|
63
|
+
raise_or_pass_through(:exec_update, sql, name, binds)
|
64
|
+
end
|
65
|
+
|
66
|
+
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
|
67
|
+
raise_or_pass_through(:insert_sql, sql, name, pk, id_value, sequence_name, binds)
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_sql(sql, name = nil)
|
71
|
+
raise_or_pass_through(:update_sql, sql, name)
|
72
|
+
end
|
73
|
+
|
74
|
+
def delete_sql(sql, name = nil)
|
75
|
+
raise_or_pass_through(:delete_sql, sql, name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module NoGo
|
2
|
+
class Connection
|
3
|
+
@@proxy_adapter = nil
|
4
|
+
|
5
|
+
# Returns proxy adapter if connected, otherwise raises an error
|
6
|
+
def self.proxy_adapter
|
7
|
+
@@proxy_adapter || raise('Proxy adapter is not connected. Please run NoGo::Connection.connect! to first establish a connection.')
|
8
|
+
end
|
9
|
+
|
10
|
+
# Proxy an existing connection. Raises an exception if no database
|
11
|
+
# connection has been established.
|
12
|
+
def self.connect!
|
13
|
+
# TODO: Abstract away ORM-specific code *
|
14
|
+
original_adapter = ActiveRecord::Base.connection_pool.spec.config[:adapter]
|
15
|
+
ActiveRecord::Base.establish_connection :adapter => :nogo, :target_adapter => ActiveRecord::Base.connection
|
16
|
+
|
17
|
+
# After establishing connection the connection pool config adapter will be set to <tt>:nogo</tt> which
|
18
|
+
# may cause problems with gems such as activerecord-import which rely on that value to be set to a
|
19
|
+
# standard ActiveRecord database adapter. Fortunately we can easily change the config setting back to
|
20
|
+
# its original value.
|
21
|
+
ActiveRecord::Base.connection_pool.spec.config[:adapter] = original_adapter
|
22
|
+
|
23
|
+
@@proxy_adapter = ActiveRecord::Base.connection
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns true or false to indicate whether a proxy adapter has been connected.
|
27
|
+
def self.connected?
|
28
|
+
!!@@proxy_adapter
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.enabled=(value)
|
32
|
+
proxy_adapter.enabled = value
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.pop_enabled_state
|
36
|
+
proxy_adapter.pop_enabled_state
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.push_enabled_state
|
40
|
+
proxy_adapter.push_enabled_state
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.strategy=(strategy)
|
44
|
+
proxy_adapter.strategy = strategy
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module NoGo
|
2
|
+
class ProxyAdapter
|
3
|
+
# Valid values for <tt>@strategy</tt> and arguments when setting <tt>strategy</tt>
|
4
|
+
StrategyOptions = [:raise, :warn, :pass_through].freeze
|
5
|
+
|
6
|
+
ErrorMessageForRaiseStrategy = <<-EOM.freeze
|
7
|
+
Access to the database adapter is currently restricted (strategy set to :raise).
|
8
|
+
Set strategy to :pass_through or :warn to allow database access. See NoGo::Connection#strategy=.
|
9
|
+
EOM
|
10
|
+
|
11
|
+
# Most methods calls should simply be passed on to the proxied adapter. By undefining most methods we can use
|
12
|
+
# <tt>method_missing</tt> to accomplish this.
|
13
|
+
instance_methods.each do |method_name|
|
14
|
+
undef_method method_name unless method_name =~ /^__|^send$|^object_id$|^extend|^tap|^instance_variable_set|^instance_variable_get/
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :enabled
|
18
|
+
|
19
|
+
# Include overriden AbstractAdapter methods
|
20
|
+
include NoGo::AbstractMethodOverrides
|
21
|
+
|
22
|
+
# Initializes an instance and sets the proxied adapter and default strategy. An exception is raised if the argument to <tt>adapter</tt> is
|
23
|
+
# not an instance of <tt>ActiveRecord::ConnectionAdapters::AbstractAdapter</tt>.
|
24
|
+
def initialize(adapter)
|
25
|
+
raise ArgumentError.new(
|
26
|
+
"Expected an instance of ActiveRecord::ConnectionAdapters::AbstractAdapter, but received #{adapter.class.name}"
|
27
|
+
) unless adapter.is_a?(ActiveRecord::ConnectionAdapters::AbstractAdapter)
|
28
|
+
|
29
|
+
@adapter = adapter
|
30
|
+
@strategy = :raise
|
31
|
+
self.enabled = false
|
32
|
+
@enabled_state_stack = []
|
33
|
+
end
|
34
|
+
|
35
|
+
# Pops the last value from <tt>enabled_state_stack</tt> and assigns it to <tt>enabled</tt>.
|
36
|
+
def pop_enabled_state
|
37
|
+
self.enabled = @enabled_state_stack.pop || false
|
38
|
+
end
|
39
|
+
|
40
|
+
# Pushes the current value of <tt>enabled</tt> onto <tt>enabled_state_stack</tt>.
|
41
|
+
def push_enabled_state
|
42
|
+
@enabled_state_stack.push(enabled)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the adapter which is being proxied by the current object.
|
46
|
+
def proxied_adapter
|
47
|
+
@adapter
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the current strategy assigned to this adapter, which can any of the <tt>StrategyOptions</tt>.
|
51
|
+
def strategy
|
52
|
+
@strategy
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sets the current strategy for this adapter. Raises an <tt>ArgumentErrer</tt> if <tt>strategy_option</tt> is not
|
56
|
+
# a value from <tt>StrategyOptions</tt>
|
57
|
+
def strategy=(strategy_option)
|
58
|
+
raise ArgumentError.new(
|
59
|
+
"Expected strategy to be set to one of [#{StrategyOptions.map{|opt| ":#{opt}"}.join(', ')}], but received #{strategy_option}"
|
60
|
+
) unless StrategyOptions.include?(strategy_option.to_sym)
|
61
|
+
|
62
|
+
@strategy = strategy_option
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Pass through any undefined instance method calls.
|
68
|
+
def method_missing(method_name, *args, &block) # :doc:
|
69
|
+
pass_through(method_name, *args, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Passes a method call to the proxied adapter.
|
73
|
+
# If the strategy is set to <tt>:warn</tt> then <tt>#warn</tt> will be invoked.
|
74
|
+
def pass_through(method_name, *args, &block) # :doc:
|
75
|
+
warn(method_name, *args, &block) if enabled && @strategy == :warn
|
76
|
+
proxied_adapter.send(method_name, *args, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Raises an error if the current strategy is <tt>:raise</tt> and otherwise defers the method call to <tt>#pass_through</tt>.
|
80
|
+
def raise_or_pass_through(method_name, *args, &block) # :doc:
|
81
|
+
raise ErrorMessageForRaiseStrategy if enabled && @strategy == :raise
|
82
|
+
pass_through(method_name, *args, &block)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Placeholder for <tt>#warn</tt> method. This is probably a place to trigger hooks once they are supported
|
86
|
+
def warn(method_name, *args, &block) # :doc:
|
87
|
+
puts "\nDatabase adapter accessed from: " + Kernel.caller[0..12].join("\n")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/nogo/rspec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
module NoGo
|
4
|
+
module RSpec
|
5
|
+
class DSL
|
6
|
+
NogoBeforeAllBlock = Proc.new do
|
7
|
+
NoGo::Connection.push_enabled_state
|
8
|
+
NoGo::Connection.enabled = true
|
9
|
+
end.freeze
|
10
|
+
NogoAfterAllBlock = Proc.new do
|
11
|
+
NoGo::Connection.pop_enabled_state
|
12
|
+
end.freeze
|
13
|
+
|
14
|
+
def self.nogo_example_group(*args, &example_group_block)
|
15
|
+
::RSpec::Core::ExampleGroup.describe(*args) do
|
16
|
+
before(:all, &NoGo::RSpec::DSL::NogoBeforeAllBlock)
|
17
|
+
after(:all, &NoGo::RSpec::DSL::NogoAfterAllBlock)
|
18
|
+
instance_eval(&example_group_block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Adds DSL method to RSpec ExampleGroup instances
|
26
|
+
RSpec::Core::DSL.module_eval do
|
27
|
+
def nogo(*args, &example_group_block)
|
28
|
+
NoGo::RSpec::DSL.nogo_example_group(*args, &example_group_block).register
|
29
|
+
end
|
30
|
+
alias :database_restricted :nogo
|
31
|
+
end
|
data/lib/nogo/version.rb
ADDED
data/nogo.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/nogo/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Andy Ogzewalla"]
|
6
|
+
gem.email = ["andyogzewalla@gmail.com"]
|
7
|
+
gem.description = %q{A library that lets you know when your code touches your database}
|
8
|
+
gem.summary = %q{A library that lets you know when your code touches your database}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "nogo"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = NoGo::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'rspec', '~> 2.7.0'
|
19
|
+
gem.add_dependency 'activerecord', '~> 3.0'
|
20
|
+
gem.add_development_dependency 'rspec', '~> 2.7.0'
|
21
|
+
gem.add_development_dependency 'activerecord', '~> 3.0'
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_record/connection_adapters/nogo_adapter'
|
3
|
+
|
4
|
+
describe ActiveRecord::Base do
|
5
|
+
describe '::nogo_connection' do
|
6
|
+
let(:adapter) { mock }
|
7
|
+
let(:nogo_adapter) { mock(:proxied_adapter => adapter) }
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
NoGo::ProxyAdapter.stub(:new).with(adapter).and_return(nogo_adapter)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns new NoGo::ProxyAdapter instance' do
|
14
|
+
adapter.stub(:connect)
|
15
|
+
ActiveRecord::Base.nogo_connection({:target_adapter => adapter}).should == nogo_adapter
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'reconnects the adapter' do
|
19
|
+
adapter.should_receive(:connect)
|
20
|
+
ActiveRecord::Base.nogo_connection({:target_adapter => adapter})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NoGo::Connection do
|
4
|
+
subject { NoGo::Connection }
|
5
|
+
let(:proxy_adapter) { mock.as_null_object }
|
6
|
+
before :each do
|
7
|
+
subject.class_variable_set(:@@proxy_adapter, proxy_adapter)
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '::proxy_adapter' do
|
11
|
+
let(:proxy_adapter) {mock}
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
subject.class_variable_set(:@@proxy_adapter, proxy_adapter)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'raises error if proxy adapter is not connected' do
|
18
|
+
subject.class_variable_set(:@@proxy_adapter, nil)
|
19
|
+
expect{subject.proxy_adapter}.to raise_error
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'does not raise an error if proxy adapter is connected' do
|
23
|
+
subject.class_variable_set(:@@proxy_adapter, proxy_adapter)
|
24
|
+
expect{subject.proxy_adapter}.to_not raise_error
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns proxy adapter if connected' do
|
28
|
+
subject.class_variable_set(:@@proxy_adapter, proxy_adapter)
|
29
|
+
subject.proxy_adapter.should == proxy_adapter
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '::connect!' do
|
34
|
+
it 'raise an error if ActiveRecord is not connected to a database' do
|
35
|
+
ActiveRecord::Base.stub(:connection).and_raise(ActiveRecord::ConnectionNotEstablished.new)
|
36
|
+
expect{subject.connect!}.to raise_error(ActiveRecord::ConnectionNotEstablished)
|
37
|
+
end
|
38
|
+
|
39
|
+
context do
|
40
|
+
let(:adapter) { ActiveRecord::ConnectionAdapters::AbstractAdapter.new(nil)}
|
41
|
+
let(:config) {{:adapter => 'original_adapter'}}
|
42
|
+
|
43
|
+
before :each do
|
44
|
+
adapter.stub(:connect)
|
45
|
+
ActiveRecord::Base.stub(:connection) { adapter }
|
46
|
+
ActiveRecord::Base.stub(:connection_pool) { mock(:spec => mock(:config => config)) }
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'proxies the current connection adapter' do
|
50
|
+
ActiveRecord::Base.should_receive(:establish_connection).
|
51
|
+
with(:adapter => :nogo, :target_adapter => adapter)
|
52
|
+
subject.connect!
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'sets @@proxy_adapter with instance of NoGo::ProxyAdapter generated when establishing connection' do
|
56
|
+
subject.connect!
|
57
|
+
subject.class_variable_get(:@@proxy_adapter).should == adapter
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'sets connection_pool spec config adapter to original (non-proxied) value' do
|
61
|
+
config.should_receive(:[]=).with(:adapter, 'original_adapter')
|
62
|
+
subject.connect!
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '::connected?' do
|
68
|
+
it 'returns false if proxy adapter has not been connected' do
|
69
|
+
subject.class_variable_set(:@@proxy_adapter, nil)
|
70
|
+
subject.connected?.should == false
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns true if proxy adapter has been connected' do
|
74
|
+
subject.connected?.should == true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '::enabled=' do
|
79
|
+
it 'invokes #enabled= with argument on proxy adapter' do
|
80
|
+
argument = mock
|
81
|
+
proxy_adapter.should_receive(:enabled=).with(argument)
|
82
|
+
subject.enabled = argument
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '::strategy=' do
|
87
|
+
it 'calls #strategy= on the proxy adapter' do
|
88
|
+
proxy_adapter.should_receive(:strategy=).with(:pass_through)
|
89
|
+
subject.strategy = :pass_through
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '::pop_enabled_state' do
|
94
|
+
it 'invokes #pop_enabled_state on the proxy adapter' do
|
95
|
+
proxy_adapter.should_receive(:pop_enabled_state)
|
96
|
+
subject.pop_enabled_state
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '::push_enabled_state' do
|
101
|
+
it 'invokes #push_enabled_state on the proxy adapter' do
|
102
|
+
proxy_adapter.should_receive(:push_enabled_state)
|
103
|
+
subject.push_enabled_state
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,352 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NoGo::ProxyAdapter do
|
4
|
+
let(:adapter) { ActiveRecord::ConnectionAdapters::AbstractAdapter.new(nil)}
|
5
|
+
let(:proxy_adapter) { NoGo::ProxyAdapter.new(adapter) }
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
NoGo::ProxyAdapter.class_eval do
|
9
|
+
|
10
|
+
# Ugh, rspec mocks freak out if we try to pass calls to
|
11
|
+
def is_a?(klass)
|
12
|
+
proxied_adapter.is_a?(klass)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def method_missing_with_test_filter(method_name, *args, &block)
|
17
|
+
# RSpec sends messages directly to method_missing when checking an object with mocked methods. Why? I don't know, but it
|
18
|
+
# causes an infinite loop for some of ProxyAdapter methods. This filter prevents that from happening.
|
19
|
+
unless %W[warn pass_through method_missing].include?(method_name.to_s)
|
20
|
+
method_missing_without_test_filter(method_name, *args, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
alias_method_chain :method_missing, :test_filter
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '::new' do
|
28
|
+
it 'initializes with adapter argument' do
|
29
|
+
expect{ NoGo::ProxyAdapter.new(adapter) }.to_not raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'raises error without adapter argument' do
|
33
|
+
expect{ NoGo::ProxyAdapter.new }.to raise_error(ArgumentError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'raises error when adapter argument is not an instance of AbstractAdapter' do
|
37
|
+
expect{ NoGo::ProxyAdapter.new(Object.new) }.to raise_error(ArgumentError)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'initializes @strategy to :raise' do
|
41
|
+
NoGo::ProxyAdapter.new(adapter).instance_variable_get(:@strategy).should == :raise
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'passes undefined instance method calls through to the adapter' do
|
46
|
+
adapter.should_receive(:method_name).with(:arg)
|
47
|
+
proxy_adapter.method_name :arg
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'initializes enabled to false' do
|
51
|
+
NoGo::ProxyAdapter.new(adapter).enabled.should == false
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'initializes enabled_state_stack to []' do
|
55
|
+
NoGo::ProxyAdapter.new(adapter).instance_variable_get(:@enabled_state_stack).should == []
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#proxied_adapter' do
|
59
|
+
it 'returns adapter' do
|
60
|
+
proxy_adapter.proxied_adapter.should == adapter
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#is_a?' do
|
65
|
+
it 'invokes method on proxied adapter' do
|
66
|
+
adapter.stub(:is_a?).with(ActiveRecord::ConnectionAdapters::AbstractAdapter) { true }
|
67
|
+
adapter.should_receive(:is_a?).with(Class)
|
68
|
+
proxy_adapter.is_a?(Class)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#pop_enabled_state' do
|
73
|
+
it 'assigns true to enabled when last value on the stack is true' do
|
74
|
+
proxy_adapter.instance_variable_set(:@enabled_state_stack, [true])
|
75
|
+
proxy_adapter.enabled = nil
|
76
|
+
proxy_adapter.pop_enabled_state
|
77
|
+
proxy_adapter.enabled.should == true
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'assigns false to enabled when last value on the stack is false' do
|
81
|
+
proxy_adapter.instance_variable_set(:@enabled_state_stack, [false])
|
82
|
+
proxy_adapter.enabled = nil
|
83
|
+
proxy_adapter.pop_enabled_state
|
84
|
+
proxy_adapter.enabled.should == false
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'assigns false to enabled when stack is empty' do
|
88
|
+
proxy_adapter.instance_variable_set(:@enabled_state_stack, [])
|
89
|
+
proxy_adapter.enabled = nil
|
90
|
+
proxy_adapter.pop_enabled_state
|
91
|
+
proxy_adapter.enabled.should == false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#push_enabled_state' do
|
96
|
+
it 'pushes true to the stack when enabled is true' do
|
97
|
+
proxy_adapter.instance_variable_set(:@enabled_state_stack, [])
|
98
|
+
proxy_adapter.enabled = true
|
99
|
+
proxy_adapter.push_enabled_state
|
100
|
+
proxy_adapter.instance_variable_get(:@enabled_state_stack).should == [true]
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'pushes false to the stack when enabled is false' do
|
104
|
+
proxy_adapter.instance_variable_set(:@enabled_state_stack, [])
|
105
|
+
proxy_adapter.enabled = false
|
106
|
+
proxy_adapter.push_enabled_state
|
107
|
+
proxy_adapter.instance_variable_get(:@enabled_state_stack).should == [false]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#strategy' do
|
112
|
+
NoGo::ProxyAdapter::StrategyOptions.each do |strategy_option|
|
113
|
+
it "returns :#{strategy_option}" do
|
114
|
+
proxy_adapter.instance_variable_set(:@strategy, strategy_option)
|
115
|
+
proxy_adapter.strategy.should == strategy_option
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#strategy=' do
|
121
|
+
NoGo::ProxyAdapter::StrategyOptions.each do |strategy_option|
|
122
|
+
it "sets :#{strategy_option} strategy" do
|
123
|
+
proxy_adapter.strategy = strategy_option
|
124
|
+
proxy_adapter.strategy.should == strategy_option
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'raises an exception if the strategy option is not valid' do
|
129
|
+
expect{ proxy_adapter.strategy = :invalid_option }.to raise_error(ArgumentError)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '#pass_through' do
|
134
|
+
it 'uoea' do
|
135
|
+
proxy_adapter.should_receive(:bleh).with(:m, :a)
|
136
|
+
proxy_adapter.bleh :m, :a
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'sends method call and arguments to @adapter' do
|
140
|
+
adapter.should_receive(:method_name).with(:arg)
|
141
|
+
proxy_adapter.send :pass_through, :method_name, :arg
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'when strategy is :warn' do
|
145
|
+
before :each do
|
146
|
+
proxy_adapter.strategy = :warn
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'invokes #warn when enabled' do
|
150
|
+
proxy_adapter.enabled = true
|
151
|
+
adapter.stub(:method_name)
|
152
|
+
proxy_adapter.should_receive(:warn).with(:method_name, :arg)
|
153
|
+
proxy_adapter.send :pass_through, :method_name, :arg
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'does not invoke #warn when disabled' do
|
157
|
+
proxy_adapter.enabled = false
|
158
|
+
adapter.stub(:method_name)
|
159
|
+
proxy_adapter.should_not_receive(:warn).with(:method_name, :arg)
|
160
|
+
proxy_adapter.send :pass_through, :method_name, :arg
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'does not invoke #warn when strategy is :pass_through' do
|
165
|
+
proxy_adapter.strategy = :pass_through
|
166
|
+
adapter.stub(:method_name)
|
167
|
+
proxy_adapter.should_not_receive(:warn).with(:method_name, :arg)
|
168
|
+
proxy_adapter.send :pass_through, :method_name, :arg
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '#raise_or_pass_through' do
|
173
|
+
context 'when strategy is set to :raise' do
|
174
|
+
before :each do
|
175
|
+
proxy_adapter.strategy = :raise
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'raises an exception when enabled' do
|
179
|
+
proxy_adapter.enabled = true
|
180
|
+
expect{ proxy_adapter.send :raise_or_pass_through, :method_name, :arg }.to raise_error
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'does not raise an exception when disabled' do
|
184
|
+
proxy_adapter.enabled = false
|
185
|
+
adapter.stub(:method_name)
|
186
|
+
expect{ proxy_adapter.send :raise_or_pass_through, :method_name, :arg }.to_not raise_error
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'when strategy is set to :warn' do
|
191
|
+
before :each do
|
192
|
+
proxy_adapter.strategy = :warn
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'passes method call through to the adapter' do
|
196
|
+
proxy_adapter.should_receive(:pass_through).with(:method_name, :arg)
|
197
|
+
proxy_adapter.send :raise_or_pass_through, :method_name, :arg
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'when strategy is set to :pass_through' do
|
202
|
+
before :each do
|
203
|
+
proxy_adapter.strategy = :pass_through
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'passes method call through to the adapter' do
|
207
|
+
proxy_adapter.should_receive(:pass_through).with(:method_name, :arg)
|
208
|
+
proxy_adapter.send :raise_or_pass_through, :method_name, :arg
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Overridden methods -------------------------------------------------------
|
214
|
+
|
215
|
+
describe '#execute' do
|
216
|
+
it 'invokes #raise_or_pass_through' do
|
217
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:execute, 'SELECT COUNT(*) FROM tables;', 'name')
|
218
|
+
proxy_adapter.execute('SELECT COUNT(*) FROM tables;', 'name')
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'invokes #pass_through if SQL is BEGIN' do
|
222
|
+
proxy_adapter.should_receive(:pass_through).with(:execute, 'BEGIN', 'name')
|
223
|
+
proxy_adapter.execute('BEGIN', 'name')
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'invokes #pass_through if SQL is ROLLBACK' do
|
227
|
+
proxy_adapter.should_receive(:pass_through).with(:execute, 'ROLLBACK', 'name')
|
228
|
+
proxy_adapter.execute('ROLLBACK', 'name')
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'invokes #pass_through if SQL is SAVEPOINT' do
|
232
|
+
proxy_adapter.should_receive(:pass_through).with(:execute, 'SAVEPOINT', 'name')
|
233
|
+
proxy_adapter.execute('SAVEPOINT', 'name')
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe '#insert' do
|
238
|
+
it 'invokes #raise_or_pass_through' do
|
239
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(
|
240
|
+
:insert, 'SQL', 'name', 'pk', 'id_value', 'sequence_name', ['bind']
|
241
|
+
)
|
242
|
+
proxy_adapter.insert('SQL', 'name', 'pk', 'id_value', 'sequence_name', ['bind'])
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe '#update' do
|
247
|
+
it 'invokes #raise_or_pass_through' do
|
248
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:update, 'SQL', 'name', [])
|
249
|
+
proxy_adapter.send(:update, 'SQL', 'name', [])
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe '#delete' do
|
254
|
+
it 'invokes #raise_or_pass_through' do
|
255
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:delete, 'SQL', 'name', [])
|
256
|
+
proxy_adapter.send(:delete, 'SQL', 'name', [])
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
describe '#select_rows' do
|
261
|
+
it 'invokes #raise_or_pass_through' do
|
262
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:select_rows, 'SQL', 'name')
|
263
|
+
proxy_adapter.select_rows('SQL', 'name')
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe '#select' do
|
268
|
+
it 'invokes #raise_or_pass_through' do
|
269
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:select, 'SQL', 'name')
|
270
|
+
proxy_adapter.send(:select, 'SQL', 'name')
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe '#select_all' do
|
275
|
+
it 'invokes #raise_or_pass_through' do
|
276
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:select_all, 'SQL', 'name', [])
|
277
|
+
proxy_adapter.send(:select_all, 'SQL', 'name', [])
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
describe '#select_one' do
|
282
|
+
it 'invokes #raise_or_pass_through' do
|
283
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:select_one, 'SQL', 'name')
|
284
|
+
proxy_adapter.send(:select_one, 'SQL', 'name')
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
describe '#select_value' do
|
289
|
+
it 'invokes #raise_or_pass_through' do
|
290
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:select_value, 'SQL', 'name')
|
291
|
+
proxy_adapter.send(:select_value, 'SQL', 'name')
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
describe '#select_values' do
|
296
|
+
it 'invokes #raise_or_pass_through' do
|
297
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:select_values, 'SQL', 'name')
|
298
|
+
proxy_adapter.send(:select_values, 'SQL', 'name')
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe '#exec_query' do
|
303
|
+
it 'invokes #raise_or_pass_through' do
|
304
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:exec_query, 'SQL', 'name', [])
|
305
|
+
proxy_adapter.send(:exec_query, 'SQL', 'name', [])
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
describe '#exec_insert' do
|
310
|
+
it 'invokes #raise_or_pass_through' do
|
311
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:exec_insert, 'SQL', 'name', [])
|
312
|
+
proxy_adapter.send(:exec_insert, 'SQL', 'name', [])
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
describe '#exec_delete' do
|
317
|
+
it 'invokes #raise_or_pass_through' do
|
318
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:exec_delete, 'SQL', 'name', [])
|
319
|
+
proxy_adapter.send(:exec_delete, 'SQL', 'name', [])
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe '#exec_update' do
|
324
|
+
it 'invokes #raise_or_pass_through' do
|
325
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:exec_update, 'SQL', 'name', [])
|
326
|
+
proxy_adapter.send(:exec_update, 'SQL', 'name', [])
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
describe '#insert_sql' do
|
331
|
+
it 'invokes #raise_or_pass_through' do
|
332
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:'insert_sql', 'SQL', 'name', 'pk', 'id_value', 'sequence_name', ['bind'])
|
333
|
+
proxy_adapter.send(:'insert_sql', 'SQL', 'name', 'pk', 'id_value', 'sequence_name', ['bind'])
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe '#delete_sql' do
|
338
|
+
it 'invokes #raise_or_pass_through' do
|
339
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:'delete_sql', 'SQL', 'name')
|
340
|
+
proxy_adapter.send(:'delete_sql', 'SQL', 'name')
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
describe '#update_sql' do
|
345
|
+
it 'invokes #raise_or_pass_through' do
|
346
|
+
proxy_adapter.should_receive(:raise_or_pass_through).with(:'update_sql', 'SQL', 'name')
|
347
|
+
proxy_adapter.send(:'update_sql', 'SQL', 'name')
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
# --------------------------------------------------------------------------
|
352
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require_relative '../../lib/nogo/rspec/dsl'
|
3
|
+
|
4
|
+
describe NoGo::RSpec::DSL do
|
5
|
+
describe '::nogo_example_group' do
|
6
|
+
it 'returns an rspec example group' do
|
7
|
+
dummy_example_group = mock
|
8
|
+
block = Proc.new {}
|
9
|
+
RSpec::Core::ExampleGroup.stub(:subclass).and_return(dummy_example_group)
|
10
|
+
NoGo::RSpec::DSL.nogo_example_group(&block).should == dummy_example_group
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'executed' do
|
14
|
+
it 'invokes nogo before all block' do
|
15
|
+
dummy = mock
|
16
|
+
dummy.should_receive(:execute)
|
17
|
+
block = Proc.new { dummy.execute }
|
18
|
+
NoGo::RSpec::DSL.stub(:NogoBeforeAllBlock).and_return(block)
|
19
|
+
NoGo::RSpec::DSL.nogo_example_group{ it{ :example_to_trigger_callbacks }}.run mock.as_null_object
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'invokes nogo after all block' do
|
23
|
+
dummy = mock
|
24
|
+
dummy.should_receive(:execute)
|
25
|
+
block = Proc.new { dummy.execute }
|
26
|
+
NoGo::RSpec::DSL.stub(:NogoAfterAllBlock).and_return(block)
|
27
|
+
NoGo::RSpec::DSL.nogo_example_group{ it{ :example_to_trigger_callbacks}}.run mock.as_null_object
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'invokes instance eval with example group block' do
|
31
|
+
dummy = mock
|
32
|
+
dummy.should_receive(:execute)
|
33
|
+
block = Proc.new { dummy.execute }
|
34
|
+
NoGo::RSpec::DSL.nogo_example_group(&block).run mock.as_null_object
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'NogoBeforeAllBlock' do
|
40
|
+
it 'invokes NoGo::Connection::push_enabled_state' do
|
41
|
+
NoGo::Connection.should_receive(:push_enabled_state)
|
42
|
+
NoGo::Connection.stub(:enabled=)
|
43
|
+
NoGo::RSpec::DSL::NogoBeforeAllBlock.call
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'enables proxy adapter' do
|
47
|
+
NoGo::Connection.stub(:push_enabled_state)
|
48
|
+
NoGo::Connection.should_receive(:enabled=).with(true)
|
49
|
+
NoGo::RSpec::DSL::NogoBeforeAllBlock.call
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'NogoAfterAllBlock' do
|
54
|
+
it 'invokes NoGo::Connection::pop_enabled_state' do
|
55
|
+
NoGo::Connection.should_receive(:pop_enabled_state)
|
56
|
+
NoGo::RSpec::DSL::NogoAfterAllBlock.call
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'nogo' do
|
62
|
+
it 'registers a nogo example group' do
|
63
|
+
dummy_example_group = mock
|
64
|
+
dummy_example_group.should_receive(:register)
|
65
|
+
NoGo::RSpec::DSL.stub(:nogo_example_group).and_return(dummy_example_group)
|
66
|
+
nogo{}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'database_restricted' do
|
71
|
+
it 'registers a nogo example group' do
|
72
|
+
dummy_example_group = mock
|
73
|
+
dummy_example_group.should_receive(:register)
|
74
|
+
NoGo::RSpec::DSL.stub(:nogo_example_group).and_return(dummy_example_group)
|
75
|
+
database_restricted{}
|
76
|
+
end
|
77
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nogo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0.beta
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Andy Ogzewalla
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-05 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &70138985281760 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.7.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70138985281760
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activerecord
|
27
|
+
requirement: &70138985281220 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70138985281220
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70138985280720 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.7.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70138985280720
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: activerecord
|
49
|
+
requirement: &70138985280140 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70138985280140
|
58
|
+
description: A library that lets you know when your code touches your database
|
59
|
+
email:
|
60
|
+
- andyogzewalla@gmail.com
|
61
|
+
executables: []
|
62
|
+
extensions: []
|
63
|
+
extra_rdoc_files: []
|
64
|
+
files:
|
65
|
+
- .gitignore
|
66
|
+
- Gemfile
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- lib/active_record/connection_adapters/nogo_adapter.rb
|
70
|
+
- lib/active_record/import.rb
|
71
|
+
- lib/nogo.rb
|
72
|
+
- lib/nogo/abstract_method_overrides.rb
|
73
|
+
- lib/nogo/connection.rb
|
74
|
+
- lib/nogo/proxy_adapter.rb
|
75
|
+
- lib/nogo/rspec.rb
|
76
|
+
- lib/nogo/rspec/dsl.rb
|
77
|
+
- lib/nogo/version.rb
|
78
|
+
- nogo.gemspec
|
79
|
+
- spec/active_record/connection_adapters/nogo_adapter_spec.rb
|
80
|
+
- spec/nogo/connection_spec.rb
|
81
|
+
- spec/nogo/proxy_adapter_spec.rb
|
82
|
+
- spec/rspec/dsl_spec.rb
|
83
|
+
- spec/spec_helper.rb
|
84
|
+
homepage: ''
|
85
|
+
licenses: []
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>'
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.3.1
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.8.11
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: A library that lets you know when your code touches your database
|
108
|
+
test_files:
|
109
|
+
- spec/active_record/connection_adapters/nogo_adapter_spec.rb
|
110
|
+
- spec/nogo/connection_spec.rb
|
111
|
+
- spec/nogo/proxy_adapter_spec.rb
|
112
|
+
- spec/rspec/dsl_spec.rb
|
113
|
+
- spec/spec_helper.rb
|