thermos 0.5.0 → 0.6.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/Rakefile +4 -0
- data/lib/thermos/beverage.rb +42 -24
- data/lib/thermos/notifier.rb +1 -3
- data/lib/thermos/refill_job.rb +9 -5
- data/lib/thermos/version.rb +1 -1
- data/lib/thermos.rb +25 -7
- data/test/dependencies_test.rb +307 -0
- data/test/dummy/app/models/category.rb +8 -6
- data/test/dummy/config/application.rb +1 -4
- data/test/dummy/config/environments/development.rb +1 -1
- data/test/dummy/config/environments/production.rb +2 -1
- data/test/dummy/config/environments/test.rb +2 -2
- data/test/dummy/config/routes.rb +0 -9
- data/test/dummy/db/schema.rb +19 -21
- data/test/filter_test.rb +52 -0
- data/test/fixtures/stores.yml +2 -0
- data/test/queue_test.rb +36 -0
- data/test/test_helper.rb +16 -6
- data/test/thermos_test.rb +47 -297
- metadata +54 -34
data/test/dummy/db/schema.rb
CHANGED
@@ -11,32 +11,30 @@
|
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
13
|
ActiveRecord::Schema.define(version: 2016_03_26_174530) do
|
14
|
-
|
15
|
-
|
16
|
-
t.
|
17
|
-
t.
|
18
|
-
t.datetime
|
19
|
-
t.datetime "updated_at", null: false
|
14
|
+
create_table 'categories', force: :cascade do |t|
|
15
|
+
t.string 'name'
|
16
|
+
t.integer 'store_id'
|
17
|
+
t.datetime 'created_at', null: false
|
18
|
+
t.datetime 'updated_at', null: false
|
20
19
|
end
|
21
20
|
|
22
|
-
create_table
|
23
|
-
t.string
|
24
|
-
t.integer
|
25
|
-
t.integer
|
26
|
-
t.datetime
|
27
|
-
t.datetime
|
21
|
+
create_table 'category_items', force: :cascade do |t|
|
22
|
+
t.string 'name'
|
23
|
+
t.integer 'category_id'
|
24
|
+
t.integer 'product_id'
|
25
|
+
t.datetime 'created_at', null: false
|
26
|
+
t.datetime 'updated_at', null: false
|
28
27
|
end
|
29
28
|
|
30
|
-
create_table
|
31
|
-
t.string
|
32
|
-
t.datetime
|
33
|
-
t.datetime
|
29
|
+
create_table 'products', force: :cascade do |t|
|
30
|
+
t.string 'name'
|
31
|
+
t.datetime 'created_at', null: false
|
32
|
+
t.datetime 'updated_at', null: false
|
34
33
|
end
|
35
34
|
|
36
|
-
create_table
|
37
|
-
t.string
|
38
|
-
t.datetime
|
39
|
-
t.datetime
|
35
|
+
create_table 'stores', force: :cascade do |t|
|
36
|
+
t.string 'name'
|
37
|
+
t.datetime 'created_at', null: false
|
38
|
+
t.datetime 'updated_at', null: false
|
40
39
|
end
|
41
|
-
|
42
40
|
end
|
data/test/filter_test.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FilterTest < ActiveSupport::TestCase
|
4
|
+
self.use_transactional_tests = true
|
5
|
+
teardown :clear_cache
|
6
|
+
|
7
|
+
test 'allows filtering for which records should be rebuilt' do
|
8
|
+
mock = Minitest::Mock.new
|
9
|
+
category = categories(:baseball)
|
10
|
+
filter = ->(model) { model.name.match('ball') }
|
11
|
+
Thermos.fill(
|
12
|
+
key: 'key',
|
13
|
+
model: Category,
|
14
|
+
lookup_key: 'name',
|
15
|
+
filter: filter,
|
16
|
+
) { |name| mock.call(name) }
|
17
|
+
|
18
|
+
mock.expect(:call, 1, ['basketball'])
|
19
|
+
category.update!(name: 'basketball')
|
20
|
+
mock.verify
|
21
|
+
|
22
|
+
mock.expect(:call, 1, ['hockey'])
|
23
|
+
category.update!(name: 'hockey')
|
24
|
+
assert_raises(MockExpectationError) { mock.verify }
|
25
|
+
end
|
26
|
+
|
27
|
+
test 'allows filtering based on the beverage when multiple beverages are configured and only one of them has a filter' do
|
28
|
+
mock = Minitest::Mock.new
|
29
|
+
store = stores(:supermarket)
|
30
|
+
category = categories(:baseball)
|
31
|
+
|
32
|
+
# filter method specific to one model
|
33
|
+
# store.ball? doesn't exist
|
34
|
+
filter = ->(model) { model.ball? }
|
35
|
+
|
36
|
+
Thermos.fill(
|
37
|
+
key: 'key',
|
38
|
+
model: Category,
|
39
|
+
lookup_key: 'name',
|
40
|
+
filter: filter,
|
41
|
+
) { |name| mock.call(name) }
|
42
|
+
|
43
|
+
Thermos.fill(key: 'key_2', model: Store, lookup_key: 'name') do |name|
|
44
|
+
mock.call(name)
|
45
|
+
end
|
46
|
+
|
47
|
+
mock.expect(:call, 1, ['groceries'])
|
48
|
+
store.update!(name: 'groceries')
|
49
|
+
assert_equal 1, Thermos.drink(key: 'key_2', id: 'groceries')
|
50
|
+
mock.verify
|
51
|
+
end
|
52
|
+
end
|
data/test/fixtures/stores.yml
CHANGED
data/test/queue_test.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class QueueTest < ActiveSupport::TestCase
|
4
|
+
include ActiveJob::TestHelper
|
5
|
+
self.use_transactional_tests = true
|
6
|
+
teardown :clear_cache
|
7
|
+
|
8
|
+
test 'uses the default background queue by default' do
|
9
|
+
mock = Minitest::Mock.new
|
10
|
+
category = categories(:baseball)
|
11
|
+
|
12
|
+
Thermos.fill(key: 'key', model: Category) { |id| mock.call(id) }
|
13
|
+
|
14
|
+
mock.expect(:call, 1, [category.id])
|
15
|
+
assert_performed_with(job: Thermos::RebuildCacheJob, queue: 'default') do
|
16
|
+
category.update!(name: 'foo')
|
17
|
+
end
|
18
|
+
mock.verify
|
19
|
+
end
|
20
|
+
|
21
|
+
test 'can specify a preferred queue name for the cache filling' do
|
22
|
+
mock = Minitest::Mock.new
|
23
|
+
category = categories(:baseball)
|
24
|
+
|
25
|
+
Thermos.fill(key: 'key', model: Category, queue: 'low_priority') do |id|
|
26
|
+
mock.call(id)
|
27
|
+
end
|
28
|
+
|
29
|
+
mock.expect(:call, 1, [category.id])
|
30
|
+
assert_performed_with(
|
31
|
+
job: Thermos::RebuildCacheJob,
|
32
|
+
queue: 'low_priority',
|
33
|
+
) { category.update!(name: 'foo') }
|
34
|
+
mock.verify
|
35
|
+
end
|
36
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# Configure Rails Environment
|
2
|
-
ENV[
|
2
|
+
ENV['RAILS_ENV'] = 'test'
|
3
3
|
|
4
|
-
require File.expand_path(
|
5
|
-
ActiveRecord::Migrator.migrations_paths = [
|
6
|
-
|
4
|
+
require File.expand_path('../../test/dummy/config/environment.rb', __FILE__)
|
5
|
+
ActiveRecord::Migrator.migrations_paths = [
|
6
|
+
File.expand_path('../../test/dummy/db/migrate', __FILE__),
|
7
|
+
]
|
8
|
+
require 'rails/test_help'
|
7
9
|
|
8
10
|
# Filter out Minitest backtrace while allowing backtrace from other libraries
|
9
11
|
# to be shown.
|
@@ -15,9 +17,17 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
15
17
|
|
16
18
|
# Load fixtures from the engine
|
17
19
|
if ActiveSupport::TestCase.respond_to?(:fixture_path=)
|
18
|
-
ActiveSupport::TestCase.fixture_path =
|
19
|
-
|
20
|
+
ActiveSupport::TestCase.fixture_path =
|
21
|
+
File.expand_path('../fixtures', __FILE__)
|
22
|
+
ActionDispatch::IntegrationTest.fixture_path =
|
23
|
+
ActiveSupport::TestCase.fixture_path
|
20
24
|
ActiveSupport::TestCase.fixtures :all
|
21
25
|
end
|
22
26
|
|
23
27
|
ActiveJob::Base.queue_adapter = :inline
|
28
|
+
ActiveSupport.test_order = :random
|
29
|
+
|
30
|
+
def clear_cache
|
31
|
+
Thermos::BeverageStorage.instance.empty
|
32
|
+
Rails.cache.clear
|
33
|
+
end
|
data/test/thermos_test.rb
CHANGED
@@ -1,404 +1,154 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class ThermosTest < ActiveSupport::TestCase
|
4
|
-
ActiveSupport.test_order = :random
|
5
4
|
self.use_transactional_tests = true
|
5
|
+
teardown :clear_cache
|
6
6
|
|
7
|
-
|
8
|
-
Thermos::BeverageStorage.instance.empty
|
9
|
-
Rails.cache.clear
|
10
|
-
end
|
11
|
-
|
12
|
-
test "keeps the cache warm using fill / drink" do
|
7
|
+
test 'keeps the cache warm using fill / drink' do
|
13
8
|
mock = Minitest::Mock.new
|
14
9
|
|
15
|
-
Thermos.fill(key:
|
16
|
-
mock.call(id)
|
17
|
-
end
|
10
|
+
Thermos.fill(key: 'key', model: Category) { |id| mock.call(id) }
|
18
11
|
|
19
12
|
mock.expect(:call, 1, [1])
|
20
|
-
assert_equal 1, Thermos.drink(key:
|
13
|
+
assert_equal 1, Thermos.drink(key: 'key', id: 1)
|
21
14
|
mock.verify
|
22
15
|
|
23
16
|
mock.expect(:call, 2, [1])
|
24
|
-
assert_equal 1, Thermos.drink(key:
|
17
|
+
assert_equal 1, Thermos.drink(key: 'key', id: 1)
|
25
18
|
assert_raises(MockExpectationError) { mock.verify }
|
26
19
|
end
|
27
20
|
|
28
|
-
test
|
21
|
+
test 'keeps the cache warm using keep_warm' do
|
29
22
|
mock = Minitest::Mock.new
|
30
23
|
|
31
24
|
mock.expect(:call, 1, [1])
|
32
|
-
response =
|
33
|
-
|
34
|
-
|
25
|
+
response =
|
26
|
+
Thermos.keep_warm(key: 'key', model: Category, id: 1) do |id|
|
27
|
+
mock.call(id)
|
28
|
+
end
|
35
29
|
assert_equal 1, response
|
36
30
|
mock.verify
|
37
31
|
|
38
32
|
mock.expect(:call, 2, [1])
|
39
|
-
response =
|
40
|
-
|
41
|
-
|
33
|
+
response =
|
34
|
+
Thermos.keep_warm(key: 'key', model: Category, id: 1) do |id|
|
35
|
+
mock.call(id)
|
36
|
+
end
|
42
37
|
assert_equal 1, response
|
43
38
|
assert_raises(MockExpectationError) { mock.verify }
|
44
39
|
end
|
45
40
|
|
46
|
-
# primary model changes
|
47
|
-
test
|
41
|
+
# primary model changes
|
42
|
+
test 'rebuilds the cache on primary model change' do
|
48
43
|
mock = Minitest::Mock.new
|
49
44
|
category = categories(:baseball)
|
50
45
|
|
51
|
-
Thermos.fill(key:
|
52
|
-
mock.call(id)
|
53
|
-
end
|
46
|
+
Thermos.fill(key: 'key', model: Category) { |id| mock.call(id) }
|
54
47
|
|
55
48
|
mock.expect(:call, 1, [category.id])
|
56
|
-
assert_equal 1, Thermos.drink(key:
|
49
|
+
assert_equal 1, Thermos.drink(key: 'key', id: category.id)
|
57
50
|
mock.verify
|
58
51
|
|
59
52
|
mock.expect(:call, 2, [category.id])
|
60
|
-
category.update!(name:
|
53
|
+
category.update!(name: 'foo')
|
61
54
|
mock.verify
|
62
55
|
|
63
56
|
mock.expect(:call, 3, [category.id])
|
64
|
-
assert_equal 2, Thermos.drink(key:
|
57
|
+
assert_equal 2, Thermos.drink(key: 'key', id: category.id)
|
65
58
|
assert_raises(MockExpectationError) { mock.verify }
|
66
59
|
end
|
67
60
|
|
68
|
-
test
|
61
|
+
test 'does not rebuild the cache on rolled back primary model change' do
|
69
62
|
mock = Minitest::Mock.new
|
70
63
|
category = categories(:baseball)
|
71
64
|
|
72
|
-
Thermos.fill(key:
|
73
|
-
mock.call(id)
|
74
|
-
end
|
65
|
+
Thermos.fill(key: 'key', model: Category) { |id| mock.call(id) }
|
75
66
|
|
76
67
|
mock.expect(:call, 1, [category.id])
|
77
|
-
assert_equal 1, Thermos.drink(key:
|
68
|
+
assert_equal 1, Thermos.drink(key: 'key', id: category.id)
|
78
69
|
mock.verify
|
79
70
|
|
80
71
|
mock.expect(:call, 2, [category.id])
|
81
72
|
ActiveRecord::Base.transaction do
|
82
|
-
category.update!(name:
|
73
|
+
category.update!(name: 'foo')
|
83
74
|
raise ActiveRecord::Rollback
|
84
75
|
end
|
85
76
|
assert_raises(MockExpectationError) { mock.verify }
|
86
77
|
|
87
78
|
mock.expect(:call, 3, [category.id])
|
88
|
-
assert_equal 1, Thermos.drink(key:
|
79
|
+
assert_equal 1, Thermos.drink(key: 'key', id: category.id)
|
89
80
|
assert_raises(MockExpectationError) { mock.verify }
|
90
81
|
end
|
91
82
|
|
92
|
-
test
|
83
|
+
test 'does not rebuild the cache for an unrelated primary model change' do
|
93
84
|
mock = Minitest::Mock.new
|
94
85
|
category = categories(:baseball)
|
95
|
-
other_category = Category.create!(name:
|
86
|
+
other_category = Category.create!(name: 'bar')
|
96
87
|
|
97
|
-
Thermos.fill(key:
|
98
|
-
mock.call(id)
|
99
|
-
end
|
88
|
+
Thermos.fill(key: 'key', model: Category) { |id| mock.call(id) }
|
100
89
|
|
101
90
|
mock.expect(:call, 2, [other_category.id])
|
102
|
-
assert_equal 2, Thermos.drink(key:
|
91
|
+
assert_equal 2, Thermos.drink(key: 'key', id: other_category.id)
|
103
92
|
mock.verify
|
104
93
|
|
105
94
|
mock.expect(:call, 1, [category.id])
|
106
|
-
category.update!(name:
|
95
|
+
category.update!(name: 'foo')
|
107
96
|
mock.verify
|
108
97
|
|
109
98
|
mock.expect(:call, 3, [other_category.id])
|
110
|
-
assert_equal 2, Thermos.drink(key:
|
111
|
-
assert_raises(MockExpectationError) { mock.verify }
|
112
|
-
end
|
113
|
-
|
114
|
-
test "pre-builds cache for new primary model records" do
|
115
|
-
mock = Minitest::Mock.new
|
116
|
-
|
117
|
-
Thermos.fill(key: "key", model: Category, lookup_key: "name") do |name|
|
118
|
-
mock.call(name)
|
119
|
-
end
|
120
|
-
|
121
|
-
mock.expect(:call, 1, ["foo"])
|
122
|
-
Category.create!(name: "foo")
|
123
|
-
mock.verify
|
124
|
-
|
125
|
-
mock.expect(:call, 2, ["foo"])
|
126
|
-
assert_equal 1, Thermos.drink(key: "key", id: "foo")
|
127
|
-
assert_raises(MockExpectationError) { mock.verify }
|
128
|
-
end
|
129
|
-
|
130
|
-
test "allows filtering for which records should be rebuilt" do
|
131
|
-
mock = Minitest::Mock.new
|
132
|
-
category = categories(:baseball)
|
133
|
-
filter = ->(model) { model.name.match("ball") }
|
134
|
-
Thermos.fill(key: "key", model: Category, lookup_key: "name", filter: filter) do |name|
|
135
|
-
mock.call(name)
|
136
|
-
end
|
137
|
-
|
138
|
-
mock.expect(:call, 1, ["basketball"])
|
139
|
-
category.update!(name: "basketball")
|
140
|
-
mock.verify
|
141
|
-
|
142
|
-
mock.expect(:call, 1, ["hockey"])
|
143
|
-
category.update!(name: "hockey")
|
144
|
-
assert_raises(MockExpectationError) { mock.verify }
|
145
|
-
end
|
146
|
-
|
147
|
-
# has_many model changes
|
148
|
-
test "rebuilds the cache on has_many model change" do
|
149
|
-
mock = Minitest::Mock.new
|
150
|
-
category = categories(:baseball)
|
151
|
-
category_item = category_items(:baseball_glove)
|
152
|
-
|
153
|
-
Thermos.fill(key: "key", model: Category, deps: [:category_items]) do |id|
|
154
|
-
mock.call(id)
|
155
|
-
end
|
156
|
-
|
157
|
-
mock.expect(:call, 1, [category.id])
|
158
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
159
|
-
mock.verify
|
160
|
-
|
161
|
-
mock.expect(:call, 2, [category.id])
|
162
|
-
category_item.update!(name: "foo")
|
163
|
-
mock.verify
|
164
|
-
|
165
|
-
mock.expect(:call, 3, [category.id])
|
166
|
-
assert_equal 2, Thermos.drink(key: "key", id: category.id)
|
167
|
-
assert_raises(MockExpectationError) { mock.verify }
|
168
|
-
end
|
169
|
-
|
170
|
-
test "does not rebuild the cache for an unrelated has_many model change" do
|
171
|
-
mock = Minitest::Mock.new
|
172
|
-
category = categories(:baseball)
|
173
|
-
category_item = CategoryItem.create(category: nil)
|
174
|
-
|
175
|
-
Thermos.fill(key: "key", model: Category, deps: [:category_items]) do |id|
|
176
|
-
mock.call(id)
|
177
|
-
end
|
178
|
-
|
179
|
-
mock.expect(:call, 1, [category.id])
|
180
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
181
|
-
mock.verify
|
182
|
-
|
183
|
-
mock.expect(:call, 2, [category.id])
|
184
|
-
category_item.update!(name: "foo")
|
185
|
-
assert_raises(MockExpectationError) { mock.verify }
|
186
|
-
|
187
|
-
mock.expect(:call, 3, [category.id])
|
188
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
189
|
-
assert_raises(MockExpectationError) { mock.verify }
|
190
|
-
end
|
191
|
-
|
192
|
-
test "re-builds the cache for new has_many records" do
|
193
|
-
mock = Minitest::Mock.new
|
194
|
-
category = categories(:baseball)
|
195
|
-
|
196
|
-
Thermos.fill(key: "key", model: Category, deps: [:category_items]) do |id|
|
197
|
-
mock.call(id)
|
198
|
-
end
|
199
|
-
|
200
|
-
mock.expect(:call, 1, [category.id])
|
201
|
-
CategoryItem.create!(category: category)
|
202
|
-
mock.verify
|
203
|
-
|
204
|
-
mock.expect(:call, 2, [category.id])
|
205
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
206
|
-
assert_raises(MockExpectationError) { mock.verify }
|
207
|
-
end
|
208
|
-
|
209
|
-
# belongs_to model changes
|
210
|
-
test "rebuilds the cache on belongs_to model change" do
|
211
|
-
mock = Minitest::Mock.new
|
212
|
-
category = categories(:baseball)
|
213
|
-
store = stores(:sports)
|
214
|
-
|
215
|
-
Thermos.fill(key: "key", model: Category, deps: [:store]) do |id|
|
216
|
-
mock.call(id)
|
217
|
-
end
|
218
|
-
|
219
|
-
mock.expect(:call, 1, [category.id])
|
220
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
221
|
-
mock.verify
|
222
|
-
|
223
|
-
mock.expect(:call, 2, [category.id])
|
224
|
-
store.update!(name: "foo")
|
225
|
-
mock.verify
|
226
|
-
|
227
|
-
mock.expect(:call, 3, [category.id])
|
228
|
-
assert_equal 2, Thermos.drink(key: "key", id: category.id)
|
229
|
-
assert_raises(MockExpectationError) { mock.verify }
|
230
|
-
end
|
231
|
-
|
232
|
-
test "does not rebuild the cache for an unrelated belongs_to model change" do
|
233
|
-
mock = Minitest::Mock.new
|
234
|
-
category = categories(:baseball)
|
235
|
-
store = Store.create!
|
236
|
-
|
237
|
-
Thermos.fill(key: "key", model: Category, deps: [:store]) do |id|
|
238
|
-
mock.call(id)
|
239
|
-
end
|
240
|
-
|
241
|
-
mock.expect(:call, 1, [category.id])
|
242
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
243
|
-
mock.verify
|
244
|
-
|
245
|
-
mock.expect(:call, 2, [category.id])
|
246
|
-
store.update!(name: "foo")
|
247
|
-
assert_raises(MockExpectationError) { mock.verify }
|
248
|
-
|
249
|
-
mock.expect(:call, 3, [category.id])
|
250
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
251
|
-
assert_raises(MockExpectationError) { mock.verify }
|
252
|
-
end
|
253
|
-
|
254
|
-
test "re-builds the cache for new belongs_to records" do
|
255
|
-
mock = Minitest::Mock.new
|
256
|
-
category = categories(:baseball)
|
257
|
-
|
258
|
-
Thermos.fill(key: "key", model: Category, deps: [:store]) do |id|
|
259
|
-
mock.call(id)
|
260
|
-
end
|
261
|
-
|
262
|
-
mock.expect(:call, 1, [category.id])
|
263
|
-
mock.expect(:call, 1, [category.id])
|
264
|
-
Store.create!(name: "foo", categories: [category])
|
265
|
-
mock.verify
|
266
|
-
|
267
|
-
mock.expect(:call, 2, [category.id])
|
268
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
269
|
-
assert_raises(MockExpectationError) { mock.verify }
|
270
|
-
end
|
271
|
-
|
272
|
-
# has_many through model changes
|
273
|
-
test "rebuilds the cache on has_many through model change" do
|
274
|
-
mock = Minitest::Mock.new
|
275
|
-
category = categories(:baseball)
|
276
|
-
product = products(:glove)
|
277
|
-
|
278
|
-
Thermos.fill(key: "key", model: Category, deps: [:products]) do |id|
|
279
|
-
mock.call(id)
|
280
|
-
end
|
281
|
-
|
282
|
-
mock.expect(:call, 1, [category.id])
|
283
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
284
|
-
mock.verify
|
285
|
-
|
286
|
-
mock.expect(:call, 2, [category.id])
|
287
|
-
product.update!(name: "foo")
|
288
|
-
mock.verify
|
289
|
-
|
290
|
-
mock.expect(:call, 3, [category.id])
|
291
|
-
assert_equal 2, Thermos.drink(key: "key", id: category.id)
|
99
|
+
assert_equal 2, Thermos.drink(key: 'key', id: other_category.id)
|
292
100
|
assert_raises(MockExpectationError) { mock.verify }
|
293
101
|
end
|
294
102
|
|
295
|
-
test
|
103
|
+
test 'does not rebuild the cache on primary model destroy' do
|
296
104
|
mock = Minitest::Mock.new
|
297
105
|
category = categories(:baseball)
|
298
|
-
product = Product.create!
|
299
106
|
|
300
|
-
Thermos.fill(key:
|
301
|
-
mock.call(id)
|
302
|
-
end
|
107
|
+
Thermos.fill(key: 'key', model: Category) { |id| mock.call(id) }
|
303
108
|
|
304
109
|
mock.expect(:call, 1, [category.id])
|
305
|
-
assert_equal 1, Thermos.drink(key:
|
110
|
+
assert_equal 1, Thermos.drink(key: 'key', id: category.id)
|
306
111
|
mock.verify
|
307
112
|
|
308
113
|
mock.expect(:call, 2, [category.id])
|
309
|
-
|
310
|
-
assert_raises(MockExpectationError) { mock.verify }
|
311
|
-
|
312
|
-
mock.expect(:call, 3, [category.id])
|
313
|
-
assert_equal 1, Thermos.drink(key: "key", id: category.id)
|
114
|
+
category.destroy!
|
314
115
|
assert_raises(MockExpectationError) { mock.verify }
|
315
116
|
end
|
316
117
|
|
317
|
-
test
|
118
|
+
test 'pre-builds cache for new primary model records' do
|
318
119
|
mock = Minitest::Mock.new
|
319
|
-
category = categories(:baseball)
|
320
120
|
|
321
|
-
Thermos.fill(key:
|
322
|
-
mock.call(
|
121
|
+
Thermos.fill(key: 'key', model: Category, lookup_key: 'name') do |name|
|
122
|
+
mock.call(name)
|
323
123
|
end
|
324
124
|
|
325
|
-
mock.expect(:call, 1, [
|
326
|
-
|
125
|
+
mock.expect(:call, 1, ['foo'])
|
126
|
+
Category.create!(name: 'foo')
|
327
127
|
mock.verify
|
328
128
|
|
329
|
-
mock.expect(:call, 2, [
|
330
|
-
assert_equal 1, Thermos.drink(key:
|
129
|
+
mock.expect(:call, 2, ['foo'])
|
130
|
+
assert_equal 1, Thermos.drink(key: 'key', id: 'foo')
|
331
131
|
assert_raises(MockExpectationError) { mock.verify }
|
332
132
|
end
|
333
133
|
|
334
|
-
test "handles indirect associations" do
|
335
|
-
mock = Minitest::Mock.new
|
336
|
-
category = categories(:baseball)
|
337
|
-
store = category.store
|
338
|
-
|
339
|
-
Thermos.fill(key: "key", model: Store, deps: [categories: [:products]]) do |id|
|
340
|
-
mock.call(id)
|
341
|
-
end
|
342
|
-
|
343
|
-
mock.expect(:call, 1, [store.id])
|
344
|
-
category.update!(name: "foo")
|
345
|
-
mock.verify
|
346
|
-
|
347
|
-
mock.expect(:call, 2, [store.id])
|
348
|
-
assert_equal 1, Thermos.drink(key: "key", id: store.id)
|
349
|
-
assert_raises(MockExpectationError) { mock.verify }
|
350
|
-
Product.create!(categories: [category])
|
351
|
-
mock.verify
|
352
|
-
|
353
|
-
mock.expect(:call, 3, [store.id])
|
354
|
-
assert_equal 2, Thermos.drink(key: "key", id: store.id)
|
355
|
-
assert_raises(MockExpectationError) { mock.verify }
|
356
|
-
end
|
357
|
-
|
358
|
-
test "only rebuilds cache for stated dependencies, even if another cache has an associated model of the primary" do
|
359
|
-
category_mock = Minitest::Mock.new
|
360
|
-
product_mock = Minitest::Mock.new
|
361
|
-
category = categories(:baseball)
|
362
|
-
product = products(:glove)
|
363
|
-
|
364
|
-
Thermos.fill(key: "category_key", model: Category) do |id|
|
365
|
-
category_mock.call(id)
|
366
|
-
end
|
367
|
-
|
368
|
-
Thermos.fill(key: "product_key", model: Product) do |id|
|
369
|
-
product_mock.call(id)
|
370
|
-
end
|
371
|
-
|
372
|
-
category_mock.expect(:call, 2, [category.id])
|
373
|
-
product_mock.expect(:call, 2, [product.id])
|
374
|
-
product.update!(name: "foo")
|
375
|
-
assert_raises(MockExpectationError) { category_mock.verify }
|
376
|
-
product_mock.verify
|
377
|
-
end
|
378
|
-
|
379
134
|
test "accepts and can rebuild off of an id other than the 'id'" do
|
380
135
|
mock = Minitest::Mock.new
|
381
136
|
category = categories(:baseball)
|
382
|
-
product = products(:glove)
|
383
137
|
|
384
|
-
Thermos.fill(key:
|
138
|
+
Thermos.fill(key: 'key', model: Category, lookup_key: :name) do |id|
|
385
139
|
mock.call(id)
|
386
140
|
end
|
387
141
|
|
388
142
|
mock.expect(:call, 1, [category.name])
|
389
|
-
assert_equal 1, Thermos.drink(key:
|
143
|
+
assert_equal 1, Thermos.drink(key: 'key', id: category.name)
|
390
144
|
mock.verify
|
391
145
|
|
392
|
-
mock.expect(:call, 2, [
|
393
|
-
category.update!(name:
|
146
|
+
mock.expect(:call, 2, ['foo'])
|
147
|
+
category.update!(name: 'foo')
|
394
148
|
mock.verify
|
395
149
|
|
396
150
|
mock.expect(:call, 3, [category.name])
|
397
|
-
|
398
|
-
mock.verify
|
399
|
-
|
400
|
-
mock.expect(:call, 4, [category.name])
|
401
|
-
assert_equal 3, Thermos.drink(key: "key", id: category.name)
|
151
|
+
assert_equal 2, Thermos.drink(key: 'key', id: category.name)
|
402
152
|
assert_raises(MockExpectationError) { mock.verify }
|
403
153
|
end
|
404
154
|
end
|