nanoc 4.6.1 → 4.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +1 -1
  3. data/Gemfile.lock +22 -22
  4. data/NEWS.md +12 -0
  5. data/lib/nanoc/base/entities/document.rb +7 -0
  6. data/lib/nanoc/base/entities/identifiable_collection.rb +12 -9
  7. data/lib/nanoc/base/entities/item_rep.rb +24 -28
  8. data/lib/nanoc/base/entities/processing_actions/snapshot.rb +15 -11
  9. data/lib/nanoc/base/entities/rule_memory.rb +15 -5
  10. data/lib/nanoc/base/entities/site.rb +15 -10
  11. data/lib/nanoc/base/entities/snapshot_def.rb +8 -2
  12. data/lib/nanoc/base/repos.rb +3 -0
  13. data/lib/nanoc/base/repos/aggregate_data_source.rb +20 -0
  14. data/lib/nanoc/base/repos/in_mem_data_source.rb +13 -0
  15. data/lib/nanoc/base/repos/prefixed_data_source.rb +19 -0
  16. data/lib/nanoc/base/repos/site_loader.rb +8 -16
  17. data/lib/nanoc/base/repos/snapshot_repo.rb +10 -5
  18. data/lib/nanoc/base/services/action_provider.rb +12 -0
  19. data/lib/nanoc/base/services/compiler/phases/recalculate.rb +5 -2
  20. data/lib/nanoc/base/services/compiler/phases/write.rb +1 -3
  21. data/lib/nanoc/base/services/compiler/stages/preprocess.rb +6 -3
  22. data/lib/nanoc/base/services/executor.rb +2 -4
  23. data/lib/nanoc/base/services/filter.rb +7 -12
  24. data/lib/nanoc/base/services/item_rep_router.rb +40 -16
  25. data/lib/nanoc/base/services/item_rep_writer.rb +19 -3
  26. data/lib/nanoc/base/services/pruner.rb +1 -1
  27. data/lib/nanoc/base/views/item_rep_view.rb +12 -3
  28. data/lib/nanoc/base/views/mutable_identifiable_collection_view.rb +1 -1
  29. data/lib/nanoc/base/views/mutable_item_collection_view.rb +1 -1
  30. data/lib/nanoc/base/views/mutable_layout_collection_view.rb +1 -1
  31. data/lib/nanoc/checking/checks/html.rb +1 -1
  32. data/lib/nanoc/checking/checks/stale.rb +2 -1
  33. data/lib/nanoc/checking/checks/w3c_validator.rb +1 -0
  34. data/lib/nanoc/cli/commands/compile.rb +3 -2
  35. data/lib/nanoc/cli/commands/show-data.rb +4 -2
  36. data/lib/nanoc/data_sources/filesystem.rb +1 -1
  37. data/lib/nanoc/helpers/filtering.rb +1 -2
  38. data/lib/nanoc/helpers/rendering.rb +1 -2
  39. data/lib/nanoc/helpers/xml_sitemap.rb +2 -2
  40. data/lib/nanoc/rule_dsl/action_provider.rb +7 -0
  41. data/lib/nanoc/rule_dsl/rule_context.rb +4 -1
  42. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +33 -13
  43. data/lib/nanoc/spec.rb +5 -6
  44. data/lib/nanoc/version.rb +1 -1
  45. data/spec/nanoc/base/checksummer_spec.rb +19 -9
  46. data/spec/nanoc/base/compiler_spec.rb +4 -8
  47. data/spec/nanoc/base/entities/document_spec.rb +20 -0
  48. data/spec/nanoc/base/entities/identifiable_collection_spec.rb +12 -0
  49. data/spec/nanoc/base/entities/item_rep_spec.rb +1 -1
  50. data/spec/nanoc/base/entities/processing_actions/snapshot_spec.rb +19 -13
  51. data/spec/nanoc/base/entities/rule_memory_spec.rb +39 -3
  52. data/spec/nanoc/base/entities/site_spec.rb +15 -10
  53. data/spec/nanoc/base/filter_spec.rb +28 -1
  54. data/spec/nanoc/base/item_rep_writer_spec.rb +4 -2
  55. data/spec/nanoc/base/repos/outdatedness_store_spec.rb +1 -2
  56. data/spec/nanoc/base/repos/snapshot_repo_spec.rb +4 -4
  57. data/spec/nanoc/base/repos/store_spec.rb +5 -1
  58. data/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb +9 -10
  59. data/spec/nanoc/base/services/executor_spec.rb +2 -2
  60. data/spec/nanoc/base/services/item_rep_router_spec.rb +83 -39
  61. data/spec/nanoc/base/services/outdatedness_checker_spec.rb +1 -2
  62. data/spec/nanoc/base/services/outdatedness_rules_spec.rb +2 -3
  63. data/spec/nanoc/base/services/pruner_spec.rb +2 -2
  64. data/spec/nanoc/base/views/identifiable_collection_view_spec.rb +46 -28
  65. data/spec/nanoc/base/views/item_rep_view_spec.rb +72 -15
  66. data/spec/nanoc/base/views/item_view_spec.rb +20 -14
  67. data/spec/nanoc/base/views/mutable_identifiable_collection_view_spec.rb +10 -4
  68. data/spec/nanoc/base/views/mutable_item_collection_view_spec.rb +10 -5
  69. data/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb +10 -5
  70. data/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb +1 -1
  71. data/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb +1 -1
  72. data/spec/nanoc/cli/commands/show_data_spec.rb +9 -7
  73. data/spec/nanoc/cli/commands/show_rules_spec.rb +16 -10
  74. data/spec/nanoc/regressions/gh_1037a_spec.rb +29 -0
  75. data/spec/nanoc/regressions/gh_1037b_spec.rb +18 -0
  76. data/spec/nanoc/regressions/gh_1082a_spec.rb +18 -0
  77. data/spec/nanoc/regressions/gh_1082b_spec.rb +20 -0
  78. data/spec/nanoc/regressions/gh_1082c_spec.rb +19 -0
  79. data/spec/nanoc/regressions/gh_1082d_spec.rb +17 -0
  80. data/spec/nanoc/regressions/gh_1093_spec.rb +49 -0
  81. data/spec/nanoc/regressions/gh_1097_spec.rb +21 -0
  82. data/spec/nanoc/regressions/gh_1100_spec.rb +20 -0
  83. data/spec/nanoc/regressions/gh_1102_spec.rb +26 -0
  84. data/spec/nanoc/regressions/gh_776_spec.rb +1 -5
  85. data/spec/nanoc/rule_dsl/recording_executor_spec.rb +14 -14
  86. data/spec/nanoc/rule_dsl/rule_context_spec.rb +22 -13
  87. data/spec/nanoc/rule_dsl/rule_memory_calculator_spec.rb +38 -54
  88. data/spec/spec_helper.rb +1 -1
  89. data/test/base/test_compiler.rb +3 -4
  90. data/test/base/test_item_array.rb +4 -15
  91. data/test/checking/checks/test_html.rb +4 -3
  92. data/test/cli/commands/test_compile.rb +2 -2
  93. data/test/filters/test_relativize_paths.rb +28 -28
  94. data/test/fixtures/vcr_cassettes/html_run_error.yml +25 -76
  95. data/test/helpers/test_xml_sitemap.rb +22 -19
  96. metadata +16 -2
@@ -64,8 +64,8 @@ describe Nanoc::Int::RuleMemory do
64
64
 
65
65
  expect(rule_memory.size).to eql(1)
66
66
  expect(rule_memory[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
67
- expect(rule_memory[0].snapshot_name).to eql(:before_layout)
68
- expect(rule_memory[0].path).to eql('/foo.md')
67
+ expect(rule_memory[0].snapshot_names).to eql([:before_layout])
68
+ expect(rule_memory[0].paths).to eql(['/foo.md'])
69
69
  end
70
70
  end
71
71
 
@@ -122,10 +122,46 @@ describe Nanoc::Int::RuleMemory do
122
122
  expect(subject).to eql(
123
123
  [
124
124
  [:filter, :erb, 'PeWUm2PtXYtqeHJdTqnY7kkwAow='],
125
- [:snapshot, :bar, true, '/foo.md'],
125
+ [:snapshot, [:bar], true, ['/foo.md']],
126
126
  [:layout, '/default.erb', '97LAe1pYTLKczxBsu+x4MmvqdkU='],
127
127
  ],
128
128
  )
129
129
  end
130
130
  end
131
+
132
+ describe '#compact_snapshots' do
133
+ subject { rule_memory.compact_snapshots }
134
+
135
+ before do
136
+ rule_memory.add_snapshot(:a1, nil)
137
+ rule_memory.add_snapshot(:a2, '/a2.md')
138
+ rule_memory.add_snapshot(:a3, nil)
139
+ rule_memory.add_filter(:erb, awesomeness: 'high')
140
+ rule_memory.add_snapshot(:b1, '/b1.md')
141
+ rule_memory.add_snapshot(:b2, nil)
142
+ rule_memory.add_snapshot(:b3, '/b3.md')
143
+ rule_memory.add_filter(:erb, awesomeness: 'high')
144
+ rule_memory.add_snapshot(:c, nil)
145
+ end
146
+
147
+ example do
148
+ expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
149
+ expect(subject[0].snapshot_names).to eql([:a1, :a2, :a3])
150
+ expect(subject[0].paths).to eql(['/a2.md'])
151
+
152
+ expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Filter)
153
+
154
+ expect(subject[2]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
155
+ expect(subject[2].snapshot_names).to eql([:b1, :b2, :b3])
156
+ expect(subject[2].paths).to eql(['/b1.md', '/b3.md'])
157
+
158
+ expect(subject[3]).to be_a(Nanoc::Int::ProcessingActions::Filter)
159
+
160
+ expect(subject[4]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
161
+ expect(subject[4].snapshot_names).to eql([:c])
162
+ expect(subject[4].paths).to be_empty
163
+
164
+ expect(subject.size).to eql(5)
165
+ end
166
+ end
131
167
  end
@@ -4,8 +4,7 @@ describe Nanoc::Int::Site do
4
4
  described_class.new(
5
5
  config: config,
6
6
  code_snippets: code_snippets,
7
- items: items,
8
- layouts: layouts,
7
+ data_source: Nanoc::Int::InMemDataSource.new(items, layouts),
9
8
  )
10
9
  end
11
10
 
@@ -21,17 +20,23 @@ describe Nanoc::Int::Site do
21
20
  end
22
21
 
23
22
  let(:items) do
24
- Nanoc::Int::IdentifiableCollection.new(config).tap do |coll|
25
- coll << Nanoc::Int::Item.new('foo', {}, '/foo.md')
26
- coll << Nanoc::Int::Item.new('bar', {}, '/bar.md')
27
- end
23
+ Nanoc::Int::IdentifiableCollection.new(
24
+ config,
25
+ [
26
+ Nanoc::Int::Item.new('foo', {}, '/foo.md'),
27
+ Nanoc::Int::Item.new('bar', {}, '/bar.md'),
28
+ ],
29
+ )
28
30
  end
29
31
 
30
32
  let(:layouts) do
31
- Nanoc::Int::IdentifiableCollection.new(config).tap do |coll|
32
- coll << Nanoc::Int::Layout.new('foo', {}, '/foo.md')
33
- coll << Nanoc::Int::Layout.new('bar', {}, '/bar.md')
34
- end
33
+ Nanoc::Int::IdentifiableCollection.new(
34
+ config,
35
+ [
36
+ Nanoc::Int::Layout.new('foo', {}, '/foo.md'),
37
+ Nanoc::Int::Layout.new('bar', {}, '/bar.md'),
38
+ ],
39
+ )
35
40
  end
36
41
 
37
42
  before do
@@ -70,7 +70,7 @@ describe Nanoc::Filter do
70
70
  before do
71
71
  reps << rep
72
72
 
73
- expect(dependency_tracker).to receive(:bounce).with(item, compiled_content: true)
73
+ expect(dependency_tracker).to receive(:bounce).with(item, compiled_content: true).at_least(:once)
74
74
  end
75
75
 
76
76
  context 'rep is compiled' do
@@ -96,5 +96,32 @@ describe Nanoc::Filter do
96
96
  expect(fiber.resume).not_to be_a(Nanoc::Int::Errors::UnmetDependency)
97
97
  end
98
98
  end
99
+
100
+ context 'multiple reps exist' do
101
+ let(:other_rep) { Nanoc::Int::ItemRep.new(item, :default) }
102
+
103
+ before do
104
+ reps << other_rep
105
+ rep.compiled = false
106
+ other_rep.compiled = false
107
+ end
108
+
109
+ it 'yields an unmet dependency error twice' do
110
+ fiber = Fiber.new { subject }
111
+
112
+ # resume 1
113
+ res = fiber.resume
114
+ expect(res).to be_a(Nanoc::Int::Errors::UnmetDependency)
115
+ expect(res.rep).to eql(rep)
116
+
117
+ # resume 2
118
+ res = fiber.resume
119
+ expect(res).to be_a(Nanoc::Int::Errors::UnmetDependency)
120
+ expect(res.rep).to eql(other_rep)
121
+
122
+ # resume 3
123
+ expect(fiber.resume).not_to be_a(Nanoc::Int::Errors::UnmetDependency)
124
+ end
125
+ end
99
126
  end
100
127
  end
@@ -20,12 +20,14 @@ describe Nanoc::Int::ItemRepWriter do
20
20
  let(:snapshot_name) { :donkey }
21
21
 
22
22
  let(:raw_paths) do
23
- { snapshot_name => raw_path }
23
+ { snapshot_name => [raw_path] }
24
24
  end
25
25
 
26
26
  let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new }
27
27
 
28
- subject { described_class.new.write(item_rep, snapshot_repo, snapshot_name) }
28
+ let(:written_paths) { [] }
29
+
30
+ subject { described_class.new.write(item_rep, snapshot_repo, snapshot_name, written_paths) }
29
31
 
30
32
  before do
31
33
  expect(File.directory?('output')).to be_falsy
@@ -11,8 +11,7 @@ describe Nanoc::Int::OutdatednessStore do
11
11
  Nanoc::Int::Site.new(
12
12
  config: config,
13
13
  code_snippets: code_snippets,
14
- items: items,
15
- layouts: layouts,
14
+ data_source: Nanoc::Int::InMemDataSource.new(items, layouts),
16
15
  )
17
16
  end
18
17
 
@@ -103,7 +103,7 @@ describe Nanoc::Int::SnapshotRepo do
103
103
 
104
104
  context 'snapshot def exists' do
105
105
  before do
106
- rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
106
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)]
107
107
  repo.set_all(rep, snapshot_name => content)
108
108
  end
109
109
 
@@ -128,7 +128,7 @@ describe Nanoc::Int::SnapshotRepo do
128
128
 
129
129
  context 'snapshot def exists, but not content' do
130
130
  before do
131
- rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
131
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)]
132
132
  repo.set_all(rep, {})
133
133
  end
134
134
 
@@ -148,7 +148,7 @@ describe Nanoc::Int::SnapshotRepo do
148
148
  context 'snapshot exists' do
149
149
  context 'snapshot is not final' do
150
150
  before do
151
- rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
151
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)]
152
152
  end
153
153
 
154
154
  context 'snapshot content does not exist' do
@@ -209,7 +209,7 @@ describe Nanoc::Int::SnapshotRepo do
209
209
 
210
210
  context 'snapshot is final' do
211
211
  before do
212
- rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
212
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name, binary: false)]
213
213
  end
214
214
 
215
215
  context 'snapshot content does not exist' do
@@ -4,7 +4,11 @@ describe Nanoc::Int::Store do
4
4
  subject { described_class.tmp_path_for(site: site, store_name: 'giraffes') }
5
5
 
6
6
  let(:site) do
7
- Nanoc::Int::Site.new(config: config, code_snippets: code_snippets, items: items, layouts: layouts)
7
+ Nanoc::Int::Site.new(
8
+ config: config,
9
+ code_snippets: code_snippets,
10
+ data_source: Nanoc::Int::InMemDataSource.new(items, layouts),
11
+ )
8
12
  end
9
13
 
10
14
  let(:code_snippets) { [] }
@@ -37,8 +37,7 @@ describe Nanoc::Int::Compiler::Stages::CompileReps do
37
37
  Nanoc::Int::Site.new(
38
38
  config: config,
39
39
  code_snippets: code_snippets,
40
- items: items,
41
- layouts: layouts,
40
+ data_source: Nanoc::Int::InMemDataSource.new(items, layouts),
42
41
  )
43
42
  end
44
43
 
@@ -47,17 +46,17 @@ describe Nanoc::Int::Compiler::Stages::CompileReps do
47
46
  let(:code_snippets) { [] }
48
47
 
49
48
  let(:items) do
50
- Nanoc::Int::IdentifiableCollection.new(config).tap do |col|
51
- col << item
52
- col << other_item
53
- end
49
+ Nanoc::Int::IdentifiableCollection.new(
50
+ config,
51
+ [item, other_item],
52
+ )
54
53
  end
55
54
 
56
55
  let(:memory) do
57
56
  actions =
58
57
  [
59
58
  Nanoc::Int::ProcessingActions::Filter.new(:erb, {}),
60
- Nanoc::Int::ProcessingActions::Snapshot.new(:last, nil),
59
+ Nanoc::Int::ProcessingActions::Snapshot.new([:last], []),
61
60
  ]
62
61
 
63
62
  Nanoc::Int::RuleMemory.new(nil, actions: actions)
@@ -68,7 +67,7 @@ describe Nanoc::Int::Compiler::Stages::CompileReps do
68
67
  reps << other_rep
69
68
 
70
69
  reps.each do |rep|
71
- rep.snapshot_defs << Nanoc::Int::SnapshotDef.new(:last)
70
+ rep.snapshot_defs << Nanoc::Int::SnapshotDef.new(:last, binary: false)
72
71
  end
73
72
 
74
73
  allow(action_provider).to receive(:memory_for).with(rep).and_return(memory)
@@ -84,11 +83,11 @@ describe Nanoc::Int::Compiler::Stages::CompileReps do
84
83
  end
85
84
 
86
85
  let(:snapshot_defs_for_rep) do
87
- [Nanoc::Int::SnapshotDef.new(:last)]
86
+ [Nanoc::Int::SnapshotDef.new(:last, binary: false)]
88
87
  end
89
88
 
90
89
  let(:snapshot_defs_for_other_rep) do
91
- [Nanoc::Int::SnapshotDef.new(:last)]
90
+ [Nanoc::Int::SnapshotDef.new(:last, binary: false)]
92
91
  end
93
92
 
94
93
  context 'rep not in outdatedness store' do
@@ -414,7 +414,7 @@ describe Nanoc::Int::Executor do
414
414
  end
415
415
 
416
416
  before do
417
- rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:pre)]
417
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(:pre, binary: false)]
418
418
 
419
419
  snapshot_repo.set(rep, :last, content)
420
420
 
@@ -616,7 +616,7 @@ describe Nanoc::Int::Executor do
616
616
 
617
617
  context 'raw path' do
618
618
  before do
619
- rep.raw_paths = { something: 'output/donkey.md' }
619
+ rep.raw_paths = { something: ['output/donkey.md'] }
620
620
  end
621
621
 
622
622
  it 'does not write' do
@@ -19,46 +19,68 @@ describe(Nanoc::Int::ItemRepRouter) do
19
19
  end
20
20
 
21
21
  let(:paths_0) do
22
- { last: '/foo/index.html' }
22
+ [
23
+ [[:last], ['/foo/index.html']],
24
+ ]
23
25
  end
24
26
 
25
27
  let(:paths_1) do
26
- { last: '/bar.html' }
28
+ [
29
+ [[:last], ['/bar.html']],
30
+ ]
27
31
  end
28
32
 
29
33
  example do
30
- expect(action_provider).to receive(:paths_for).with(reps[0]).and_return(paths_0)
31
- expect(action_provider).to receive(:paths_for).with(reps[1]).and_return(paths_1)
34
+ allow(action_provider).to receive(:paths_for).with(reps[0]).and_return(paths_0)
35
+ allow(action_provider).to receive(:paths_for).with(reps[1]).and_return(paths_1)
36
+
37
+ subject
38
+
39
+ expect(reps[0].raw_paths).to eql(last: ['output/foo/index.html'])
40
+ expect(reps[0].paths).to eql(last: ['/foo/'])
41
+
42
+ expect(reps[1].raw_paths).to eql(last: ['output/bar.html'])
43
+ expect(reps[1].paths).to eql(last: ['/bar.html'])
44
+ end
45
+
46
+ it 'picks the paths last returned' do
47
+ expect(action_provider).to receive(:paths_for).with(reps[0]).and_return([[[:last], []]]).ordered
48
+ expect(action_provider).to receive(:paths_for).with(reps[0]).and_return(paths_0).ordered
49
+ expect(action_provider).to receive(:paths_for).with(reps[1]).and_return([[[:last], []]]).ordered
50
+ expect(action_provider).to receive(:paths_for).with(reps[1]).and_return(paths_1).ordered
32
51
 
33
52
  subject
34
53
 
35
- expect(reps[0].raw_paths).to eql(last: 'output/foo/index.html')
36
- expect(reps[0].paths).to eql(last: '/foo/')
54
+ expect(reps[0].raw_paths).to eql(last: ['output/foo/index.html'])
55
+ expect(reps[0].paths).to eql(last: ['/foo/'])
37
56
 
38
- expect(reps[1].raw_paths).to eql(last: 'output/bar.html')
39
- expect(reps[1].paths).to eql(last: '/bar.html')
57
+ expect(reps[1].raw_paths).to eql(last: ['output/bar.html'])
58
+ expect(reps[1].paths).to eql(last: ['/bar.html'])
40
59
  end
41
60
  end
42
61
 
43
62
  describe '#route_rep' do
44
- subject { item_rep_router.route_rep(rep, path, snapshot_name, paths_to_reps) }
63
+ subject { item_rep_router.route_rep(rep, paths, snapshot_names, paths_to_reps) }
45
64
 
46
- let(:path) { basic_path }
47
- let(:snapshot_name) { :foo }
65
+ let(:snapshot_names) { [:foo] }
48
66
  let(:rep) { Nanoc::Int::ItemRep.new(item, :default) }
49
67
  let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') }
50
68
  let(:paths_to_reps) { {} }
51
69
 
52
70
  context 'basic path is nil' do
53
- let(:basic_path) { nil }
54
- it { is_expected.to be_nil }
71
+ let(:paths) { [] }
72
+
73
+ it 'assigns no paths' do
74
+ subject
75
+ expect(rep.raw_paths[:foo]).to be_empty
76
+ end
55
77
  end
56
78
 
57
79
  context 'basic path is not nil' do
58
- let(:basic_path) { '/foo/index.html' }
80
+ let(:paths) { ['/foo/index.html'] }
59
81
 
60
82
  context 'other snapshot with this path already exists' do
61
- let(:paths_to_reps) { { '/foo/index.html' => double(:other_rep) } }
83
+ let(:paths_to_reps) { { '/foo/index.html' => Nanoc::Int::ItemRep.new(item, :other) } }
62
84
 
63
85
  it 'errors' do
64
86
  expect { subject }.to raise_error(Nanoc::Int::ItemRepRouter::IdenticalRoutesError)
@@ -66,42 +88,64 @@ describe(Nanoc::Int::ItemRepRouter) do
66
88
  end
67
89
 
68
90
  context 'path is unique' do
69
- it 'sets the raw path' do
70
- subject
71
- expect(rep.raw_paths).to eql(foo: 'output/foo/index.html')
72
- end
91
+ context 'single path' do
92
+ it 'sets the raw path' do
93
+ subject
94
+ expect(rep.raw_paths).to eql(foo: ['output/foo/index.html'])
95
+ end
73
96
 
74
- it 'sets the path' do
75
- subject
76
- expect(rep.paths).to eql(foo: '/foo/')
77
- end
97
+ it 'sets the path' do
98
+ subject
99
+ expect(rep.paths).to eql(foo: ['/foo/'])
100
+ end
78
101
 
79
- it 'adds to paths_to_reps' do
80
- subject
81
- expect(paths_to_reps).to have_key('/foo/index.html')
82
- end
102
+ it 'adds to paths_to_reps' do
103
+ subject
104
+ expect(paths_to_reps).to have_key('/foo/index.html')
105
+ end
83
106
 
84
- context 'path does not start with a slash' do
85
- let(:basic_path) { 'foo/index.html' }
107
+ context 'path does not start with a slash' do
108
+ let(:paths) { ['foo/index.html'] }
86
109
 
87
- it 'errors' do
88
- expect { subject }.to raise_error(Nanoc::Int::ItemRepRouter::RouteWithoutSlashError)
110
+ it 'errors' do
111
+ expect { subject }.to raise_error(Nanoc::Int::ItemRepRouter::RouteWithoutSlashError)
112
+ end
113
+ end
114
+
115
+ context 'path is not UTF-8' do
116
+ let(:paths) { ['/foo/index.html'.encode('ISO-8859-1')] }
117
+
118
+ it 'sets the path as UTF-8' do
119
+ subject
120
+ expect(rep.paths).to eql(foo: ['/foo/'])
121
+ expect(rep.paths[:foo].first.encoding.to_s).to eql('UTF-8')
122
+ end
123
+
124
+ it 'sets the raw path as UTF-8' do
125
+ subject
126
+ expect(rep.raw_paths).to eql(foo: ['output/foo/index.html'])
127
+ expect(rep.raw_paths[:foo].first.encoding.to_s).to eql('UTF-8')
128
+ end
89
129
  end
90
130
  end
91
131
 
92
- context 'path is not UTF-8' do
93
- let(:basic_path) { '/foo/index.html'.encode('ISO-8859-1') }
132
+ context 'multiple paths' do
133
+ let(:paths) { ['/foo/index.html', '/bar/index.html'] }
134
+
135
+ it 'sets the raw paths' do
136
+ subject
137
+ expect(rep.raw_paths).to eql(foo: ['output/foo/index.html', 'output/bar/index.html'])
138
+ end
94
139
 
95
- it 'sets the path as UTF-8' do
140
+ it 'sets the paths' do
96
141
  subject
97
- expect(rep.paths).to eql(foo: '/foo/')
98
- expect(rep.paths[:foo].encoding.to_s).to eql('UTF-8')
142
+ expect(rep.paths).to eql(foo: ['/foo/', '/bar/'])
99
143
  end
100
144
 
101
- it 'sets the raw path as UTF-8' do
145
+ it 'adds to paths_to_reps' do
102
146
  subject
103
- expect(rep.raw_paths).to eql(foo: 'output/foo/index.html')
104
- expect(rep.raw_paths[:foo].encoding.to_s).to eql('UTF-8')
147
+ expect(paths_to_reps).to have_key('/foo/index.html')
148
+ expect(paths_to_reps).to have_key('/bar/index.html')
105
149
  end
106
150
  end
107
151
  end