nanoc 4.6.1 → 4.6.2

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 (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