activerecord-nulldb-adapter 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/Gemfile +3 -0
- data/Gemfile.lock +46 -0
- data/README.rdoc +3 -1
- data/Rakefile +5 -77
- data/VERSION +1 -1
- data/activerecord-nulldb-adapter.gemspec +9 -11
- data/lib/active_record/connection_adapters/nulldb_adapter.rb +80 -7
- data/lib/activerecord-nulldb-adapter.rb +1 -0
- data/lib/nulldb.rb +2 -0
- data/lib/nulldb_rspec.rb +4 -8
- data/spec/nulldb_spec.rb +66 -7
- metadata +55 -74
- data/ginger_scenarios.rb +0 -27
data/.gitignore
CHANGED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
activerecord-nulldb-adapter (0.2.1)
|
5
|
+
activerecord (>= 2.0.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activemodel (3.2.3)
|
11
|
+
activesupport (= 3.2.3)
|
12
|
+
builder (~> 3.0.0)
|
13
|
+
activerecord (3.2.3)
|
14
|
+
activemodel (= 3.2.3)
|
15
|
+
activesupport (= 3.2.3)
|
16
|
+
arel (~> 3.0.2)
|
17
|
+
tzinfo (~> 0.3.29)
|
18
|
+
activesupport (3.2.3)
|
19
|
+
i18n (~> 0.6)
|
20
|
+
multi_json (~> 1.0)
|
21
|
+
appraisal (0.4.1)
|
22
|
+
bundler
|
23
|
+
rake
|
24
|
+
arel (3.0.2)
|
25
|
+
builder (3.0.0)
|
26
|
+
diff-lcs (1.1.3)
|
27
|
+
i18n (0.6.0)
|
28
|
+
multi_json (1.3.4)
|
29
|
+
rake (0.9.2.2)
|
30
|
+
rspec (2.10.0)
|
31
|
+
rspec-core (~> 2.10.0)
|
32
|
+
rspec-expectations (~> 2.10.0)
|
33
|
+
rspec-mocks (~> 2.10.0)
|
34
|
+
rspec-core (2.10.0)
|
35
|
+
rspec-expectations (2.10.0)
|
36
|
+
diff-lcs (~> 1.1.3)
|
37
|
+
rspec-mocks (2.10.1)
|
38
|
+
tzinfo (0.3.33)
|
39
|
+
|
40
|
+
PLATFORMS
|
41
|
+
ruby
|
42
|
+
|
43
|
+
DEPENDENCIES
|
44
|
+
activerecord-nulldb-adapter!
|
45
|
+
appraisal
|
46
|
+
rspec (>= 1.2.9)
|
data/README.rdoc
CHANGED
@@ -49,6 +49,8 @@ include the same module inside a context:
|
|
49
49
|
# ...
|
50
50
|
end
|
51
51
|
|
52
|
+
If you want to have NullDB enabled by default but disabled for particular contexts then (see this post)[http://andywaite.com/2011/5/18/rspec-disable-nulldb]
|
53
|
+
|
52
54
|
NullDB::Rspec provides some custom matcher support for verifying
|
53
55
|
expectations about interactions with the database:
|
54
56
|
|
@@ -88,7 +90,7 @@ touch the database. The biggest is probably speed of execution - unit
|
|
88
90
|
tests must be fast for test-driven development to be practical.
|
89
91
|
Another is separation of concerns: unit tests should be exercising
|
90
92
|
only the business logic contained in your models, not ActiveRecord.
|
91
|
-
For more on why testing-sans-database is a
|
93
|
+
For more on why testing-sans-database is a good idea, see:
|
92
94
|
http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database.
|
93
95
|
|
94
96
|
NullDB is one way to separate your unit tests from the database. It
|
data/Rakefile
CHANGED
@@ -1,82 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'appraisal'
|
2
|
+
require 'rspec/core/rake_task'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name = 'activerecord-nulldb-adapter'
|
8
|
-
gem.summary = %Q{The Null Object pattern as applied to ActiveRecord database adapters}
|
9
|
-
gem.description = %Q{A database backend that translates database interactions into no-ops. Using NullDB enables you to test your model business logic - including after_save hooks - without ever touching a real database.}
|
10
|
-
gem.email = "myron.marston@gmail.com"
|
11
|
-
gem.homepage = "http://github.com/nulldb/nulldb"
|
12
|
-
gem.authors = ["Avdi Grimm", "Myron Marston"]
|
13
|
-
gem.rubyforge_project = "nulldb"
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
task :default => :spec
|
14
6
|
|
15
|
-
|
16
|
-
gem.add_development_dependency "rspec", ">= 1.2.9"
|
17
|
-
|
18
|
-
gem.files.exclude 'vendor/ginger'
|
19
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
|
-
end
|
21
|
-
Jeweler::GemcutterTasks.new
|
22
|
-
Jeweler::RubyforgeTasks.new do |rubyforge|
|
23
|
-
rubyforge.doc_task = "rdoc"
|
24
|
-
end
|
25
|
-
rescue LoadError
|
26
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
27
|
-
end
|
28
|
-
|
29
|
-
# We want to test ActiveRecord 3 against RSpec 2.x, and
|
30
|
-
# prior versions of AR against RSpec 1.x. The task
|
31
|
-
# definitions are different, and in order to allow ginger
|
32
|
-
# to invoke a single task (:spec_for_ginger) that runs the
|
33
|
-
# specs against the right version of RSpec, we dynamically
|
34
|
-
# define the spec task with this method.
|
35
|
-
def define_specs_task
|
36
|
-
require 'active_record/version'
|
37
|
-
|
38
|
-
if ActiveRecord::VERSION::MAJOR > 2
|
39
|
-
# rspec 2
|
40
|
-
require "rspec/core/rake_task"
|
41
|
-
RSpec::Core::RakeTask.new(:specs) do |spec|
|
42
|
-
spec.pattern = "spec/*_spec.rb"
|
43
|
-
end
|
44
|
-
else
|
45
|
-
# rspec 1
|
46
|
-
require 'spec/rake/spectask'
|
47
|
-
Spec::Rake::SpecTask.new(:specs) do |spec|
|
48
|
-
spec.libs << 'lib' << 'spec'
|
49
|
-
spec.spec_files = FileList['spec/**/*_spec.rb']
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
desc "Run the specs"
|
55
|
-
task :spec do
|
56
|
-
define_specs_task
|
57
|
-
Rake::Task[:specs].invoke
|
58
|
-
end
|
59
|
-
|
60
|
-
task :spec_for_ginger do
|
61
|
-
$LOAD_PATH << File.join(*%w[vendor ginger lib])
|
62
|
-
require 'ginger'
|
63
|
-
define_specs_task
|
64
|
-
Rake::Task[:specs].invoke
|
65
|
-
end
|
66
|
-
|
67
|
-
task :spec => :check_dependencies if defined?(Jeweler)
|
68
|
-
|
69
|
-
desc 'Run ginger tests'
|
70
|
-
task :ginger do
|
71
|
-
$LOAD_PATH << File.join(*%w[vendor ginger lib])
|
72
|
-
ARGV.clear
|
73
|
-
ARGV << 'spec_for_ginger'
|
74
|
-
load File.join(*%w[vendor ginger bin ginger])
|
75
|
-
end
|
76
|
-
|
77
|
-
task :default => :ginger
|
78
|
-
|
79
|
-
require 'rake/rdoctask'
|
7
|
+
require 'rdoc/task'
|
80
8
|
Rake::RDocTask.new do |rd|
|
81
9
|
rd.main = "README.rdoc"
|
82
10
|
rd.rdoc_files.include("README.rdoc", "LICENSE", "lib/**/*.rb")
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
@@ -1,15 +1,10 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
1
|
Gem::Specification.new do |s|
|
7
2
|
s.name = %q{activerecord-nulldb-adapter}
|
8
|
-
s.version = "0.2.
|
3
|
+
s.version = "0.2.2"
|
9
4
|
|
10
5
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
6
|
s.authors = ["Avdi Grimm", "Myron Marston"]
|
12
|
-
s.date = %q{
|
7
|
+
s.date = %q{2011-09-12}
|
13
8
|
s.description = %q{A database backend that translates database interactions into no-ops. Using NullDB enables you to test your model business logic - including after_save hooks - without ever touching a real database.}
|
14
9
|
s.email = %q{myron.marston@gmail.com}
|
15
10
|
s.extra_rdoc_files = [
|
@@ -18,12 +13,15 @@ Gem::Specification.new do |s|
|
|
18
13
|
]
|
19
14
|
s.files = [
|
20
15
|
".gitignore",
|
16
|
+
"Gemfile",
|
17
|
+
"Gemfile.lock",
|
21
18
|
"LICENSE",
|
22
19
|
"README.rdoc",
|
23
20
|
"Rakefile",
|
24
21
|
"VERSION",
|
25
22
|
"activerecord-nulldb-adapter.gemspec",
|
26
|
-
"
|
23
|
+
"lib/nulldb.rb",
|
24
|
+
"lib/activerecord-nulldb-adapter.rb",
|
27
25
|
"lib/active_record/connection_adapters/nulldb_adapter.rb",
|
28
26
|
"lib/nulldb/arel_compiler.rb",
|
29
27
|
"lib/nulldb_rspec.rb",
|
@@ -46,14 +44,14 @@ Gem::Specification.new do |s|
|
|
46
44
|
s.specification_version = 3
|
47
45
|
|
48
46
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
-
s.add_runtime_dependency(%q<activerecord>, [">= 2.0.0"
|
47
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 2.0.0"])
|
50
48
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
51
49
|
else
|
52
|
-
s.add_dependency(%q<activerecord>, [">= 2.0.0"
|
50
|
+
s.add_dependency(%q<activerecord>, [">= 2.0.0"])
|
53
51
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
54
52
|
end
|
55
53
|
else
|
56
|
-
s.add_dependency(%q<activerecord>, [">= 2.0.0"
|
54
|
+
s.add_dependency(%q<activerecord>, [">= 2.0.0"])
|
57
55
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
58
56
|
end
|
59
57
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'logger'
|
2
2
|
require 'stringio'
|
3
3
|
require 'singleton'
|
4
|
+
require 'pathname'
|
4
5
|
require 'active_record/connection_adapters/abstract_adapter'
|
6
|
+
require 'nulldb/core'
|
5
7
|
|
6
8
|
unless respond_to?(:tap)
|
7
9
|
class Object
|
@@ -12,6 +14,22 @@ unless respond_to?(:tap)
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
17
|
+
unless respond_to?(:try)
|
18
|
+
class Object
|
19
|
+
def try(*a, &b)
|
20
|
+
if a.empty? && block_given?
|
21
|
+
yield self
|
22
|
+
else
|
23
|
+
__send__(*a, &b)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class NilClass
|
29
|
+
def try(*args); nil; end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
15
33
|
class ActiveRecord::Base
|
16
34
|
# Instantiate a new NullDB connection. Used by ActiveRecord internally.
|
17
35
|
def self.nulldb_connection(config)
|
@@ -67,12 +85,21 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter <
|
|
67
85
|
|
68
86
|
TableDefinition = ActiveRecord::ConnectionAdapters::TableDefinition
|
69
87
|
|
88
|
+
class IndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders)
|
89
|
+
end
|
90
|
+
|
70
91
|
class NullObject
|
71
92
|
def method_missing(*args, &block)
|
72
93
|
nil
|
73
94
|
end
|
74
95
|
end
|
75
96
|
|
97
|
+
class EmptyResult
|
98
|
+
def rows
|
99
|
+
[]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
76
103
|
# A convenience method for integratinginto RSpec. See README for example of
|
77
104
|
# use.
|
78
105
|
def self.insinuate_into_spec(config)
|
@@ -93,9 +120,11 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter <
|
|
93
120
|
@logger = Logger.new(@log)
|
94
121
|
@last_unique_id = 0
|
95
122
|
@tables = {'schema_info' => TableDefinition.new(nil)}
|
123
|
+
@indexes = Hash.new { |hash, key| hash[key] = [] }
|
96
124
|
@schema_path = config.fetch(:schema){ "db/schema.rb" }
|
97
125
|
@config = config.merge(:adapter => :nulldb)
|
98
126
|
super(nil, @logger)
|
127
|
+
@visitor = Arel::Visitors::ToSql.new self if defined?(Arel::Visitors::ToSql)
|
99
128
|
end
|
100
129
|
|
101
130
|
# A log of every statement that has been "executed" by this connection adapter
|
@@ -136,6 +165,35 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter <
|
|
136
165
|
@tables[table_name] = table_definition
|
137
166
|
end
|
138
167
|
|
168
|
+
def add_index(table_name, column_names, options = {})
|
169
|
+
index_name, index_type, ignore = add_index_options(table_name, column_names, options)
|
170
|
+
@indexes[table_name] << IndexDefinition.new(table_name, index_name, (index_type == 'UNIQUE'), column_names, [], [])
|
171
|
+
end
|
172
|
+
|
173
|
+
unless instance_methods.include? :add_index_options
|
174
|
+
def add_index_options(table_name, column_name, options = {})
|
175
|
+
column_names = Array.wrap(column_name)
|
176
|
+
index_name = index_name(table_name, :column => column_names)
|
177
|
+
|
178
|
+
if Hash === options # legacy support, since this param was a string
|
179
|
+
index_type = options[:unique] ? "UNIQUE" : ""
|
180
|
+
index_name = options[:name].to_s if options.key?(:name)
|
181
|
+
else
|
182
|
+
index_type = options
|
183
|
+
end
|
184
|
+
|
185
|
+
if index_name.length > index_name_length
|
186
|
+
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters"
|
187
|
+
end
|
188
|
+
if index_name_exists?(table_name, index_name, false)
|
189
|
+
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
|
190
|
+
end
|
191
|
+
index_columns = quoted_columns_for_index(column_names, options).join(", ")
|
192
|
+
|
193
|
+
[index_name, index_type, index_columns]
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
139
197
|
def add_fk_constraint(*args)
|
140
198
|
# NOOP
|
141
199
|
end
|
@@ -153,7 +211,12 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter <
|
|
153
211
|
def columns(table_name, name = nil)
|
154
212
|
if @tables.size <= 1
|
155
213
|
ActiveRecord::Migration.verbose = false
|
156
|
-
|
214
|
+
schema_path = if Pathname(@schema_path).absolute?
|
215
|
+
@schema_path
|
216
|
+
else
|
217
|
+
File.join(NullDB.configuration.project_root, @schema_path)
|
218
|
+
end
|
219
|
+
Kernel.load(schema_path)
|
157
220
|
end
|
158
221
|
|
159
222
|
if table = @tables[table_name]
|
@@ -170,18 +233,28 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter <
|
|
170
233
|
end
|
171
234
|
end
|
172
235
|
|
236
|
+
# Retrieve table indexes as defined by the schema
|
237
|
+
def indexes(table_name, name = nil)
|
238
|
+
@indexes[table_name]
|
239
|
+
end
|
240
|
+
|
173
241
|
def execute(statement, name = nil)
|
174
242
|
self.execution_log << Statement.new(entry_point, statement)
|
175
243
|
NullObject.new
|
176
244
|
end
|
177
245
|
|
246
|
+
def exec_query(statement, name = 'SQL', binds = [])
|
247
|
+
self.execution_log << Statement.new(entry_point, statement)
|
248
|
+
EmptyResult.new
|
249
|
+
end
|
250
|
+
|
178
251
|
def select_rows(statement, name = nil)
|
179
252
|
[].tap do
|
180
253
|
self.execution_log << Statement.new(entry_point, statement)
|
181
254
|
end
|
182
255
|
end
|
183
256
|
|
184
|
-
def insert(statement, name = nil, primary_key = nil, object_id = nil, sequence_name = nil)
|
257
|
+
def insert(statement, name = nil, primary_key = nil, object_id = nil, sequence_name = nil, binds = [])
|
185
258
|
(object_id || next_unique_id).tap do
|
186
259
|
with_entry_point(:insert) do
|
187
260
|
super(statement, name, primary_key, object_id, sequence_name)
|
@@ -190,19 +263,19 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter <
|
|
190
263
|
end
|
191
264
|
alias :create :insert
|
192
265
|
|
193
|
-
def update(statement, name=nil)
|
266
|
+
def update(statement, name=nil, binds = [])
|
194
267
|
with_entry_point(:update) do
|
195
268
|
super(statement, name)
|
196
269
|
end
|
197
270
|
end
|
198
271
|
|
199
|
-
def delete(statement, name=nil)
|
272
|
+
def delete(statement, name=nil, binds = [])
|
200
273
|
with_entry_point(:delete) do
|
201
274
|
super(statement, name)
|
202
275
|
end
|
203
276
|
end
|
204
277
|
|
205
|
-
def select_all(statement, name=nil)
|
278
|
+
def select_all(statement, name=nil, binds = [])
|
206
279
|
with_entry_point(:select_all) do
|
207
280
|
super(statement, name)
|
208
281
|
end
|
@@ -221,12 +294,12 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter <
|
|
221
294
|
end
|
222
295
|
|
223
296
|
def primary_key(table_name)
|
224
|
-
columns(table_name).detect { |col| col.sql_type == :primary_key }.name
|
297
|
+
columns(table_name).detect { |col| col.sql_type == :primary_key }.try(:name)
|
225
298
|
end
|
226
299
|
|
227
300
|
protected
|
228
301
|
|
229
|
-
def select(statement, name)
|
302
|
+
def select(statement, name, binds = [])
|
230
303
|
[].tap do
|
231
304
|
self.execution_log << Statement.new(entry_point, statement)
|
232
305
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'nulldb'
|
data/lib/nulldb.rb
ADDED
data/lib/nulldb_rspec.rb
CHANGED
@@ -16,7 +16,7 @@ module NullDB::RSpec::NullifiedDatabase
|
|
16
16
|
|
17
17
|
def matches?(connection)
|
18
18
|
log = connection.execution_log_since_checkpoint
|
19
|
-
if entry_point == :anything
|
19
|
+
if @entry_point == :anything
|
20
20
|
not log.empty?
|
21
21
|
else
|
22
22
|
log.include?(NullDBAdapter::Statement.new(@entry_point))
|
@@ -81,14 +81,10 @@ module NullDB::RSpec::NullifiedDatabase
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def self.nullify_contextually?(other)
|
84
|
-
|
85
|
-
|
86
|
-
other.ancestors.include?(rspec_root::Rails::RailsExampleGroup)
|
84
|
+
if defined?(RSpec)
|
85
|
+
other < RSpec::Core::ExampleGroup
|
87
86
|
else
|
88
|
-
other.
|
89
|
-
other.ancestors.include?(rspec_root::Rails::ControllerExampleGroup) ||
|
90
|
-
other.ancestors.include?(rspec_root::Rails::ViewExampleGroup) ||
|
91
|
-
other.ancestors.include?(rspec_root::Rails::HelperExampleGroup)
|
87
|
+
other.is_a? Spec::ExampleGroup
|
92
88
|
end
|
93
89
|
end
|
94
90
|
|
data/spec/nulldb_spec.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
-
$LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. vendor ginger lib])
|
4
|
-
require 'ginger'
|
5
3
|
require 'active_record'
|
6
4
|
require 'active_record/version'
|
7
5
|
$: << File.join(File.dirname(__FILE__), "..", "lib")
|
@@ -24,11 +22,7 @@ end
|
|
24
22
|
class TablelessModel < ActiveRecord::Base
|
25
23
|
end
|
26
24
|
|
27
|
-
|
28
|
-
def self.root
|
29
|
-
'Rails.root'
|
30
|
-
end
|
31
|
-
end
|
25
|
+
NullDB.configure {|ndb| ndb.project_root = 'Rails.root'}
|
32
26
|
|
33
27
|
describe "NullDB with no schema pre-loaded" do
|
34
28
|
before :each do
|
@@ -76,6 +70,15 @@ describe "NullDB" do
|
|
76
70
|
t.decimal :salary
|
77
71
|
end
|
78
72
|
|
73
|
+
create_table(:employees_widgets, :id => false) do |t|
|
74
|
+
t.integer :employee_id
|
75
|
+
t.integer :widget_id
|
76
|
+
end
|
77
|
+
|
78
|
+
add_index "employees", ["name"], :name => "index_employees_on_name"
|
79
|
+
add_index "employees", ["employee_number"], :name => "index_employees_on_employee_number", :unique => true
|
80
|
+
add_index "employees_widgets", ["employee_id", "widget_id"], :name => "my_index"
|
81
|
+
|
79
82
|
add_fk_constraint "foo", "bar", "baz", "buz", "bungle"
|
80
83
|
add_pk_constraint "foo", "bar", {}, "baz", "buz"
|
81
84
|
end
|
@@ -108,6 +111,10 @@ describe "NullDB" do
|
|
108
111
|
ActiveRecord::Base.connection.primary_key('employees').should == 'id'
|
109
112
|
end
|
110
113
|
|
114
|
+
it "should return a nil primary key on habtm" do
|
115
|
+
ActiveRecord::Base.connection.primary_key('employees_widgets').should be_nil
|
116
|
+
end
|
117
|
+
|
111
118
|
it "should return an empty array of columns for a table-less model" do
|
112
119
|
TablelessModel.columns.should == []
|
113
120
|
end
|
@@ -225,9 +232,61 @@ describe "NullDB" do
|
|
225
232
|
col.should_not be_nil
|
226
233
|
col.type.should == col_type
|
227
234
|
end
|
235
|
+
|
236
|
+
|
237
|
+
it "should support adding indexes" do
|
238
|
+
Employee.connection.indexes('employees').size.should == 2
|
239
|
+
Employee.connection.indexes('employees_widgets').size.should == 1
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should support unique indexes" do
|
243
|
+
Employee.connection.indexes('employees').detect{|idx| idx.columns == ["name"]}.unique.should be_false
|
244
|
+
Employee.connection.indexes('employees').detect{|idx| idx.columns == ["employee_number"]}.unique.should be_true
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should support multi-column indexes" do
|
248
|
+
Employee.connection.indexes('employees_widgets').first.columns.should == ["employee_id", "widget_id"]
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should support custom index names" do
|
252
|
+
Employee.connection.indexes('employees_widgets').first.name.should == 'my_index'
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'should handle ActiveRecord::ConnectionNotEstablished' do
|
256
|
+
ActiveRecord::Base.should_receive(:connection_pool).and_raise(ActiveRecord::ConnectionNotEstablished)
|
257
|
+
lambda { NullDB.nullify }.should_not raise_error(ActiveRecord::ConnectionNotEstablished)
|
258
|
+
end
|
228
259
|
end
|
229
260
|
|
261
|
+
# need a fallback db for contextual nullification
|
262
|
+
ActiveRecord::Base.configurations['test'] = {'adapter' => 'nulldb'}
|
263
|
+
|
230
264
|
describe NullDB::RSpec::NullifiedDatabase do
|
265
|
+
describe 'have_executed rspec matcher' do
|
266
|
+
before(:all) do
|
267
|
+
ActiveRecord::Schema.define do
|
268
|
+
create_table(:employees)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
include NullDB::RSpec::NullifiedDatabase
|
273
|
+
|
274
|
+
before { NullDB.checkpoint }
|
275
|
+
|
276
|
+
it 'passes if an execution was made' do
|
277
|
+
Kernel.stub(:load)
|
278
|
+
Employee.create
|
279
|
+
Employee.connection.should have_executed(:insert)
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'fails if an execution was not made' do
|
283
|
+
rspec_root = defined?(RSpec) ? RSpec : Spec
|
284
|
+
|
285
|
+
lambda { Employee.connection.should have_executed(:insert) }.
|
286
|
+
should raise_error(rspec_root::Expectations::ExpectationNotMetError)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
231
290
|
describe '.globally_nullify_database' do
|
232
291
|
it 'nullifies the database' do
|
233
292
|
NullDB::RSpec::NullifiedDatabase.should respond_to(:nullify_database)
|
metadata
CHANGED
@@ -1,119 +1,100 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-nulldb-adapter
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
- 1
|
10
|
-
version: 0.2.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.2
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Avdi Grimm
|
14
9
|
- Myron Marston
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
dependencies:
|
22
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2011-09-12 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
23
16
|
name: activerecord
|
24
|
-
|
25
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
26
18
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
hash: 15
|
31
|
-
segments:
|
32
|
-
- 2
|
33
|
-
- 0
|
34
|
-
- 0
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
35
22
|
version: 2.0.0
|
36
|
-
- - <
|
37
|
-
- !ruby/object:Gem::Version
|
38
|
-
hash: 5
|
39
|
-
segments:
|
40
|
-
- 3
|
41
|
-
- 1
|
42
|
-
version: "3.1"
|
43
23
|
type: :runtime
|
44
|
-
version_requirements: *id001
|
45
|
-
- !ruby/object:Gem::Dependency
|
46
|
-
name: rspec
|
47
24
|
prerelease: false
|
48
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
26
|
none: false
|
50
|
-
requirements:
|
51
|
-
- -
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 2.0.0
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: rspec
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
58
38
|
version: 1.2.9
|
59
39
|
type: :development
|
60
|
-
|
61
|
-
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.2.9
|
47
|
+
description: A database backend that translates database interactions into no-ops.
|
48
|
+
Using NullDB enables you to test your model business logic - including after_save
|
49
|
+
hooks - without ever touching a real database.
|
62
50
|
email: myron.marston@gmail.com
|
63
51
|
executables: []
|
64
|
-
|
65
52
|
extensions: []
|
66
|
-
|
67
|
-
extra_rdoc_files:
|
53
|
+
extra_rdoc_files:
|
68
54
|
- LICENSE
|
69
55
|
- README.rdoc
|
70
|
-
files:
|
56
|
+
files:
|
71
57
|
- .gitignore
|
58
|
+
- Gemfile
|
59
|
+
- Gemfile.lock
|
72
60
|
- LICENSE
|
73
61
|
- README.rdoc
|
74
62
|
- Rakefile
|
75
63
|
- VERSION
|
76
64
|
- activerecord-nulldb-adapter.gemspec
|
77
|
-
-
|
65
|
+
- lib/nulldb.rb
|
66
|
+
- lib/activerecord-nulldb-adapter.rb
|
78
67
|
- lib/active_record/connection_adapters/nulldb_adapter.rb
|
79
68
|
- lib/nulldb/arel_compiler.rb
|
80
69
|
- lib/nulldb_rspec.rb
|
81
70
|
- lib/tasks/database.rake
|
82
71
|
- spec/nulldb_spec.rb
|
83
72
|
- spec/spec.opts
|
84
|
-
has_rdoc: true
|
85
73
|
homepage: http://github.com/nulldb/nulldb
|
86
74
|
licenses: []
|
87
|
-
|
88
75
|
post_install_message:
|
89
|
-
rdoc_options:
|
76
|
+
rdoc_options:
|
90
77
|
- --charset=UTF-8
|
91
|
-
require_paths:
|
78
|
+
require_paths:
|
92
79
|
- lib
|
93
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
81
|
none: false
|
95
|
-
requirements:
|
96
|
-
- -
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
|
99
|
-
|
100
|
-
- 0
|
101
|
-
version: "0"
|
102
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
87
|
none: false
|
104
|
-
requirements:
|
105
|
-
- -
|
106
|
-
- !ruby/object:Gem::Version
|
107
|
-
|
108
|
-
segments:
|
109
|
-
- 0
|
110
|
-
version: "0"
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
111
92
|
requirements: []
|
112
|
-
|
113
93
|
rubyforge_project: nulldb
|
114
|
-
rubygems_version: 1.
|
94
|
+
rubygems_version: 1.8.24
|
115
95
|
signing_key:
|
116
96
|
specification_version: 3
|
117
97
|
summary: The Null Object pattern as applied to ActiveRecord database adapters
|
118
|
-
test_files:
|
98
|
+
test_files:
|
119
99
|
- spec/nulldb_spec.rb
|
100
|
+
has_rdoc:
|
data/ginger_scenarios.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'ginger'
|
2
|
-
|
3
|
-
def create_scenario(version)
|
4
|
-
scenario = Ginger::Scenario.new("Rails #{version}")
|
5
|
-
scenario[/^active_?record$/] = version
|
6
|
-
scenario[/^active_?support$/] = version
|
7
|
-
scenario
|
8
|
-
end
|
9
|
-
|
10
|
-
Ginger.configure do |config|
|
11
|
-
config.aliases["active_record"] = "activerecord"
|
12
|
-
config.aliases["active_support"] = "activesupport"
|
13
|
-
|
14
|
-
versions = []
|
15
|
-
|
16
|
-
# Rails 3 only works on Ruby 1.8.7 and 1.9.2
|
17
|
-
versions << '3.0.0' if %w[1.8.7 1.9.2].include?(RUBY_VERSION)
|
18
|
-
versions += %w( 2.3.8 2.3.5 2.3.4 2.3.3 2.3.2 )
|
19
|
-
versions += %w(
|
20
|
-
2.2.3 2.2.2
|
21
|
-
2.1.2 2.1.1 2.1.0
|
22
|
-
2.0.5 2.0.4 2.0.2 2.0.1 2.0.0
|
23
|
-
) if RUBY_VERSION =~ /^1\.8/
|
24
|
-
versions.each do |version|
|
25
|
-
config.scenarios << create_scenario(version)
|
26
|
-
end
|
27
|
-
end
|