nanoc 4.7.13 → 4.7.14
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/NEWS.md +6 -0
- data/bin/nanoc +7 -0
- data/lib/nanoc/base/entities/code_snippet.rb +1 -1
- data/lib/nanoc/base/entities/configuration.rb +1 -1
- data/lib/nanoc/base/entities/directed_graph.rb +18 -119
- data/lib/nanoc/base/entities/item.rb +1 -1
- data/lib/nanoc/base/entities/item_collection.rb +1 -1
- data/lib/nanoc/base/entities/item_rep.rb +1 -1
- data/lib/nanoc/base/entities/layout.rb +1 -1
- data/lib/nanoc/base/entities/layout_collection.rb +1 -1
- data/lib/nanoc/base/errors.rb +4 -3
- data/lib/nanoc/base/services/item_rep_selector.rb +40 -61
- data/lib/nanoc/data_sources/filesystem.rb +1 -1
- data/lib/nanoc/rule_dsl/rules_collection.rb +1 -1
- data/lib/nanoc/version.rb +1 -1
- data/spec/nanoc/base/directed_graph_spec.rb +123 -296
- data/spec/nanoc/base/entities/identifiable_collection_spec.rb +2 -2
- data/spec/nanoc/base/entities/item_spec.rb +1 -1
- data/spec/nanoc/base/entities/layout_spec.rb +1 -1
- data/spec/nanoc/base/errors/dependency_cycle_spec.rb +14 -13
- data/spec/nanoc/base/services/item_rep_selector_spec.rb +41 -0
- data/test/base/test_directed_graph.rb +0 -256
- metadata +2 -2
@@ -183,7 +183,7 @@ module Nanoc::DataSources
|
|
183
183
|
|
184
184
|
def attributes_checksum_data_for(proto_doc, content_filename, meta_filename)
|
185
185
|
Digest::SHA1.digest(
|
186
|
-
|
186
|
+
Marshal.dump(
|
187
187
|
attributes: proto_doc.attributes_checksum_data,
|
188
188
|
extra_attributes: extra_attributes_for(content_filename, meta_filename),
|
189
189
|
),
|
data/lib/nanoc/version.rb
CHANGED
@@ -1,401 +1,228 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
describe Nanoc::Int::DirectedGraph do
|
4
|
-
subject(:graph) { described_class.new([1
|
4
|
+
subject(:graph) { described_class.new(%w[1 2 3]) }
|
5
5
|
|
6
|
-
describe '#
|
7
|
-
subject { graph.
|
6
|
+
describe '#edges' do
|
7
|
+
subject { graph.edges }
|
8
8
|
|
9
9
|
context 'empty graph' do
|
10
|
-
it { is_expected.to
|
10
|
+
it { is_expected.to be_empty }
|
11
11
|
end
|
12
12
|
|
13
|
-
context '
|
13
|
+
context 'graph with vertices, but no edges' do
|
14
14
|
before do
|
15
|
-
graph.
|
15
|
+
graph.add_vertex('1')
|
16
|
+
graph.add_vertex('2')
|
16
17
|
end
|
17
18
|
|
18
|
-
it { is_expected.to
|
19
|
+
it { is_expected.to be_empty }
|
19
20
|
end
|
20
21
|
|
21
|
-
context '
|
22
|
+
context 'graph with edges from previously added vertices' do
|
22
23
|
before do
|
23
|
-
graph.
|
24
|
-
graph.
|
24
|
+
graph.add_vertex('1')
|
25
|
+
graph.add_vertex('2')
|
26
|
+
graph.add_vertex('3')
|
27
|
+
|
28
|
+
graph.add_edge('1', '2')
|
29
|
+
graph.add_edge('1', '3')
|
25
30
|
end
|
26
31
|
|
27
|
-
it { is_expected.to
|
32
|
+
it { is_expected.to match_array([[0, 1, nil], [0, 2, nil]]) }
|
28
33
|
end
|
29
34
|
|
30
|
-
context '
|
35
|
+
context 'graph with edges from new vertices' do
|
31
36
|
before do
|
32
|
-
graph.add_edge(1, 2
|
37
|
+
graph.add_edge('1', '2')
|
38
|
+
graph.add_edge('1', '3')
|
33
39
|
end
|
34
40
|
|
35
|
-
it { is_expected.to
|
41
|
+
it { is_expected.to match_array([[0, 1, nil], [0, 2, nil]]) }
|
36
42
|
end
|
37
43
|
|
38
|
-
context '
|
44
|
+
context 'graph with edge props' do
|
39
45
|
before do
|
40
|
-
graph.add_edge(1, 2, props: '
|
41
|
-
graph.add_edge(
|
46
|
+
graph.add_edge('1', '2', props: { name: 'Mr. C' })
|
47
|
+
graph.add_edge('1', '3', props: { name: 'Cooper' })
|
42
48
|
end
|
43
49
|
|
44
|
-
it { is_expected.to
|
50
|
+
it { is_expected.to match_array([[0, 1, { name: 'Mr. C' }], [0, 2, { name: 'Cooper' }]]) }
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
48
|
-
describe '#
|
49
|
-
subject { graph.
|
54
|
+
describe '#props_for' do
|
55
|
+
subject { graph.props_for('1', '2') }
|
50
56
|
|
51
|
-
context 'no
|
57
|
+
context 'no edge' do
|
52
58
|
it { is_expected.to be_nil }
|
53
59
|
end
|
54
60
|
|
55
|
-
context '
|
56
|
-
before
|
57
|
-
|
58
|
-
graph.add_edge(2, 1)
|
59
|
-
end
|
60
|
-
|
61
|
-
it { is_expected.to eq([1, 2]) }
|
61
|
+
context 'edge, but no props' do
|
62
|
+
before { graph.add_edge('1', '2') }
|
63
|
+
it { is_expected.to be_nil }
|
62
64
|
end
|
63
65
|
|
64
|
-
context '
|
65
|
-
before
|
66
|
-
|
67
|
-
graph.add_edge(2, 3)
|
68
|
-
graph.add_edge(3, 2)
|
69
|
-
end
|
66
|
+
context 'edge with props' do
|
67
|
+
before { graph.add_edge('1', '2', props: { name: 'Mr. C' }) }
|
68
|
+
it { is_expected.to eq(name: 'Mr. C') }
|
70
69
|
|
71
|
-
|
70
|
+
context 'deleted edge (#delete_edges_to)' do
|
71
|
+
before { graph.delete_edges_to('2') }
|
72
|
+
it { is_expected.to be_nil }
|
73
|
+
end
|
72
74
|
end
|
75
|
+
end
|
73
76
|
|
74
|
-
|
75
|
-
|
76
|
-
graph.add_edge(1, 2)
|
77
|
-
graph.add_edge(2, 20)
|
78
|
-
graph.add_edge(20, 21)
|
79
|
-
graph.add_edge(2, 3)
|
80
|
-
graph.add_edge(3, 1)
|
81
|
-
end
|
77
|
+
describe '#direct_predecessors_of' do
|
78
|
+
subject { graph.direct_predecessors_of('2') }
|
82
79
|
|
83
|
-
|
80
|
+
context 'no edges' do
|
81
|
+
it { is_expected.to be_empty }
|
84
82
|
end
|
85
83
|
|
86
|
-
context '
|
87
|
-
before
|
88
|
-
|
89
|
-
graph.add_edge(2, 3)
|
90
|
-
graph.add_edge(3, 4)
|
91
|
-
graph.add_edge(4, 5)
|
92
|
-
graph.add_edge(5, 1)
|
93
|
-
end
|
94
|
-
|
95
|
-
it { is_expected.to eq([1, 2, 3, 4, 5]) }
|
84
|
+
context 'one edge to' do
|
85
|
+
before { graph.add_edge('1', '2') }
|
86
|
+
it { is_expected.to eq(['1']) }
|
96
87
|
end
|
97
88
|
|
98
|
-
context '
|
89
|
+
context 'two edges to' do
|
99
90
|
before do
|
100
|
-
graph.add_edge(1, 2)
|
101
|
-
graph.add_edge(
|
102
|
-
graph.add_edge(3, 4)
|
103
|
-
graph.add_edge(4, 5)
|
104
|
-
graph.add_edge(5, 2)
|
91
|
+
graph.add_edge('1', '2')
|
92
|
+
graph.add_edge('3', '2')
|
105
93
|
end
|
106
94
|
|
107
|
-
it { is_expected.to
|
95
|
+
it { is_expected.to match_array(%w[1 3]) }
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'edge from' do
|
99
|
+
before { graph.add_edge('2', '3') }
|
100
|
+
it { is_expected.to be_empty }
|
108
101
|
end
|
109
102
|
end
|
110
103
|
|
111
|
-
describe '#
|
112
|
-
subject { graph.
|
104
|
+
describe '#direct_successors_of' do
|
105
|
+
subject { graph.direct_successors_of('2') }
|
113
106
|
|
114
|
-
context 'no
|
115
|
-
|
116
|
-
expect(subject).to contain_exactly(
|
117
|
-
[1],
|
118
|
-
[2],
|
119
|
-
[3],
|
120
|
-
)
|
121
|
-
end
|
107
|
+
context 'no edges' do
|
108
|
+
it { is_expected.to be_empty }
|
122
109
|
end
|
123
110
|
|
124
|
-
context 'one
|
125
|
-
before
|
126
|
-
|
127
|
-
|
128
|
-
end
|
111
|
+
context 'one edge to' do
|
112
|
+
before { graph.add_edge('1', '2') }
|
113
|
+
it { is_expected.to be_empty }
|
114
|
+
end
|
129
115
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
[1, 2],
|
134
|
-
[1, 2, 1],
|
135
|
-
[2],
|
136
|
-
[2, 1],
|
137
|
-
[2, 1, 2],
|
138
|
-
[3],
|
139
|
-
)
|
140
|
-
end
|
116
|
+
context 'one edge from' do
|
117
|
+
before { graph.add_edge('2', '3') }
|
118
|
+
it { is_expected.to eq(['3']) }
|
141
119
|
end
|
142
120
|
|
143
|
-
context '
|
121
|
+
context 'two edges from' do
|
144
122
|
before do
|
145
|
-
graph.add_edge(
|
146
|
-
graph.add_edge(2, 3)
|
147
|
-
graph.add_edge(3, 2)
|
123
|
+
graph.add_edge('2', '1')
|
124
|
+
graph.add_edge('2', '3')
|
148
125
|
end
|
149
126
|
|
150
|
-
|
151
|
-
expect(subject).to contain_exactly(
|
152
|
-
[1],
|
153
|
-
[1, 2],
|
154
|
-
[1, 2, 3],
|
155
|
-
[1, 2, 3, 2],
|
156
|
-
[2],
|
157
|
-
[2, 3],
|
158
|
-
[2, 3, 2],
|
159
|
-
[3],
|
160
|
-
[3, 2],
|
161
|
-
[3, 2, 3],
|
162
|
-
)
|
163
|
-
end
|
127
|
+
it { is_expected.to match_array(%w[1 3]) }
|
164
128
|
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#predecessors_of' do
|
132
|
+
subject { graph.predecessors_of('2') }
|
165
133
|
|
166
|
-
context '
|
134
|
+
context 'no predecessors' do
|
167
135
|
before do
|
168
|
-
graph.add_edge(
|
169
|
-
graph.add_edge(2, 20)
|
170
|
-
graph.add_edge(20, 21)
|
171
|
-
graph.add_edge(2, 3)
|
172
|
-
graph.add_edge(3, 1)
|
136
|
+
graph.add_edge('2', '3')
|
173
137
|
end
|
174
138
|
|
175
|
-
|
176
|
-
expect(subject).to contain_exactly(
|
177
|
-
[1],
|
178
|
-
[1, 2],
|
179
|
-
[1, 2, 20],
|
180
|
-
[1, 2, 20, 21],
|
181
|
-
[1, 2, 3],
|
182
|
-
[1, 2, 3, 1],
|
183
|
-
[2],
|
184
|
-
[2, 20],
|
185
|
-
[2, 20, 21],
|
186
|
-
[2, 3],
|
187
|
-
[2, 3, 1],
|
188
|
-
[2, 3, 1, 2],
|
189
|
-
[3],
|
190
|
-
[3, 1],
|
191
|
-
[3, 1, 2],
|
192
|
-
[3, 1, 2, 20],
|
193
|
-
[3, 1, 2, 20, 21],
|
194
|
-
[3, 1, 2, 3],
|
195
|
-
[20],
|
196
|
-
[20, 21],
|
197
|
-
[21],
|
198
|
-
)
|
199
|
-
end
|
139
|
+
it { is_expected.to be_empty }
|
200
140
|
end
|
201
141
|
|
202
|
-
context '
|
142
|
+
context 'direct predecessor' do
|
203
143
|
before do
|
204
|
-
graph.add_edge(
|
205
|
-
graph.add_edge(
|
206
|
-
graph.add_edge(3, 4)
|
207
|
-
graph.add_edge(4, 5)
|
208
|
-
graph.add_edge(5, 1)
|
209
|
-
end
|
210
|
-
|
211
|
-
example do
|
212
|
-
expect(subject).to contain_exactly(
|
213
|
-
[1],
|
214
|
-
[1, 2],
|
215
|
-
[1, 2, 3],
|
216
|
-
[1, 2, 3, 4],
|
217
|
-
[1, 2, 3, 4, 5],
|
218
|
-
[1, 2, 3, 4, 5, 1],
|
219
|
-
[2],
|
220
|
-
[2, 3],
|
221
|
-
[2, 3, 4],
|
222
|
-
[2, 3, 4, 5],
|
223
|
-
[2, 3, 4, 5, 1],
|
224
|
-
[2, 3, 4, 5, 1, 2],
|
225
|
-
[3],
|
226
|
-
[3, 4],
|
227
|
-
[3, 4, 5],
|
228
|
-
[3, 4, 5, 1],
|
229
|
-
[3, 4, 5, 1, 2],
|
230
|
-
[3, 4, 5, 1, 2, 3],
|
231
|
-
[4],
|
232
|
-
[4, 5],
|
233
|
-
[4, 5, 1],
|
234
|
-
[4, 5, 1, 2],
|
235
|
-
[4, 5, 1, 2, 3],
|
236
|
-
[4, 5, 1, 2, 3, 4],
|
237
|
-
[5],
|
238
|
-
[5, 1],
|
239
|
-
[5, 1, 2],
|
240
|
-
[5, 1, 2, 3],
|
241
|
-
[5, 1, 2, 3, 4],
|
242
|
-
[5, 1, 2, 3, 4, 5],
|
243
|
-
)
|
144
|
+
graph.add_edge('2', '3')
|
145
|
+
graph.add_edge('1', '2')
|
244
146
|
end
|
245
|
-
end
|
246
147
|
|
247
|
-
|
248
|
-
|
249
|
-
graph.add_edge(1, 2)
|
250
|
-
graph.add_edge(2, 3)
|
251
|
-
graph.add_edge(3, 4)
|
252
|
-
graph.add_edge(4, 5)
|
253
|
-
graph.add_edge(5, 2)
|
148
|
+
context 'no indirect predecessors' do
|
149
|
+
it { is_expected.to match_array(['1']) }
|
254
150
|
end
|
255
151
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
[1, 2],
|
260
|
-
[1, 2, 3],
|
261
|
-
[1, 2, 3, 4],
|
262
|
-
[1, 2, 3, 4, 5],
|
263
|
-
[1, 2, 3, 4, 5, 2],
|
264
|
-
[2],
|
265
|
-
[2, 3],
|
266
|
-
[2, 3, 4],
|
267
|
-
[2, 3, 4, 5],
|
268
|
-
[2, 3, 4, 5, 2],
|
269
|
-
[3],
|
270
|
-
[3, 4],
|
271
|
-
[3, 4, 5],
|
272
|
-
[3, 4, 5, 2],
|
273
|
-
[3, 4, 5, 2, 3],
|
274
|
-
[4],
|
275
|
-
[4, 5],
|
276
|
-
[4, 5, 2],
|
277
|
-
[4, 5, 2, 3],
|
278
|
-
[4, 5, 2, 3, 4],
|
279
|
-
[5],
|
280
|
-
[5, 2],
|
281
|
-
[5, 2, 3],
|
282
|
-
[5, 2, 3, 4],
|
283
|
-
[5, 2, 3, 4, 5],
|
284
|
-
)
|
152
|
+
context 'indirect predecessors' do
|
153
|
+
before { graph.add_edge('3', '1') }
|
154
|
+
it { is_expected.to match_array(%w[1 2 3]) }
|
285
155
|
end
|
286
156
|
end
|
287
157
|
end
|
288
158
|
|
289
|
-
describe '#
|
290
|
-
subject
|
291
|
-
[].tap do |ps|
|
292
|
-
graph.dfs_from(1) do |p|
|
293
|
-
ps << p
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
159
|
+
describe '#successors_of' do
|
160
|
+
subject { graph.successors_of('2') }
|
297
161
|
|
298
|
-
context 'no
|
299
|
-
|
300
|
-
|
301
|
-
[1],
|
302
|
-
)
|
162
|
+
context 'no successors' do
|
163
|
+
before do
|
164
|
+
graph.add_edge('1', '2')
|
303
165
|
end
|
166
|
+
|
167
|
+
it { is_expected.to be_empty }
|
304
168
|
end
|
305
169
|
|
306
|
-
context '
|
170
|
+
context 'direct predecessor' do
|
307
171
|
before do
|
308
|
-
graph.add_edge(1, 2)
|
309
|
-
graph.add_edge(2,
|
172
|
+
graph.add_edge('1', '2')
|
173
|
+
graph.add_edge('2', '3')
|
310
174
|
end
|
311
175
|
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
)
|
176
|
+
context 'no indirect successors' do
|
177
|
+
it { is_expected.to match_array(['3']) }
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'indirect successors' do
|
181
|
+
before { graph.add_edge('3', '1') }
|
182
|
+
it { is_expected.to match_array(%w[1 2 3]) }
|
318
183
|
end
|
319
184
|
end
|
185
|
+
end
|
320
186
|
|
321
|
-
|
187
|
+
describe '#inspect' do
|
188
|
+
subject { graph.inspect }
|
189
|
+
|
190
|
+
context 'empty graph' do
|
191
|
+
it { is_expected.to eq('Nanoc::Int::DirectedGraph()') }
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'one edge, no props' do
|
322
195
|
before do
|
323
|
-
graph.add_edge(1, 2)
|
324
|
-
graph.add_edge(2, 3)
|
325
|
-
graph.add_edge(3, 2)
|
196
|
+
graph.add_edge('1', '2')
|
326
197
|
end
|
327
198
|
|
328
|
-
|
329
|
-
expect(subject).to contain_exactly(
|
330
|
-
[1],
|
331
|
-
[1, 2],
|
332
|
-
[1, 2, 3],
|
333
|
-
[1, 2, 3, 2],
|
334
|
-
)
|
335
|
-
end
|
199
|
+
it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props=nil)') }
|
336
200
|
end
|
337
201
|
|
338
|
-
context '
|
202
|
+
context 'two edges, no props' do
|
339
203
|
before do
|
340
|
-
graph.add_edge(1, 2)
|
341
|
-
graph.add_edge(2,
|
342
|
-
graph.add_edge(20, 21)
|
343
|
-
graph.add_edge(2, 3)
|
344
|
-
graph.add_edge(3, 1)
|
204
|
+
graph.add_edge('1', '2')
|
205
|
+
graph.add_edge('2', '3')
|
345
206
|
end
|
346
207
|
|
347
|
-
|
348
|
-
expect(subject).to contain_exactly(
|
349
|
-
[1],
|
350
|
-
[1, 2],
|
351
|
-
[1, 2, 20],
|
352
|
-
[1, 2, 20, 21],
|
353
|
-
[1, 2, 3],
|
354
|
-
[1, 2, 3, 1],
|
355
|
-
)
|
356
|
-
end
|
208
|
+
it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props=nil, "2" -> "3" props=nil)') }
|
357
209
|
end
|
358
210
|
|
359
|
-
context '
|
211
|
+
context 'one edge, props' do
|
360
212
|
before do
|
361
|
-
graph.add_edge(1, 2)
|
362
|
-
graph.add_edge(2, 3)
|
363
|
-
graph.add_edge(3, 4)
|
364
|
-
graph.add_edge(4, 5)
|
365
|
-
graph.add_edge(5, 1)
|
213
|
+
graph.add_edge('1', '2', props: 'giraffe')
|
366
214
|
end
|
367
215
|
|
368
|
-
|
369
|
-
expect(subject).to contain_exactly(
|
370
|
-
[1],
|
371
|
-
[1, 2],
|
372
|
-
[1, 2, 3],
|
373
|
-
[1, 2, 3, 4],
|
374
|
-
[1, 2, 3, 4, 5],
|
375
|
-
[1, 2, 3, 4, 5, 1],
|
376
|
-
)
|
377
|
-
end
|
216
|
+
it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props="giraffe")') }
|
378
217
|
end
|
379
218
|
|
380
|
-
context '
|
219
|
+
context 'two edges, props' do
|
381
220
|
before do
|
382
|
-
graph.add_edge(1, 2)
|
383
|
-
graph.add_edge(2, 3)
|
384
|
-
graph.add_edge(3, 4)
|
385
|
-
graph.add_edge(4, 5)
|
386
|
-
graph.add_edge(5, 2)
|
221
|
+
graph.add_edge('1', '2', props: 'donkey')
|
222
|
+
graph.add_edge('2', '3', props: 'zebra')
|
387
223
|
end
|
388
224
|
|
389
|
-
|
390
|
-
expect(subject).to contain_exactly(
|
391
|
-
[1],
|
392
|
-
[1, 2],
|
393
|
-
[1, 2, 3],
|
394
|
-
[1, 2, 3, 4],
|
395
|
-
[1, 2, 3, 4, 5],
|
396
|
-
[1, 2, 3, 4, 5, 2],
|
397
|
-
)
|
398
|
-
end
|
225
|
+
it { is_expected.to eq('Nanoc::Int::DirectedGraph("1" -> "2" props="donkey", "2" -> "3" props="zebra")') }
|
399
226
|
end
|
400
227
|
end
|
401
228
|
end
|