activerecord-nulldb-adapter 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +18 -5
- data/Appraisals +5 -1
- data/CHANGES.md +13 -0
- data/Gemfile +0 -1
- data/README.md +157 -0
- data/Rakefile +2 -2
- data/activerecord-nulldb-adapter.gemspec +2 -2
- data/gemfiles/activerecord_7.0.gemfile +17 -0
- data/gemfiles/activerecord_master.gemfile +1 -1
- data/lib/active_record/connection_adapters/nulldb_adapter/core.rb +28 -4
- data/lib/active_record/connection_adapters/nulldb_adapter/table_definition.rb +4 -0
- data/lib/nulldb/version.rb +1 -1
- data/spec/nulldb_spec.rb +15 -0
- metadata +8 -7
- data/README.rdoc +0 -154
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0da8a5f679279b76c36a80995783db057cf0bbc680d4006209619d068c55fbf3
|
4
|
+
data.tar.gz: eb7c91fe3bd86f1d8787cd2dc394aeecc1b8c0950e7133fb4a21f74f6e596a8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87e4cb3496818735480c034bb2444bec7cdd60eb6032332d78875d3f1cd8bb769f256d70d8a80b254cc11d9c91564b76f32fe8f863d65dba5d13427a4d6f74d1
|
7
|
+
data.tar.gz: ae332ef581de6f46f46940d2f4c6a0011606abbe2432e258a88b7ab9b5c0be50af03a9b140b630c4e79228c3ed65d4569ae50f9e828ad37d3b64dc031de9bcbf
|
data/.github/workflows/ruby.yml
CHANGED
@@ -10,18 +10,31 @@ jobs:
|
|
10
10
|
activerecord_5.2,
|
11
11
|
activerecord_6.0,
|
12
12
|
activerecord_6.1,
|
13
|
+
activerecord_7.0,
|
13
14
|
activerecord_master,
|
14
15
|
]
|
15
|
-
ruby: ["2.5", "2.6", "2.7", "3.0", "jruby-9.
|
16
|
+
ruby: ["2.5", "2.6", "2.7", "3.0", "jruby-9.3.1.0"]
|
16
17
|
exclude:
|
17
18
|
- ruby: "3.0"
|
18
19
|
gemfile: activerecord_5.2
|
19
20
|
|
20
|
-
- ruby: "
|
21
|
-
gemfile:
|
21
|
+
- ruby: "2.5"
|
22
|
+
gemfile: "activerecord_master"
|
22
23
|
|
23
|
-
- ruby: "
|
24
|
-
gemfile: activerecord_master
|
24
|
+
- ruby: "2.6"
|
25
|
+
gemfile: "activerecord_master"
|
26
|
+
|
27
|
+
- ruby: "2.5"
|
28
|
+
gemfile: "activerecord_7.0"
|
29
|
+
|
30
|
+
- ruby: "2.6"
|
31
|
+
gemfile: "activerecord_7.0"
|
32
|
+
|
33
|
+
- ruby: "jruby-9.3.1.0"
|
34
|
+
gemfile: "activerecord_7.0"
|
35
|
+
|
36
|
+
- ruby: "jruby-9.3.1.0"
|
37
|
+
gemfile: "activerecord_master"
|
25
38
|
|
26
39
|
runs-on: ubuntu-latest
|
27
40
|
env:
|
data/Appraisals
CHANGED
@@ -6,6 +6,10 @@ appraise "activerecord-6.0" do
|
|
6
6
|
gem "activerecord", "~> 6.0.0"
|
7
7
|
end
|
8
8
|
|
9
|
+
appraise "activerecord-7.0" do
|
10
|
+
gem "activerecord", "~> 7.0.0"
|
11
|
+
end
|
12
|
+
|
9
13
|
appraise "activerecord-master" do
|
10
|
-
gem "activerecord", github: 'rails/rails'
|
14
|
+
gem "activerecord", github: 'rails/rails', branch: :main
|
11
15
|
end
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
Unreleased
|
2
2
|
----------
|
3
3
|
|
4
|
+
0.9.0 (2023-03-10)
|
5
|
+
-----------
|
6
|
+
|
7
|
+
- Add support to BigSerial #119
|
8
|
+
- Add support to hstore #118
|
9
|
+
- Support Postgres type modifiers #117
|
10
|
+
|
11
|
+
|
12
|
+
0.8.0 (2022-10-28)
|
13
|
+
-----------
|
14
|
+
|
15
|
+
- Add support for Rails 7. #111 #112
|
16
|
+
|
4
17
|
0.7.0 (2021-01-18)
|
5
18
|
-----------
|
6
19
|
|
data/Gemfile
CHANGED
data/README.md
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
[<img src="https://badge.fury.io/rb/activerecord-nulldb-adapter.png" alt="Gem
|
2
|
+
Version" />](http://badge.fury.io/rb/activerecord-nulldb-adapter) [<img
|
3
|
+
src="https://codeclimate.com/github/nulldb/nulldb.png"
|
4
|
+
/>](https://codeclimate.com/github/nulldb/nulldb) [<img
|
5
|
+
src="https://github.com/nulldb/nulldb/workflows/build/badge.svg?branch=master"
|
6
|
+
alt="Build Status" />](https://github.com/nulldb/nulldb/actions)
|
7
|
+
|
8
|
+
# The NullDB Connection Adapter Plugin
|
9
|
+
|
10
|
+
## What
|
11
|
+
|
12
|
+
NullDB is the Null Object pattern as applied to ActiveRecord database
|
13
|
+
adapters. It is a database backend that translates database interactions into
|
14
|
+
no-ops. Using NullDB enables you to test your model business logic -
|
15
|
+
including `after_save` hooks - without ever touching a real database.
|
16
|
+
|
17
|
+
## Compatibility
|
18
|
+
|
19
|
+
### Ruby
|
20
|
+
Currently supported Ruby versions: MRI 2.5.x, 2.6.x, 2.7.x, 3.X.
|
21
|
+
|
22
|
+
Experimental support provided for: JRuby
|
23
|
+
|
24
|
+
### ActiveRecord
|
25
|
+
Any version of ActiveRecord >= 5.2
|
26
|
+
|
27
|
+
It is tested against AR 5.2, 6.0, 6.1 and master branch.
|
28
|
+
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
gem install activerecord-nulldb-adapter
|
32
|
+
|
33
|
+
## How
|
34
|
+
|
35
|
+
Once installed, NullDB can be used much like any other ActiveRecord database
|
36
|
+
adapter:
|
37
|
+
|
38
|
+
ActiveRecord::Base.establish_connection :adapter => :nulldb
|
39
|
+
|
40
|
+
NullDB needs to know where you keep your schema file in order to reflect table
|
41
|
+
metadata. By default it looks in RAILS_ROOT/db/schema.rb. You can override
|
42
|
+
that by setting the `schema` option:
|
43
|
+
|
44
|
+
ActiveRecord::Base.establish_connection :adapter => :nulldb,
|
45
|
+
:schema => 'foo/myschema.rb'
|
46
|
+
|
47
|
+
NullDB comes with RSpec integration. To replace the database with NullDB in
|
48
|
+
all of your specs, put the following in your spec/rails_helper:
|
49
|
+
|
50
|
+
require 'nulldb_rspec'
|
51
|
+
include NullDB::RSpec::NullifiedDatabase
|
52
|
+
|
53
|
+
after you load your rails environment
|
54
|
+
|
55
|
+
require File.expand_path('../config/environment', __dir__)
|
56
|
+
|
57
|
+
otherwise you will encounter issues such as
|
58
|
+
([bug)](https://github.com/nulldb/nulldb/pull/90#issuecomment-496690958).
|
59
|
+
|
60
|
+
Or if you just want to use NullDB in a specific spec context, you can include
|
61
|
+
the same module inside a context:
|
62
|
+
|
63
|
+
require 'nulldb_rspec'
|
64
|
+
|
65
|
+
describe Employee, "with access to the database" do
|
66
|
+
fixtures :employees
|
67
|
+
# ...
|
68
|
+
end
|
69
|
+
|
70
|
+
describe Employee, "with NullDB" do
|
71
|
+
include NullDB::RSpec::NullifiedDatabase
|
72
|
+
# ...
|
73
|
+
end
|
74
|
+
|
75
|
+
If you want to have NullDB enabled by default but disabled for particular
|
76
|
+
contexts then (see this
|
77
|
+
[post)](https://web.archive.org/web/20120419204019/http://andywaite.com/2011/5
|
78
|
+
/18/rspec-disable-nulldb)
|
79
|
+
|
80
|
+
NullDB::Rspec provides some custom matcher support for verifying expectations
|
81
|
+
about interactions with the database:
|
82
|
+
|
83
|
+
describe Employee do
|
84
|
+
include NullDB::RSpec::NullifiedDatabase
|
85
|
+
|
86
|
+
it "should cause an insert statement to be executed" do
|
87
|
+
Employee.create!
|
88
|
+
Employee.connection.should have_executed(:insert)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
UnitRecord-style verification that no database calls have been made at all can
|
93
|
+
be achieved by using the special `:anything` symbol:
|
94
|
+
|
95
|
+
describe "stuff that shouldn't touch the database" do
|
96
|
+
after :each do
|
97
|
+
Employee.connection.should_not have_executed(:anything)
|
98
|
+
end
|
99
|
+
# ...
|
100
|
+
end
|
101
|
+
|
102
|
+
You can also experiment with putting NullDB in your database.yml:
|
103
|
+
|
104
|
+
unit_test:
|
105
|
+
adapter: nulldb
|
106
|
+
|
107
|
+
However, due to the way Rails hard-codes specific database adapters into its
|
108
|
+
standard Rake tasks, you may find that this generates unexpected and
|
109
|
+
difficult-to-debug behavior. Workarounds for this are under development.
|
110
|
+
|
111
|
+
## Why
|
112
|
+
|
113
|
+
There are a number of advantages to writing unit tests that never touch the
|
114
|
+
database. The biggest is probably speed of execution - unit tests must be
|
115
|
+
fast for test-driven development to be practical. Another is separation of
|
116
|
+
concerns: unit tests should be exercising only the business logic contained in
|
117
|
+
your models, not ActiveRecord. For more on why testing-sans-database is a good
|
118
|
+
idea, see:
|
119
|
+
http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database.
|
120
|
+
|
121
|
+
NullDB is one way to separate your unit tests from the database. It was
|
122
|
+
inspired by the [ARBS](http://arbs.rubyforge.org/) and
|
123
|
+
[UnitRecord](http://unit-test-ar.rubyforge.org/) libraries. It differs from
|
124
|
+
them in that rather than modifying parts of ActiveRecord, it implements the
|
125
|
+
same [semi-]well-documented public interface that the other standard database
|
126
|
+
adapters, like MySQL and SQLServer, implement. This has enabled it to evolve
|
127
|
+
to support new ActiveRecord versions relatively easily.
|
128
|
+
|
129
|
+
One concrete advantage of this null-object pattern design is that it is
|
130
|
+
possible with NullDB to test `after_save` hooks. With NullDB, you can call
|
131
|
+
`#save` and all of the usual callbacks will be called - but nothing will be
|
132
|
+
saved.
|
133
|
+
|
134
|
+
## Limitations
|
135
|
+
|
136
|
+
* It is **not** an in-memory database. Finds will not work. Neither will
|
137
|
+
`reload`, currently. Test fixtures won't work either, for obvious
|
138
|
+
reasons.
|
139
|
+
* It has only the most rudimentery schema/migration support. Complex
|
140
|
+
migrations will probably break it.
|
141
|
+
* Lots of other things probably don't work. Patches welcome!
|
142
|
+
|
143
|
+
|
144
|
+
## Who
|
145
|
+
|
146
|
+
NullDB was originally written by Avdi Grimm <mailto:avdi@avdi.org>. It is
|
147
|
+
currently maintained by [Danilo Cabello](https://github.com/cabello).
|
148
|
+
Previously maintained by: [Bram de Vries](https://github.com/blaet).
|
149
|
+
|
150
|
+
## Where
|
151
|
+
|
152
|
+
* Homepage: https://github.com/nulldb/nulldb
|
153
|
+
|
154
|
+
|
155
|
+
## License
|
156
|
+
|
157
|
+
See the LICENSE file for licensing information.
|
data/Rakefile
CHANGED
@@ -9,6 +9,6 @@ task :default => :spec
|
|
9
9
|
|
10
10
|
require 'rdoc/task'
|
11
11
|
Rake::RDocTask.new do |rd|
|
12
|
-
rd.main = "README.
|
13
|
-
rd.rdoc_files.include("README.
|
12
|
+
rd.main = "README.md"
|
13
|
+
rd.rdoc_files.include("README.md", "LICENSE", "lib/**/*.rb")
|
14
14
|
end
|
@@ -14,13 +14,13 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.email = "cabello@users.noreply.github.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.md"
|
18
18
|
]
|
19
19
|
s.files = `git ls-files`.split($/)
|
20
20
|
s.homepage = "https://github.com/nulldb/nulldb"
|
21
21
|
s.licenses = ["MIT"]
|
22
22
|
|
23
|
-
s.add_runtime_dependency 'activerecord', '>= 5.2.0', '<
|
23
|
+
s.add_runtime_dependency 'activerecord', '>= 5.2.0', '< 7.1'
|
24
24
|
s.add_development_dependency 'spec'
|
25
25
|
s.add_development_dependency 'rdoc'
|
26
26
|
s.add_development_dependency 'rspec'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "activerecord", "~> 7.0.0"
|
6
|
+
|
7
|
+
group :development, :test do
|
8
|
+
gem "spec"
|
9
|
+
gem "rspec", ">= 1.2.9"
|
10
|
+
gem "rake"
|
11
|
+
gem "rdoc"
|
12
|
+
end
|
13
|
+
|
14
|
+
group :development do
|
15
|
+
gem "appraisal"
|
16
|
+
gem "simplecov", require: false
|
17
|
+
end
|
@@ -98,7 +98,7 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter < ActiveRecord::Connection
|
|
98
98
|
end
|
99
99
|
|
100
100
|
# Rails 6.1+
|
101
|
-
if ActiveRecord::VERSION::MAJOR >= 6 and ActiveRecord::VERSION::MINOR > 0
|
101
|
+
if ActiveRecord::VERSION::MAJOR >= 7 || (ActiveRecord::VERSION::MAJOR >= 6 and ActiveRecord::VERSION::MINOR > 0)
|
102
102
|
def remove_index(table_name, column_name = nil, **options )
|
103
103
|
index_name = index_name_for_remove(table_name, column_name, options)
|
104
104
|
index = @indexes[table_name].reject! { |index| index.name == index_name }
|
@@ -264,7 +264,7 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter < ActiveRecord::Connection
|
|
264
264
|
|
265
265
|
protected
|
266
266
|
|
267
|
-
def select(statement, name = nil, binds = [])
|
267
|
+
def select(statement, name = nil, binds = [], prepare: nil, async: nil)
|
268
268
|
EmptyResult.new.tap do |r|
|
269
269
|
r.bind_column_meta(columns_for(name))
|
270
270
|
self.execution_log << Statement.new(entry_point, statement)
|
@@ -313,7 +313,7 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter < ActiveRecord::Connection
|
|
313
313
|
|
314
314
|
def new_table_definition(adapter = nil, table_name = nil, is_temporary = nil, options = {})
|
315
315
|
case ::ActiveRecord::VERSION::MAJOR
|
316
|
-
when 6
|
316
|
+
when 6, 7
|
317
317
|
TableDefinition.new(self, table_name, temporary: is_temporary, options: options.except(:id))
|
318
318
|
when 5
|
319
319
|
TableDefinition.new(table_name, is_temporary, options.except(:id), nil)
|
@@ -343,13 +343,37 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter < ActiveRecord::Connection
|
|
343
343
|
[nil, @logger, @config]
|
344
344
|
end
|
345
345
|
|
346
|
+
# Register types only once to avoid ActiveRecord::TypeConflictError
|
347
|
+
# in ActiveRecord::Type::Registration#<=>
|
348
|
+
REGISTRATION_MUTEX = Mutex.new
|
349
|
+
|
346
350
|
def register_types
|
347
|
-
|
351
|
+
REGISTRATION_MUTEX.synchronize do
|
352
|
+
return if self.class.types_registered
|
353
|
+
|
354
|
+
self.class.types_registered = true
|
355
|
+
end
|
356
|
+
|
348
357
|
ActiveRecord::Type.register(
|
349
358
|
:primary_key,
|
350
359
|
ActiveModel::Type::Integer,
|
351
360
|
adapter: adapter_name,
|
352
361
|
override: true
|
353
362
|
)
|
363
|
+
|
364
|
+
ActiveRecord::Type.add_modifier({ array: true }, DummyOID, adapter: :nulldb)
|
365
|
+
ActiveRecord::Type.add_modifier({ range: true }, DummyOID, adapter: :nulldb)
|
366
|
+
end
|
367
|
+
|
368
|
+
class << self
|
369
|
+
attr_accessor :types_registered
|
370
|
+
end
|
371
|
+
|
372
|
+
class DummyOID < ActiveModel::Type::Value
|
373
|
+
attr_reader :subtype
|
374
|
+
|
375
|
+
def initialize(*args)
|
376
|
+
@subtype = args.first
|
377
|
+
end
|
354
378
|
end
|
355
379
|
end
|
@@ -6,6 +6,10 @@ class ActiveRecord::ConnectionAdapters::NullDBAdapter
|
|
6
6
|
alias_method :citext, :text
|
7
7
|
alias_method :interval, :text
|
8
8
|
alias_method :geometry, :text
|
9
|
+
alias_method :serial, :integer
|
10
|
+
alias_method :bigserial, :integer
|
11
|
+
alias_method :inet, :string
|
9
12
|
alias_method :jsonb, :json if method_defined? :json
|
13
|
+
alias_method :hstore, :json
|
10
14
|
end
|
11
15
|
end
|
data/lib/nulldb/version.rb
CHANGED
data/spec/nulldb_spec.rb
CHANGED
@@ -490,6 +490,7 @@ describe 'adapter-specific extensions' do
|
|
490
490
|
t.interval :time_interval
|
491
491
|
t.geometry :feature_geometry, srid: 4326, type: "multi_polygon"
|
492
492
|
t.jsonb :jsonb_column
|
493
|
+
t.hstore :hstore_column
|
493
494
|
end
|
494
495
|
end
|
495
496
|
}.to_not raise_error
|
@@ -503,6 +504,20 @@ describe 'adapter-specific extensions' do
|
|
503
504
|
should_have_column(ExtendedModel, :jsonb_column, :json)
|
504
505
|
end
|
505
506
|
|
507
|
+
it 'supports ActiveModel attributes with postgres modifiers' do
|
508
|
+
class ExtendedModel < ActiveRecord::Base
|
509
|
+
attribute :strings, :string, array: true
|
510
|
+
attribute :size, :integer, range: true
|
511
|
+
end
|
512
|
+
|
513
|
+
expect(ExtendedModel.type_for_attribute(:strings))
|
514
|
+
.to be_a ActiveRecord::ConnectionAdapters::NullDBAdapter::DummyOID
|
515
|
+
expect(ExtendedModel.new(strings: %w[a b]).strings).to eq %w[a b]
|
516
|
+
expect(ExtendedModel.type_for_attribute(:size))
|
517
|
+
.to be_a ActiveRecord::ConnectionAdapters::NullDBAdapter::DummyOID
|
518
|
+
expect(ExtendedModel.new(size: 1..5).size).to eq 1..5
|
519
|
+
end
|
520
|
+
|
506
521
|
it 'registers a primary_key type' do
|
507
522
|
expect(ActiveRecord::Type.lookup(:primary_key, adapter: 'NullDB'))
|
508
523
|
.to be_a(ActiveModel::Type::Integer)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-nulldb-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Avdi Grimm
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-03-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 5.2.0
|
22
22
|
- - "<"
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: '
|
24
|
+
version: '7.1'
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -31,7 +31,7 @@ dependencies:
|
|
31
31
|
version: 5.2.0
|
32
32
|
- - "<"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '7.1'
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: spec
|
37
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -138,7 +138,7 @@ executables: []
|
|
138
138
|
extensions: []
|
139
139
|
extra_rdoc_files:
|
140
140
|
- LICENSE
|
141
|
-
- README.
|
141
|
+
- README.md
|
142
142
|
files:
|
143
143
|
- ".github/workflows/ruby.yml"
|
144
144
|
- ".gitignore"
|
@@ -146,12 +146,13 @@ files:
|
|
146
146
|
- CHANGES.md
|
147
147
|
- Gemfile
|
148
148
|
- LICENSE
|
149
|
-
- README.
|
149
|
+
- README.md
|
150
150
|
- Rakefile
|
151
151
|
- activerecord-nulldb-adapter.gemspec
|
152
152
|
- gemfiles/activerecord_5.2.gemfile
|
153
153
|
- gemfiles/activerecord_6.0.gemfile
|
154
154
|
- gemfiles/activerecord_6.1.gemfile
|
155
|
+
- gemfiles/activerecord_7.0.gemfile
|
155
156
|
- gemfiles/activerecord_master.gemfile
|
156
157
|
- lib/active_record/connection_adapters/nulldb_adapter.rb
|
157
158
|
- lib/active_record/connection_adapters/nulldb_adapter/checkpoint.rb
|
@@ -194,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
195
|
- !ruby/object:Gem::Version
|
195
196
|
version: '0'
|
196
197
|
requirements: []
|
197
|
-
rubygems_version: 3.
|
198
|
+
rubygems_version: 3.3.26
|
198
199
|
signing_key:
|
199
200
|
specification_version: 4
|
200
201
|
summary: The Null Object pattern as applied to ActiveRecord database adapters
|
data/README.rdoc
DELETED
@@ -1,154 +0,0 @@
|
|
1
|
-
{<img src="https://badge.fury.io/rb/activerecord-nulldb-adapter.png" alt="Gem Version" />}[http://badge.fury.io/rb/activerecord-nulldb-adapter]
|
2
|
-
{<img src="https://codeclimate.com/github/nulldb/nulldb.png" />}[https://codeclimate.com/github/nulldb/nulldb]
|
3
|
-
{<img src="https://github.com/nulldb/nulldb/workflows/build/badge.svg?branch=master" alt="Build Status" />}[https://github.com/nulldb/nulldb/actions]
|
4
|
-
|
5
|
-
|
6
|
-
= The NullDB Connection Adapter Plugin
|
7
|
-
|
8
|
-
== What
|
9
|
-
|
10
|
-
NullDB is the Null Object pattern as applied to ActiveRecord database
|
11
|
-
adapters. It is a database backend that translates database
|
12
|
-
interactions into no-ops. Using NullDB enables you to test your model
|
13
|
-
business logic - including +after_save+ hooks - without ever touching
|
14
|
-
a real database.
|
15
|
-
|
16
|
-
== Compatibility
|
17
|
-
|
18
|
-
=== Ruby
|
19
|
-
Currently supported Ruby versions: MRI 2.5.x, 2.6.x, 2.7.x, 3.X.
|
20
|
-
|
21
|
-
Experimental support provided for: JRuby
|
22
|
-
|
23
|
-
=== ActiveRecord
|
24
|
-
Any version of ActiveRecord >= 5.2
|
25
|
-
|
26
|
-
It is tested against AR 5.2, 6.0, 6.1 and master branch.
|
27
|
-
|
28
|
-
== Installation
|
29
|
-
|
30
|
-
gem install activerecord-nulldb-adapter
|
31
|
-
|
32
|
-
== How
|
33
|
-
|
34
|
-
Once installed, NullDB can be used much like any other ActiveRecord
|
35
|
-
database adapter:
|
36
|
-
|
37
|
-
ActiveRecord::Base.establish_connection :adapter => :nulldb
|
38
|
-
|
39
|
-
NullDB needs to know where you keep your schema file in order to
|
40
|
-
reflect table metadata. By default it looks in
|
41
|
-
RAILS_ROOT/db/schema.rb. You can override that by setting the
|
42
|
-
+schema+ option:
|
43
|
-
|
44
|
-
ActiveRecord::Base.establish_connection :adapter => :nulldb,
|
45
|
-
:schema => 'foo/myschema.rb'
|
46
|
-
|
47
|
-
NullDB comes with RSpec integration. To replace the database with
|
48
|
-
NullDB in all of your specs, put the following in your
|
49
|
-
spec/rails_helper:
|
50
|
-
|
51
|
-
require 'nulldb_rspec'
|
52
|
-
include NullDB::RSpec::NullifiedDatabase
|
53
|
-
|
54
|
-
after you load your rails environment
|
55
|
-
|
56
|
-
require File.expand_path('../config/environment', __dir__)
|
57
|
-
|
58
|
-
otherwise you will encounter issues such as (bug)[https://github.com/nulldb/nulldb/pull/90#issuecomment-496690958].
|
59
|
-
|
60
|
-
Or if you just want to use NullDB in a specific spec context, you can
|
61
|
-
include the same module inside a context:
|
62
|
-
|
63
|
-
require 'nulldb_rspec'
|
64
|
-
|
65
|
-
describe Employee, "with access to the database" do
|
66
|
-
fixtures :employees
|
67
|
-
# ...
|
68
|
-
end
|
69
|
-
|
70
|
-
describe Employee, "with NullDB" do
|
71
|
-
include NullDB::RSpec::NullifiedDatabase
|
72
|
-
# ...
|
73
|
-
end
|
74
|
-
|
75
|
-
If you want to have NullDB enabled by default but disabled for particular contexts then (see this post)[https://web.archive.org/web/20120419204019/http://andywaite.com/2011/5/18/rspec-disable-nulldb]
|
76
|
-
|
77
|
-
NullDB::Rspec provides some custom matcher support for verifying
|
78
|
-
expectations about interactions with the database:
|
79
|
-
|
80
|
-
describe Employee do
|
81
|
-
include NullDB::RSpec::NullifiedDatabase
|
82
|
-
|
83
|
-
it "should cause an insert statement to be executed" do
|
84
|
-
Employee.create!
|
85
|
-
Employee.connection.should have_executed(:insert)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
UnitRecord-style verification that no database calls have been made at
|
90
|
-
all can be achieved by using the special +:anything+ symbol:
|
91
|
-
|
92
|
-
describe "stuff that shouldn't touch the database" do
|
93
|
-
after :each do
|
94
|
-
Employee.connection.should_not have_executed(:anything)
|
95
|
-
end
|
96
|
-
# ...
|
97
|
-
end
|
98
|
-
|
99
|
-
You can also experiment with putting NullDB in your database.yml:
|
100
|
-
|
101
|
-
unit_test:
|
102
|
-
adapter: nulldb
|
103
|
-
|
104
|
-
However, due to the way Rails hard-codes specific database adapters
|
105
|
-
into its standard Rake tasks, you may find that this generates
|
106
|
-
unexpected and difficult-to-debug behavior. Workarounds for this are
|
107
|
-
under development.
|
108
|
-
|
109
|
-
== Why
|
110
|
-
|
111
|
-
There are a number of advantages to writing unit tests that never
|
112
|
-
touch the database. The biggest is probably speed of execution - unit
|
113
|
-
tests must be fast for test-driven development to be practical.
|
114
|
-
Another is separation of concerns: unit tests should be exercising
|
115
|
-
only the business logic contained in your models, not ActiveRecord.
|
116
|
-
For more on why testing-sans-database is a good idea, see:
|
117
|
-
http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database.
|
118
|
-
|
119
|
-
NullDB is one way to separate your unit tests from the database. It
|
120
|
-
was inspired by the ARBS[http://arbs.rubyforge.org/] and
|
121
|
-
UnitRecord[http://unit-test-ar.rubyforge.org/] libraries. It differs
|
122
|
-
from them in that rather than modifying parts of ActiveRecord, it
|
123
|
-
implements the same [semi-]well-documented public interface that the
|
124
|
-
other standard database adapters, like MySQL and SQLServer,
|
125
|
-
implement. This has enabled it to evolve to support new ActiveRecord
|
126
|
-
versions relatively easily.
|
127
|
-
|
128
|
-
One concrete advantage of this null-object pattern design is that it
|
129
|
-
is possible with NullDB to test +after_save+ hooks. With NullDB, you
|
130
|
-
can call +#save+ and all of the usual callbacks will be called - but
|
131
|
-
nothing will be saved.
|
132
|
-
|
133
|
-
== Limitations
|
134
|
-
|
135
|
-
* It is *not* an in-memory database. Finds will not work. Neither
|
136
|
-
will +reload+, currently. Test fixtures won't work either, for
|
137
|
-
obvious reasons.
|
138
|
-
* It has only the most rudimentery schema/migration support. Complex
|
139
|
-
migrations will probably break it.
|
140
|
-
* Lots of other things probably don't work. Patches welcome!
|
141
|
-
|
142
|
-
== Who
|
143
|
-
|
144
|
-
NullDB was originally written by Avdi Grimm <mailto:avdi@avdi.org>.
|
145
|
-
It is currently maintained by {Danilo Cabello}[https://github.com/cabello].
|
146
|
-
Previously maintained by: {Bram de Vries}[https://github.com/blaet].
|
147
|
-
|
148
|
-
== Where
|
149
|
-
|
150
|
-
* Homepage: https://github.com/nulldb/nulldb
|
151
|
-
|
152
|
-
== License
|
153
|
-
|
154
|
-
See the LICENSE file for licensing information.
|