nanoc 4.5.2 → 4.5.3

Sign up to get free protection for your applications and to get access to all the features.
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