nanoc 4.5.2 → 4.5.3

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +7 -7
  3. data/NEWS.md +7 -0
  4. data/lib/nanoc/base/entities/item_rep.rb +0 -46
  5. data/lib/nanoc/base/repos.rb +1 -0
  6. data/lib/nanoc/base/repos/snapshot_repo.rb +60 -0
  7. data/lib/nanoc/base/services/compiler.rb +30 -17
  8. data/lib/nanoc/base/services/executor.rb +17 -8
  9. data/lib/nanoc/base/services/item_rep_writer.rb +3 -3
  10. data/lib/nanoc/base/views/item_rep_collection_view.rb +1 -1
  11. data/lib/nanoc/base/views/item_rep_view.rb +2 -2
  12. data/lib/nanoc/base/views/post_compile_item_rep_view.rb +9 -7
  13. data/lib/nanoc/base/views/view_context.rb +3 -1
  14. data/lib/nanoc/cli/commands/compile.rb +3 -3
  15. data/lib/nanoc/cli/commands/shell.rb +1 -0
  16. data/lib/nanoc/extra/parallel_collection.rb +1 -1
  17. data/lib/nanoc/helpers/capturing.rb +9 -5
  18. data/lib/nanoc/rule_dsl/action_provider.rb +2 -0
  19. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +4 -1
  20. data/lib/nanoc/spec.rb +17 -18
  21. data/lib/nanoc/version.rb +1 -1
  22. data/spec/nanoc/base/compiler_spec.rb +9 -8
  23. data/spec/nanoc/base/entities/item_rep_spec.rb +0 -222
  24. data/spec/nanoc/base/filter_spec.rb +1 -0
  25. data/spec/nanoc/base/item_rep_writer_spec.rb +9 -4
  26. data/spec/nanoc/base/repos/snapshot_repo_spec.rb +314 -0
  27. data/spec/nanoc/base/services/compiler/phases/cache_spec.rb +107 -0
  28. data/spec/nanoc/base/services/executor_spec.rb +230 -44
  29. data/spec/nanoc/base/views/document_view_spec.rb +1 -0
  30. data/spec/nanoc/base/views/item_rep_view_spec.rb +18 -5
  31. data/spec/nanoc/base/views/item_view_spec.rb +18 -7
  32. data/spec/nanoc/base/views/mutable_document_view_spec.rb +6 -5
  33. data/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb +8 -3
  34. data/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb +3 -3
  35. data/spec/nanoc/helpers/capturing_spec.rb +8 -5
  36. data/spec/nanoc/regressions/gh_1064_spec.rb +18 -0
  37. data/spec/nanoc/rule_dsl/rule_context_spec.rb +2 -1
  38. data/spec/nanoc/rule_dsl/rule_memory_calculator_spec.rb +15 -3
  39. data/spec/spec_helper.rb +43 -0
  40. data/test/cli/commands/test_compile.rb +1 -1
  41. data/test/filters/test_xsl.rb +1 -0
  42. data/test/helpers/test_capturing.rb +9 -2
  43. data/test/helpers/test_xml_sitemap.rb +1 -1
  44. metadata +6 -2
@@ -7,6 +7,7 @@ describe Nanoc::Int::Executor do
7
7
  reps: reps,
8
8
  site: site,
9
9
  compiled_content_cache: compiled_content_cache,
10
+ snapshot_repo: snapshot_repo,
10
11
  )
11
12
  end
12
13
 
@@ -18,6 +19,7 @@ describe Nanoc::Int::Executor do
18
19
  let(:reps) { double(:reps) }
19
20
  let(:site) { double(:site) }
20
21
  let(:compiled_content_cache) { double(:compiled_content_cache) }
22
+ let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new }
21
23
 
22
24
  let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(double(:dependency_store)) }
23
25
 
@@ -31,29 +33,61 @@ describe Nanoc::Int::Executor do
31
33
  end
32
34
 
33
35
  context 'normal flow with textual rep' do
36
+ subject { executor.filter(:erb) }
37
+
34
38
  before do
35
39
  expect(Nanoc::Int::NotificationCenter)
36
40
  .to receive(:post).with(:filtering_started, rep, :erb)
37
41
  expect(Nanoc::Int::NotificationCenter)
38
42
  .to receive(:post).with(:filtering_ended, rep, :erb)
43
+
44
+ snapshot_repo.set(rep, :last, content)
39
45
  end
40
46
 
41
- example do
42
- executor.filter(:erb)
47
+ it 'does not set :pre on rep' do
48
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
49
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
50
+ end
43
51
 
44
- expect(rep.snapshot_contents[:last].string).to eq('Donkey Power')
45
- expect(rep.snapshot_contents[:pre]).to be_nil
46
- expect(rep.snapshot_contents[:post]).to be_nil
52
+ it 'does not set :post on rep' do
53
+ expect(snapshot_repo.get(rep, :post)).to be_nil
54
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
55
+ end
56
+
57
+ it 'updates :last on rep' do
58
+ expect { subject }
59
+ .to change { snapshot_repo.get(rep, :last).string }
60
+ .from('<%= "Donkey" %> Power')
61
+ .to('Donkey Power')
62
+ end
63
+
64
+ it 'does not set :pre in repo' do
65
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
66
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
67
+ end
68
+
69
+ it 'does not set :post in repo' do
70
+ expect(snapshot_repo.get(rep, :post)).to be_nil
71
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
72
+ end
73
+
74
+ it 'updates :last in repo' do
75
+ expect { subject }
76
+ .to change { snapshot_repo.get(rep, :last).string }
77
+ .from('<%= "Donkey" %> Power')
78
+ .to('Donkey Power')
47
79
  end
48
80
 
49
81
  it 'returns frozen data' do
50
82
  executor.filter(:erb)
51
83
 
52
- expect(rep.snapshot_contents[:last]).to be_frozen
84
+ expect(snapshot_repo.get(rep, :last)).to be_frozen
53
85
  end
54
86
  end
55
87
 
56
88
  context 'normal flow with binary rep' do
89
+ subject { executor.filter(:whatever) }
90
+
57
91
  let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) }
58
92
 
59
93
  before do
@@ -73,25 +107,54 @@ describe Nanoc::Int::Executor do
73
107
  end
74
108
 
75
109
  expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class }
110
+
111
+ snapshot_repo.set(rep, :last, content)
76
112
  end
77
113
 
78
- example do
79
- executor.filter(:whatever)
114
+ it 'does not set :pre on rep' do
115
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
116
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
117
+ end
118
+
119
+ it 'does not set :post on rep' do
120
+ expect(snapshot_repo.get(rep, :post)).to be_nil
121
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
122
+ end
123
+
124
+ it 'updates :last on rep' do
125
+ expect { subject }
126
+ .to change { snapshot_repo.get(rep, :last) }
127
+ .from(some_binary_content('Foo Data'))
128
+ .to(some_binary_content(/\ACompiled data for \/.*\/foo.dat\z/))
129
+ end
130
+
131
+ it 'does not set :pre in repo' do
132
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
133
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
134
+ end
80
135
 
81
- expect(File.read(rep.snapshot_contents[:last].filename))
82
- .to match(/\ACompiled data for \/.*\/foo.dat\z/)
83
- expect(rep.snapshot_contents[:pre]).to be_nil
84
- expect(rep.snapshot_contents[:post]).to be_nil
136
+ it 'does not set :post in repo' do
137
+ expect(snapshot_repo.get(rep, :post)).to be_nil
138
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
139
+ end
140
+
141
+ it 'updates :last in repo' do
142
+ expect { subject }
143
+ .to change { File.read(snapshot_repo.get(rep, :last).filename) }
144
+ .from('Foo Data')
145
+ .to(/\ACompiled data for \/.*\/foo.dat\z/)
85
146
  end
86
147
 
87
148
  it 'returns frozen data' do
88
149
  executor.filter(:whatever)
89
150
 
90
- expect(rep.snapshot_contents[:last]).to be_frozen
151
+ expect(snapshot_repo.get(rep, :last)).to be_frozen
91
152
  end
92
153
  end
93
154
 
94
155
  context 'normal flow with binary rep and binary-to-text filter' do
156
+ subject { executor.filter(:whatever) }
157
+
95
158
  let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) }
96
159
 
97
160
  before do
@@ -111,18 +174,48 @@ describe Nanoc::Int::Executor do
111
174
  end
112
175
 
113
176
  expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class }
177
+
178
+ snapshot_repo.set(rep, :last, content)
114
179
  end
115
180
 
116
- example do
117
- executor.filter(:whatever)
181
+ it 'does not set :pre on rep' do
182
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
183
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
184
+ end
118
185
 
119
- expect(rep.snapshot_contents[:last].string).to match(/\ACompiled data for \/.*\/foo.dat\z/)
120
- expect(rep.snapshot_contents[:pre]).to be_nil
121
- expect(rep.snapshot_contents[:post]).to be_nil
186
+ it 'does not set :post on rep' do
187
+ expect(snapshot_repo.get(rep, :post)).to be_nil
188
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
189
+ end
190
+
191
+ it 'updates :last on rep' do
192
+ expect { subject }
193
+ .to change { snapshot_repo.get(rep, :last) }
194
+ .from(some_binary_content('Foo Data'))
195
+ .to(some_textual_content(/\ACompiled data for \/.*\/foo.dat\z/))
196
+ end
197
+
198
+ it 'does not set :pre in repo' do
199
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
200
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
201
+ end
202
+
203
+ it 'does not set :post in repo' do
204
+ expect(snapshot_repo.get(rep, :post)).to be_nil
205
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
206
+ end
207
+
208
+ it 'updates :last in repo' do
209
+ expect { subject }
210
+ .to change { snapshot_repo.get(rep, :last) }
211
+ .from(some_binary_content('Foo Data'))
212
+ .to(some_textual_content(/\ACompiled data for \/.*\/foo.dat\z/))
122
213
  end
123
214
  end
124
215
 
125
216
  context 'normal flow with textual rep and text-to-binary filter' do
217
+ subject { executor.filter(:whatever) }
218
+
126
219
  before do
127
220
  expect(Nanoc::Int::NotificationCenter)
128
221
  .to receive(:post).with(:filtering_started, rep, :whatever)
@@ -138,15 +231,42 @@ describe Nanoc::Int::Executor do
138
231
  end
139
232
 
140
233
  expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class }
234
+
235
+ snapshot_repo.set(rep, :last, content)
141
236
  end
142
237
 
143
- example do
144
- executor.filter(:whatever)
238
+ it 'does not set :pre on rep' do
239
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
240
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
241
+ end
242
+
243
+ it 'does not set :post on rep' do
244
+ expect(snapshot_repo.get(rep, :post)).to be_nil
245
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
246
+ end
247
+
248
+ it 'updates :last on rep' do
249
+ expect { subject }
250
+ .to change { snapshot_repo.get(rep, :last) }
251
+ .from(some_textual_content('<%= "Donkey" %> Power'))
252
+ .to(some_binary_content('Binary <%= "Donkey" %> Power'))
253
+ end
145
254
 
146
- expect(File.read(rep.snapshot_contents[:last].filename))
147
- .to eq('Binary <%= "Donkey" %> Power')
148
- expect(rep.snapshot_contents[:pre]).to be_nil
149
- expect(rep.snapshot_contents[:post]).to be_nil
255
+ it 'does not set :pre in repo' do
256
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
257
+ expect { subject }.not_to change { snapshot_repo.get(rep, :pre) }
258
+ end
259
+
260
+ it 'does not set :post in repo' do
261
+ expect(snapshot_repo.get(rep, :post)).to be_nil
262
+ expect { subject }.not_to change { snapshot_repo.get(rep, :post) }
263
+ end
264
+
265
+ it 'updates :last in repo' do
266
+ expect { subject }
267
+ .to change { snapshot_repo.get(rep, :last) }
268
+ .from(some_textual_content('<%= "Donkey" %> Power'))
269
+ .to(some_binary_content('Binary <%= "Donkey" %> Power'))
150
270
  end
151
271
  end
152
272
 
@@ -166,6 +286,8 @@ describe Nanoc::Int::Executor do
166
286
  end
167
287
 
168
288
  expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class }
289
+
290
+ snapshot_repo.set(rep, :last, content)
169
291
  end
170
292
 
171
293
  it 'raises' do
@@ -177,6 +299,10 @@ describe Nanoc::Int::Executor do
177
299
  context 'binary rep, text-to-something filter' do
178
300
  let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.md')) }
179
301
 
302
+ before do
303
+ snapshot_repo.set(rep, :last, content)
304
+ end
305
+
180
306
  it 'raises' do
181
307
  expect { executor.filter(:erb) }
182
308
  .to raise_error(Nanoc::Int::Errors::CannotUseTextualFilter)
@@ -200,6 +326,8 @@ describe Nanoc::Int::Executor do
200
326
  def run(_filename, _params = {}); end
201
327
  end
202
328
 
329
+ snapshot_repo.set(rep, :last, content)
330
+
203
331
  expect(Nanoc::Filter).to receive(:named).with(:whatever) { filter_class }
204
332
  end
205
333
 
@@ -210,6 +338,10 @@ describe Nanoc::Int::Executor do
210
338
  end
211
339
 
212
340
  context 'content is frozen' do
341
+ before do
342
+ snapshot_repo.set(rep, :last, item.content)
343
+ end
344
+
213
345
  let(:item) do
214
346
  Nanoc::Int::Item.new('foo bar', {}, '/foo.md').tap(&:freeze)
215
347
  end
@@ -271,6 +403,7 @@ describe Nanoc::Int::Executor do
271
403
  items: double(:items),
272
404
  dependency_tracker: dependency_tracker,
273
405
  compilation_context: double(:compilation_context),
406
+ snapshot_repo: snapshot_repo,
274
407
  )
275
408
  end
276
409
 
@@ -283,6 +416,8 @@ describe Nanoc::Int::Executor do
283
416
  before do
284
417
  rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:pre)]
285
418
 
419
+ snapshot_repo.set(rep, :last, content)
420
+
286
421
  allow(compilation_context).to receive(:site) { site }
287
422
  allow(compilation_context).to receive(:assigns_for).with(rep, dependency_tracker) { assigns }
288
423
  allow(compilation_context).to receive(:create_view_context).with(dependency_tracker).and_return(view_context)
@@ -302,27 +437,36 @@ describe Nanoc::Int::Executor do
302
437
  .with(layout, raw_content: false, attributes: true, compiled_content: false, path: false)
303
438
  allow(dependency_tracker).to receive(:exit)
304
439
  subject
305
- expect(rep.snapshot_contents[:last].string).to eq('head Gum Emperor foot')
440
+ expect(snapshot_repo.get(rep, :last).string).to eq('head Gum Emperor foot')
306
441
  end
307
442
  end
308
443
 
309
444
  context 'normal flow' do
310
- it 'updates last content' do
311
- subject
312
- expect(rep.snapshot_contents[:last].string).to eq('head hallo foot')
445
+ it 'updates :last on rep' do
446
+ expect { subject }
447
+ .to change { snapshot_repo.get(rep, :last) }
448
+ .from(some_textual_content('Donkey Power'))
449
+ .to(some_textual_content('head hallo foot'))
450
+ end
451
+
452
+ it 'updates :last in repo' do
453
+ expect { subject }
454
+ .to change { snapshot_repo.get(rep, :last) }
455
+ .from(some_textual_content('Donkey Power'))
456
+ .to(some_textual_content('head hallo foot'))
313
457
  end
314
458
 
315
459
  it 'sets frozen content' do
316
460
  subject
317
- expect(rep.snapshot_contents[:last]).to be_frozen
318
- expect(rep.snapshot_contents[:pre]).to be_frozen
461
+ expect(snapshot_repo.get(rep, :last)).to be_frozen
462
+ expect(snapshot_repo.get(rep, :pre)).to be_frozen
319
463
  end
320
464
 
321
465
  it 'does not create pre snapshot' do
322
466
  # a #layout is followed by a #snapshot(:pre, …)
323
- expect(rep.snapshot_contents[:pre]).to be_nil
467
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
324
468
  subject
325
- expect(rep.snapshot_contents[:pre]).to be_nil
469
+ expect(snapshot_repo.get(rep, :pre)).to be_nil
326
470
  end
327
471
 
328
472
  it 'sends notifications' do
@@ -343,18 +487,36 @@ describe Nanoc::Int::Executor do
343
487
  executor.snapshot(:pre)
344
488
  end
345
489
 
346
- it 'can contain compiled_content reference' do
347
- subject
348
- expect(rep.snapshot_contents[:last].string).to eq('head Donkey Power foot')
490
+ it 'updates :last on rep' do
491
+ expect { subject }
492
+ .to change { snapshot_repo.get(rep, :last) }
493
+ .from(some_textual_content('Donkey Power'))
494
+ .to(some_textual_content('head Donkey Power foot'))
495
+ end
496
+
497
+ it 'updates :last in repo' do
498
+ expect { subject }
499
+ .to change { snapshot_repo.get(rep, :last) }
500
+ .from(some_textual_content('Donkey Power'))
501
+ .to(some_textual_content('head Donkey Power foot'))
349
502
  end
350
503
  end
351
504
 
352
505
  context 'content with layout reference' do
353
506
  let(:layout_content) { 'head <%= @layout.identifier %> foot' }
354
507
 
355
- it 'includes layout in assigns' do
356
- subject
357
- expect(rep.snapshot_contents[:last].string).to eq('head /default.erb foot')
508
+ it 'updates :last on rep' do
509
+ expect { subject }
510
+ .to change { snapshot_repo.get(rep, :last) }
511
+ .from(some_textual_content('Donkey Power'))
512
+ .to(some_textual_content('head /default.erb foot'))
513
+ end
514
+
515
+ it 'updates :last in repo' do
516
+ expect { subject }
517
+ .to change { snapshot_repo.get(rep, :last) }
518
+ .from(some_textual_content('Donkey Power'))
519
+ .to(some_textual_content('head /default.erb foot'))
358
520
  end
359
521
  end
360
522
  end
@@ -405,23 +567,47 @@ describe Nanoc::Int::Executor do
405
567
  end
406
568
 
407
569
  describe '#snapshot' do
570
+ subject { executor.snapshot(:something) }
571
+
572
+ before do
573
+ snapshot_repo.set(rep, :last, content)
574
+
575
+ File.write('donkey.dat', 'binary donkey')
576
+ end
577
+
408
578
  context 'binary content' do
409
579
  let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat')) }
410
580
 
411
- it 'creates snapshots' do
412
- executor.snapshot(:something)
581
+ it 'creates snapshots on rep' do
582
+ expect { subject }
583
+ .to change { snapshot_repo.get(rep, :something) }
584
+ .from(nil)
585
+ .to(some_binary_content('binary donkey'))
586
+ end
413
587
 
414
- expect(rep.snapshot_contents[:something]).not_to be_nil
588
+ it 'creates snapshots in repo' do
589
+ expect { subject }
590
+ .to change { snapshot_repo.get(rep, :something) }
591
+ .from(nil)
592
+ .to(some_binary_content('binary donkey'))
415
593
  end
416
594
  end
417
595
 
418
596
  context 'textual content' do
419
597
  let(:content) { Nanoc::Int::TextualContent.new('Donkey Power') }
420
598
 
421
- it 'creates a snapshot' do
422
- executor.snapshot(:something)
599
+ it 'creates snapshots on rep' do
600
+ expect { subject }
601
+ .to change { snapshot_repo.get(rep, :something) }
602
+ .from(nil)
603
+ .to(some_textual_content('Donkey Power'))
604
+ end
423
605
 
424
- expect(rep.snapshot_contents[:something].string).to eq('Donkey Power')
606
+ it 'creates snapshots in repo' do
607
+ expect { subject }
608
+ .to change { snapshot_repo.get(rep, :something) }
609
+ .from(nil)
610
+ .to(some_textual_content('Donkey Power'))
425
611
  end
426
612
  end
427
613
 
@@ -7,6 +7,7 @@ shared_examples 'a document view' do
7
7
  items: double(:items),
8
8
  dependency_tracker: dependency_tracker,
9
9
  compilation_context: double(:compilation_context),
10
+ snapshot_repo: double(:snapshot_repo),
10
11
  )
11
12
  end
12
13
 
@@ -1,9 +1,18 @@
1
1
  describe Nanoc::ItemRepView do
2
- let(:view_context) { Nanoc::ViewContext.new(reps: reps, items: items, dependency_tracker: dependency_tracker, compilation_context: compilation_context) }
2
+ let(:view_context) do
3
+ Nanoc::ViewContext.new(
4
+ reps: reps,
5
+ items: items,
6
+ dependency_tracker: dependency_tracker,
7
+ compilation_context: compilation_context,
8
+ snapshot_repo: snapshot_repo,
9
+ )
10
+ end
3
11
 
4
12
  let(:reps) { double(:reps) }
5
13
  let(:items) { double(:items) }
6
14
  let(:compilation_context) { double(:compilation_context) }
15
+ let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new }
7
16
 
8
17
  let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) }
9
18
  let(:dependency_store) { Nanoc::Int::DependencyStore.new([]) }
@@ -139,9 +148,6 @@ describe Nanoc::ItemRepView do
139
148
  ir.snapshot_defs = [
140
149
  Nanoc::Int::SnapshotDef.new(:last),
141
150
  ]
142
- ir.snapshot_contents = {
143
- last: Nanoc::Int::TextualContent.new('Hallo'),
144
- }
145
151
  end
146
152
  end
147
153
 
@@ -149,8 +155,15 @@ describe Nanoc::ItemRepView do
149
155
  Nanoc::Int::Item.new('content', {}, '/asdf.md')
150
156
  end
151
157
 
158
+ before do
159
+ snapshot_repo.set(rep, :last, Nanoc::Int::TextualContent.new('Hallo'))
160
+ end
161
+
152
162
  it 'creates a dependency' do
153
- expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item])
163
+ expect { subject }
164
+ .to change { dependency_store.objects_causing_outdatedness_of(base_item) }
165
+ .from([])
166
+ .to([item])
154
167
  end
155
168
 
156
169
  it 'creates a dependency with the right props' do