activerecord-nulldb-adapter 0.2.1 → 0.2.2
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/.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
|