with_model 2.1.7 → 2.2.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/ci.yml +20 -9
- data/.rspec +1 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +21 -23
- data/Rakefile +8 -17
- data/lib/with_model/constant_stubber.rb +1 -1
- data/lib/with_model/descendants_tracker.rb +87 -0
- data/lib/with_model/model.rb +12 -16
- data/lib/with_model/table.rb +6 -6
- data/lib/with_model/version.rb +1 -1
- data/lib/with_model.rb +6 -6
- data/spec/active_record_behaviors_spec.rb +27 -27
- data/spec/constant_stubber_spec.rb +5 -5
- data/spec/descendants_tracking_spec.rb +48 -0
- data/spec/readme_spec.rb +24 -24
- data/spec/spec_helper.rb +7 -19
- data/spec/with_model_spec.rb +109 -118
- data/test/test_helper.rb +7 -18
- data/test/with_model_test.rb +9 -9
- data/with_model.gemspec +15 -15
- metadata +8 -12
- data/.rubocop.yml +0 -33
- data/.rubocop_todo.yml +0 -78
- data/spec/.rubocop.yml +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 809e5984c60e2fa27b71d3d3ce7664feae0a3b2c7a59f345e2a94a819affb623
|
4
|
+
data.tar.gz: 5e8b519ef7d338aa754755efd065af68b718e6dc1f96fe27632266752e7b4990
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf09e4aabe724638f054a54199d62a61ae9efd0cca28485412f85fd082a99f104d4f538bd7041f1777c9380398e7d1497d5f01dcc07cb5fdacc116ad3e7dd69f
|
7
|
+
data.tar.gz: 6f795b756e9b33abd148d51010a0afb80e01660af35c76d1a98a634c6b2d31c38a616e94aeff99c6d8b19b019c69b994c9b5dc21e69439fbbcb004528dc3606b
|
data/.github/workflows/ci.yml
CHANGED
@@ -6,8 +6,6 @@ on:
|
|
6
6
|
- master
|
7
7
|
- github-actions
|
8
8
|
pull_request:
|
9
|
-
branches:
|
10
|
-
- master
|
11
9
|
|
12
10
|
jobs:
|
13
11
|
test:
|
@@ -17,18 +15,31 @@ jobs:
|
|
17
15
|
strategy:
|
18
16
|
fail-fast: false
|
19
17
|
matrix:
|
20
|
-
ruby-version: ['
|
18
|
+
ruby-version: ['3.1', '3.2', '3.3', '3.4']
|
21
19
|
active-record-version-env:
|
22
|
-
- ACTIVE_RECORD_VERSION="~> 6.0.0"
|
23
|
-
- ACTIVE_RECORD_VERSION="~> 6.1.0"
|
24
20
|
- ACTIVE_RECORD_VERSION="~> 7.0.0"
|
21
|
+
- ACTIVE_RECORD_VERSION="~> 7.1.0"
|
22
|
+
- ACTIVE_RECORD_VERSION="~> 7.2.0"
|
23
|
+
- ACTIVE_RECORD_VERSION="~> 8.0.0"
|
25
24
|
allow-failure: [false]
|
25
|
+
exclude:
|
26
|
+
- ruby-version: '3.1'
|
27
|
+
active-record-version-env: ACTIVE_RECORD_VERSION="~> 8.0.0"
|
26
28
|
include:
|
27
|
-
- ruby-version: '3.
|
28
|
-
active-record-version-env: ACTIVE_RECORD_BRANCH="
|
29
|
+
- ruby-version: '3.4'
|
30
|
+
active-record-version-env: ACTIVE_RECORD_BRANCH="main"
|
31
|
+
allow-failure: true
|
32
|
+
- ruby-version: '3.4'
|
33
|
+
active-record-version-env: ACTIVE_RECORD_BRANCH="8-0-stable"
|
29
34
|
allow-failure: true
|
30
|
-
- ruby-version: '3.
|
31
|
-
active-record-version-env: ACTIVE_RECORD_BRANCH="
|
35
|
+
- ruby-version: '3.4'
|
36
|
+
active-record-version-env: ACTIVE_RECORD_BRANCH="7-2-stable"
|
37
|
+
allow-failure: true
|
38
|
+
- ruby-version: '3.4'
|
39
|
+
active-record-version-env: ACTIVE_RECORD_BRANCH="7-1-stable"
|
40
|
+
allow-failure: true
|
41
|
+
- ruby-version: '3.4'
|
42
|
+
active-record-version-env: ACTIVE_RECORD_BRANCH="7-0-stable"
|
32
43
|
allow-failure: true
|
33
44
|
continue-on-error: ${{ matrix.allow-failure }}
|
34
45
|
steps:
|
data/.rspec
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
### 2.2.0
|
2
|
+
|
3
|
+
- Fix dependency tracking issue when `cache_classes: true` is set in Rails 7+.
|
4
|
+
- Create table in same database as `superclass` (Joe Lind)
|
5
|
+
- Switch to standard instead of rubocop for linting.
|
6
|
+
- Add support for Active Record 7 and 8.
|
7
|
+
- Require Active Record 7 or later.
|
8
|
+
- Add support for Ruby 3.3.
|
9
|
+
- Require Ruby 3.1 or later.
|
10
|
+
|
1
11
|
### 2.1.7
|
2
12
|
- Require Ruby 2.7 or later
|
3
13
|
- Add Ruby 3.2 support
|
data/Gemfile
CHANGED
@@ -1,33 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
source
|
3
|
+
source "https://rubygems.org"
|
4
4
|
|
5
5
|
gemspec
|
6
6
|
|
7
|
-
ar_branch = ENV.fetch(
|
8
|
-
ar_version = ENV.fetch(
|
9
|
-
is_jruby = RUBY_PLATFORM == 'java'
|
7
|
+
ar_branch = ENV.fetch("ACTIVE_RECORD_BRANCH", nil)
|
8
|
+
ar_version = ENV.fetch("ACTIVE_RECORD_VERSION", nil)
|
10
9
|
|
11
10
|
if ar_branch
|
12
|
-
gem
|
13
|
-
if ar_branch ==
|
14
|
-
gem 'arel', git: 'https://github.com/rails/arel.git'
|
15
|
-
gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter.git' if is_jruby
|
16
|
-
end
|
11
|
+
gem "activerecord", git: "https://github.com/rails/rails.git", branch: ar_branch
|
12
|
+
gem "arel", git: "https://github.com/rails/arel.git" if ar_branch == "master"
|
17
13
|
elsif ar_version
|
18
|
-
gem
|
19
|
-
if is_jruby && !Gem::Requirement.new(ar_version).satisfied_by?(Gem::Version.new('5.2.0'))
|
20
|
-
gem 'activerecord-jdbcsqlite3-adapter', git: 'https://github.com/jruby/activerecord-jdbc-adapter.git'
|
21
|
-
end
|
14
|
+
gem "activerecord", ar_version
|
22
15
|
end
|
23
16
|
|
24
|
-
gem
|
25
|
-
gem
|
26
|
-
gem
|
27
|
-
gem
|
28
|
-
gem
|
29
|
-
gem
|
30
|
-
gem
|
31
|
-
gem
|
32
|
-
gem
|
33
|
-
|
17
|
+
gem "bigdecimal"
|
18
|
+
gem "bundler"
|
19
|
+
gem "debug"
|
20
|
+
gem "logger"
|
21
|
+
gem "minitest"
|
22
|
+
gem "mutex_m"
|
23
|
+
gem "rake"
|
24
|
+
gem "rspec"
|
25
|
+
gem "standard"
|
26
|
+
|
27
|
+
if ar_branch == "7-0-stable" || ar_version == "~> 7.0.0"
|
28
|
+
gem "sqlite3", "< 2"
|
29
|
+
else
|
30
|
+
gem "sqlite3"
|
31
|
+
end
|
data/Rakefile
CHANGED
@@ -1,23 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
require 'rake/testtask'
|
6
|
-
require 'rubocop/rake_task'
|
3
|
+
require "bundler/gem_tasks"
|
7
4
|
|
8
|
-
|
9
|
-
RSpec::Core::RakeTask.new
|
10
|
-
t.pattern = Dir.glob('spec/**/*_spec.rb')
|
11
|
-
end
|
5
|
+
require "rspec/core/rake_task"
|
6
|
+
RSpec::Core::RakeTask.new
|
12
7
|
|
13
|
-
|
14
|
-
|
15
|
-
t.libs << 'test'
|
16
|
-
t.libs << 'lib'
|
17
|
-
t.pattern = 'test/**/*_test.rb'
|
18
|
-
end
|
8
|
+
require "minitest/test_task"
|
9
|
+
Minitest::TestTask.create
|
19
10
|
|
20
|
-
|
21
|
-
|
11
|
+
# standard rake task
|
12
|
+
require "standard/rake"
|
22
13
|
|
23
|
-
task default: %i[spec test
|
14
|
+
task default: %i[spec test standard]
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "active_support/descendants_tracker"
|
2
|
+
|
3
|
+
module WithModel
|
4
|
+
# Based on https://github.com/rails/rails/blob/491afff27e2dd3d5f301b478b9a43d3c31709af8/activesupport/lib/active_support/descendants_tracker.rb
|
5
|
+
module DescendantsTracker
|
6
|
+
if RUBY_ENGINE == "ruby"
|
7
|
+
# On MRI `ObjectSpace::WeakMap` keys are weak references.
|
8
|
+
# So we can simply use WeakMap as a `Set`.
|
9
|
+
class WeakSet < ObjectSpace::WeakMap # :nodoc:
|
10
|
+
alias_method :to_a, :keys
|
11
|
+
|
12
|
+
def <<(object)
|
13
|
+
self[object] = true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
else
|
17
|
+
# On TruffleRuby `ObjectSpace::WeakMap` keys are strong references.
|
18
|
+
# So we use `object_id` as a key and the actual object as a value.
|
19
|
+
#
|
20
|
+
# JRuby for now doesn't have Class#descendant, but when it will, it will likely
|
21
|
+
# have the same WeakMap semantic than Truffle so we future proof this as much as possible.
|
22
|
+
class WeakSet # :nodoc:
|
23
|
+
def initialize
|
24
|
+
@map = ObjectSpace::WeakMap.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](object)
|
28
|
+
@map.key?(object.object_id)
|
29
|
+
end
|
30
|
+
alias_method :include?, :[]
|
31
|
+
|
32
|
+
def []=(object, _present)
|
33
|
+
@map[object.object_id] = object
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_a
|
37
|
+
@map.values
|
38
|
+
end
|
39
|
+
|
40
|
+
def <<(object)
|
41
|
+
self[object] = true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
@excluded_descendants = WeakSet.new
|
46
|
+
|
47
|
+
class << self
|
48
|
+
def clear(classes) # :nodoc:
|
49
|
+
classes.each do |klass|
|
50
|
+
@excluded_descendants << klass
|
51
|
+
klass.descendants.each do |descendant|
|
52
|
+
@excluded_descendants << descendant
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def reject!(classes) # :nodoc:
|
58
|
+
if @excluded_descendants
|
59
|
+
classes.reject! { |d| @excluded_descendants.include?(d) }
|
60
|
+
end
|
61
|
+
classes
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
module DestroyedClassesFiltering
|
66
|
+
def subclasses
|
67
|
+
WithModel::DescendantsTracker.reject!(super)
|
68
|
+
end
|
69
|
+
|
70
|
+
def descendants
|
71
|
+
WithModel::DescendantsTracker.reject!(super)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class ActiveRecord::Base
|
78
|
+
extend WithModel::DescendantsTracker::DestroyedClassesFiltering
|
79
|
+
end
|
80
|
+
|
81
|
+
module ActiveSupport
|
82
|
+
module DescendantsTracker
|
83
|
+
class << self
|
84
|
+
attr_reader :clear_disabled
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/with_model/model.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
3
|
+
require "logger"
|
4
|
+
require "active_record"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
6
|
+
require "English"
|
7
|
+
require "with_model/constant_stubber"
|
8
|
+
require "with_model/descendants_tracker"
|
9
|
+
require "with_model/methods"
|
10
|
+
require "with_model/table"
|
9
11
|
|
10
12
|
module WithModel
|
11
13
|
# In general, direct use of this class should be avoided. Instead use
|
@@ -38,6 +40,7 @@ module WithModel
|
|
38
40
|
cleanup_descendants_tracking
|
39
41
|
reset_dependencies_cache
|
40
42
|
table.destroy
|
43
|
+
WithModel::DescendantsTracker.clear([@model])
|
41
44
|
@model = nil
|
42
45
|
end
|
43
46
|
|
@@ -54,15 +57,8 @@ module WithModel
|
|
54
57
|
end
|
55
58
|
|
56
59
|
def cleanup_descendants_tracking
|
57
|
-
|
58
|
-
|
59
|
-
ActiveSupport::DescendantsTracker.clear([@model])
|
60
|
-
else
|
61
|
-
ActiveSupport::DescendantsTracker.class_variable_get(:@@direct_descendants).delete(ActiveRecord::Base)
|
62
|
-
end
|
63
|
-
elsif @model.superclass.respond_to?(:direct_descendants)
|
64
|
-
@model.superclass.direct_descendants.delete(@model)
|
65
|
-
end
|
60
|
+
ActiveSupport::DescendantsTracker.clear([@model]) \
|
61
|
+
unless ActiveSupport::DescendantsTracker.clear_disabled
|
66
62
|
end
|
67
63
|
|
68
64
|
def reset_dependencies_cache
|
@@ -76,7 +72,7 @@ module WithModel
|
|
76
72
|
end
|
77
73
|
|
78
74
|
def table
|
79
|
-
@table ||= Table.new table_name, @table_options, &@table_block
|
75
|
+
@table ||= Table.new table_name, @table_options, connection: @superclass.connection, &@table_block
|
80
76
|
end
|
81
77
|
|
82
78
|
def table_name
|
data/lib/with_model/table.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "active_record"
|
4
4
|
|
5
5
|
module WithModel
|
6
6
|
# In general, direct use of this class should be avoided. Instead use
|
@@ -8,12 +8,14 @@ module WithModel
|
|
8
8
|
class Table
|
9
9
|
# @param [Symbol] name The name of the table to create.
|
10
10
|
# @param options Passed to ActiveRecord `create_table`.
|
11
|
+
# @param connection The connection to use for creating the table.
|
11
12
|
# @param block Passed to ActiveRecord `create_table`.
|
12
13
|
# @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-create_table
|
13
|
-
def initialize(name, options = {}, &block)
|
14
|
+
def initialize(name, options = {}, connection: ActiveRecord::Base.connection, &block)
|
14
15
|
@name = name.freeze
|
15
16
|
@options = options.freeze
|
16
17
|
@block = block
|
18
|
+
@connection = connection
|
17
19
|
end
|
18
20
|
|
19
21
|
# Creates the table with the initialized options. Drops the table if
|
@@ -29,6 +31,8 @@ module WithModel
|
|
29
31
|
|
30
32
|
private
|
31
33
|
|
34
|
+
attr_reader :connection
|
35
|
+
|
32
36
|
def exists?
|
33
37
|
if connection.respond_to?(:data_source_exists?)
|
34
38
|
connection.data_source_exists?(@name)
|
@@ -36,9 +40,5 @@ module WithModel
|
|
36
40
|
connection.table_exists?(@name)
|
37
41
|
end
|
38
42
|
end
|
39
|
-
|
40
|
-
def connection
|
41
|
-
ActiveRecord::Base.connection
|
42
|
-
end
|
43
43
|
end
|
44
44
|
end
|
data/lib/with_model/version.rb
CHANGED
data/lib/with_model.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
3
|
+
require "with_model/model"
|
4
|
+
require "with_model/model/dsl"
|
5
|
+
require "with_model/table"
|
6
|
+
require "with_model/version"
|
7
7
|
|
8
8
|
module WithModel
|
9
9
|
class MiniTestLifeCycle < Module
|
@@ -61,7 +61,7 @@ module WithModel
|
|
61
61
|
# @param [Object] object The new model object instance to create
|
62
62
|
# @param scope Passed to `before`/`after` in the test context. Rspec only.
|
63
63
|
# @param [Symbol] runner The test running, either :rspec or :minitest, defaults to :rspec
|
64
|
-
def setup_object(object, scope: nil, runner: nil)
|
64
|
+
def setup_object(object, scope: nil, runner: nil)
|
65
65
|
case runner || WithModel.runner
|
66
66
|
when :rspec
|
67
67
|
before(*scope) do
|
@@ -76,7 +76,7 @@ module WithModel
|
|
76
76
|
include MiniTestLifeCycle.call(object)
|
77
77
|
end
|
78
78
|
else
|
79
|
-
raise ArgumentError,
|
79
|
+
raise ArgumentError, "Unsupported test runner set, expected :rspec or :minitest"
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -1,19 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
|
-
describe
|
6
|
-
describe
|
7
|
-
context
|
5
|
+
describe "ActiveRecord behaviors" do
|
6
|
+
describe "a temporary ActiveRecord model created with with_model" do
|
7
|
+
context "that has a named scope" do
|
8
8
|
before do
|
9
9
|
@regular_model = Class.new ActiveRecord::Base do
|
10
|
-
self.table_name =
|
11
|
-
scope :title_is_foo, -> { where(title:
|
10
|
+
self.table_name = "regular_models"
|
11
|
+
scope :title_is_foo, -> { where(title: "foo") }
|
12
12
|
end
|
13
13
|
|
14
14
|
@regular_model.connection.create_table(@regular_model.table_name, force: true) do |t|
|
15
|
-
t.string
|
16
|
-
t.text
|
15
|
+
t.string "title"
|
16
|
+
t.text "content"
|
17
17
|
t.timestamps null: false
|
18
18
|
end
|
19
19
|
end
|
@@ -24,37 +24,37 @@ describe 'ActiveRecord behaviors' do
|
|
24
24
|
|
25
25
|
with_model :BlogPost do
|
26
26
|
table do |t|
|
27
|
-
t.string
|
28
|
-
t.text
|
27
|
+
t.string "title"
|
28
|
+
t.text "content"
|
29
29
|
t.timestamps null: false
|
30
30
|
end
|
31
31
|
|
32
32
|
model do
|
33
|
-
scope :title_is_foo, -> { where(title:
|
33
|
+
scope :title_is_foo, -> { where(title: "foo") }
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
describe
|
38
|
-
it
|
39
|
-
included = @regular_model.create!(title:
|
40
|
-
@regular_model.create!(title:
|
37
|
+
describe "the named scope" do
|
38
|
+
it "works like a regular named scope" do
|
39
|
+
included = @regular_model.create!(title: "foo", content: "Include me!")
|
40
|
+
@regular_model.create!(title: "bar", content: "Include me!")
|
41
41
|
|
42
42
|
expect(@regular_model.title_is_foo).to eq [included]
|
43
43
|
|
44
|
-
included = BlogPost.create!(title:
|
45
|
-
BlogPost.create!(title:
|
44
|
+
included = BlogPost.create!(title: "foo", content: "Include me!")
|
45
|
+
BlogPost.create!(title: "bar", content: "Include me!")
|
46
46
|
|
47
47
|
expect(BlogPost.title_is_foo).to eq [included]
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
context
|
52
|
+
context "that has a polymorphic belongs_to" do
|
53
53
|
before do
|
54
54
|
animal = Class.new ActiveRecord::Base do
|
55
55
|
has_many :tea_cups, as: :pet
|
56
56
|
end
|
57
|
-
stub_const
|
57
|
+
stub_const "Animal", animal
|
58
58
|
end
|
59
59
|
|
60
60
|
with_model :TeaCup do
|
@@ -74,24 +74,24 @@ describe 'ActiveRecord behaviors' do
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
describe
|
78
|
-
it
|
77
|
+
describe "the polymorphic belongs_to" do
|
78
|
+
it "works like a regular polymorphic belongs_to" do
|
79
79
|
animal = Animal.create!
|
80
80
|
stuffed_animal = StuffedAnimal.create!
|
81
81
|
|
82
82
|
tea_cup_for_animal = TeaCup.create!(pet: animal)
|
83
|
-
expect(tea_cup_for_animal.pet_type).to eq
|
83
|
+
expect(tea_cup_for_animal.pet_type).to eq "Animal"
|
84
84
|
expect(animal.tea_cups).to include(tea_cup_for_animal)
|
85
85
|
|
86
86
|
tea_cup_for_stuffed_animal = TeaCup.create!(pet: stuffed_animal)
|
87
|
-
expect(tea_cup_for_stuffed_animal.pet_type).to eq
|
87
|
+
expect(tea_cup_for_stuffed_animal.pet_type).to eq "StuffedAnimal"
|
88
88
|
expect(stuffed_animal.tea_cups).to include(tea_cup_for_stuffed_animal)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
context
|
94
|
+
context "with an association" do
|
95
95
|
with_model :Province do
|
96
96
|
table do |t|
|
97
97
|
t.belongs_to :country
|
@@ -103,13 +103,13 @@ describe 'ActiveRecord behaviors' do
|
|
103
103
|
|
104
104
|
with_model :Country
|
105
105
|
|
106
|
-
context
|
107
|
-
it
|
106
|
+
context "in earlier examples" do
|
107
|
+
it "works as normal" do
|
108
108
|
expect { Province.create!(country: Country.create!) }.not_to raise_error
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
-
context
|
112
|
+
context "in later examples" do
|
113
113
|
it "does not hold a reference to earlier example groups' classes" do
|
114
114
|
expect(Province.reflect_on_association(:country).klass).to eq Country
|
115
115
|
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
module WithModel
|
6
6
|
describe ConstantStubber do
|
7
|
-
it
|
8
|
-
stubber = described_class.new(
|
7
|
+
it "allows calling unstub_const multiple times" do
|
8
|
+
stubber = described_class.new("Foo")
|
9
9
|
stubber.stub_const(1)
|
10
10
|
expect { 2.times { stubber.unstub_const } }.not_to raise_error
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
14
|
-
stubber = described_class.new(
|
13
|
+
it "allows calling unstub_const without stub_const" do
|
14
|
+
stubber = described_class.new("Foo")
|
15
15
|
expect { stubber.unstub_const }.not_to raise_error
|
16
16
|
end
|
17
17
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe "Descendants tracking" do
|
6
|
+
with_model :BlogPost do
|
7
|
+
model do
|
8
|
+
def self.inspect
|
9
|
+
"BlogPost class #{object_id}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def blog_post_classes
|
15
|
+
ActiveRecord::Base.descendants.select do |c|
|
16
|
+
c.table_name == BlogPost.table_name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_examples "clearing descendants between test runs" do
|
21
|
+
it "includes the correct model class in descendants on the first test run" do
|
22
|
+
expect(blog_post_classes).to eq [BlogPost]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "includes the correct model class in descendants on the second test run" do
|
26
|
+
expect(blog_post_classes).to eq [BlogPost]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with ActiveSupport::DescendantsTracker (cache_classes: true)" do
|
31
|
+
before do
|
32
|
+
expect(ActiveSupport::DescendantsTracker.clear_disabled).to be_falsey
|
33
|
+
expect { ActiveSupport::DescendantsTracker.clear([]) }.not_to raise_exception
|
34
|
+
end
|
35
|
+
|
36
|
+
include_examples "clearing descendants between test runs"
|
37
|
+
end
|
38
|
+
|
39
|
+
context "without ActiveSupport::DescendantsTracker (cache_classes: false)" do
|
40
|
+
before do
|
41
|
+
ActiveSupport::DescendantsTracker.disable_clear!
|
42
|
+
expect(ActiveSupport::DescendantsTracker.clear_disabled).to be_truthy
|
43
|
+
expect { ActiveSupport::DescendantsTracker.clear([]) }.to raise_exception(RuntimeError)
|
44
|
+
end
|
45
|
+
|
46
|
+
include_examples "clearing descendants between test runs"
|
47
|
+
end
|
48
|
+
end
|