nanoc 4.7.12 → 4.7.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +6 -0
  3. data/lib/nanoc/base/core_ext.rb +0 -1
  4. data/lib/nanoc/base/entities.rb +4 -1
  5. data/lib/nanoc/base/entities/dependency.rb +5 -4
  6. data/lib/nanoc/base/entities/directed_graph.rb +12 -0
  7. data/lib/nanoc/base/entities/identifiable_collection.rb +11 -6
  8. data/lib/nanoc/base/entities/item_collection.rb +14 -0
  9. data/lib/nanoc/base/entities/layout_collection.rb +14 -0
  10. data/lib/nanoc/base/entities/outdatedness_reasons.rb +19 -0
  11. data/lib/nanoc/base/entities/props.rb +33 -10
  12. data/lib/nanoc/base/repos/aggregate_data_source.rb +2 -2
  13. data/lib/nanoc/base/repos/checksum_store.rb +1 -1
  14. data/lib/nanoc/base/repos/dependency_store.rb +25 -12
  15. data/lib/nanoc/base/services/dependency_tracker.rb +3 -2
  16. data/lib/nanoc/base/services/outdatedness_checker.rb +33 -10
  17. data/lib/nanoc/base/services/outdatedness_rules.rb +2 -0
  18. data/lib/nanoc/base/services/outdatedness_rules/item_collection_extended.rb +16 -0
  19. data/lib/nanoc/base/services/outdatedness_rules/layout_collection_extended.rb +16 -0
  20. data/lib/nanoc/base/services/pruner.rb +13 -1
  21. data/lib/nanoc/base/views/identifiable_collection_view.rb +24 -0
  22. data/lib/nanoc/cli/commands/show-data.rb +4 -0
  23. data/lib/nanoc/spec.rb +2 -2
  24. data/lib/nanoc/version.rb +1 -1
  25. data/spec/nanoc/base/checksummer_spec.rb +4 -4
  26. data/spec/nanoc/base/compiler_spec.rb +2 -2
  27. data/spec/nanoc/base/directed_graph_spec.rb +42 -0
  28. data/spec/nanoc/base/entities/identifiable_collection_spec.rb +110 -93
  29. data/spec/nanoc/base/entities/props_spec.rb +121 -1
  30. data/spec/nanoc/base/entities/site_spec.rb +2 -2
  31. data/spec/nanoc/base/repos/dependency_store_spec.rb +34 -40
  32. data/spec/nanoc/base/services/compiler/stages/calculate_checksums_spec.rb +2 -2
  33. data/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb +2 -2
  34. data/spec/nanoc/base/services/dependency_tracker_spec.rb +3 -4
  35. data/spec/nanoc/base/services/outdatedness_checker_spec.rb +290 -4
  36. data/spec/nanoc/base/services/outdatedness_rules_spec.rb +3 -3
  37. data/spec/nanoc/base/services/pruner_spec.rb +9 -0
  38. data/spec/nanoc/base/views/document_view_spec.rb +3 -4
  39. data/spec/nanoc/base/views/identifiable_collection_view_spec.rb +74 -7
  40. data/spec/nanoc/base/views/item_collection_with_reps_view_spec.rb +2 -1
  41. data/spec/nanoc/base/views/item_collection_without_reps_view_spec.rb +2 -1
  42. data/spec/nanoc/base/views/item_rep_view_spec.rb +3 -4
  43. data/spec/nanoc/base/views/item_view_spec.rb +5 -6
  44. data/spec/nanoc/base/views/layout_collection_view_spec.rb +2 -1
  45. data/spec/nanoc/base/views/mutable_identifiable_collection_view_spec.rb +1 -1
  46. data/spec/nanoc/base/views/mutable_item_collection_view_spec.rb +3 -2
  47. data/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb +3 -2
  48. data/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb +1 -1
  49. data/spec/nanoc/cli/commands/show_data_spec.rb +4 -4
  50. data/spec/nanoc/cli/commands/show_rules_spec.rb +2 -2
  51. data/spec/nanoc/helpers/rendering_spec.rb +5 -0
  52. data/spec/nanoc/rule_dsl/action_sequence_calculator_spec.rb +2 -2
  53. data/spec/nanoc/rule_dsl/rule_context_spec.rb +6 -4
  54. data/test/base/test_dependency_tracker.rb +22 -22
  55. data/test/base/test_item_array.rb +2 -2
  56. data/test/filters/test_xsl.rb +2 -2
  57. data/test/fixtures/vcr_cassettes/html_run_error.yml +17 -12
  58. data/test/fixtures/vcr_cassettes/html_run_ok.yml +17 -12
  59. data/test/helpers/test_blogging.rb +2 -2
  60. data/test/helpers/test_xml_sitemap.rb +7 -7
  61. metadata +6 -4
  62. data/lib/nanoc/base/core_ext/pathname.rb +0 -10
  63. data/test/extra/core_ext/test_pathname.rb +0 -14
@@ -12,3 +12,5 @@ require_relative 'outdatedness_rules/content_modified'
12
12
  require_relative 'outdatedness_rules/not_written'
13
13
  require_relative 'outdatedness_rules/rules_modified'
14
14
  require_relative 'outdatedness_rules/uses_always_outdated_filter'
15
+ require_relative 'outdatedness_rules/item_collection_extended'
16
+ require_relative 'outdatedness_rules/layout_collection_extended'
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc::Int::OutdatednessRules
4
+ class ItemCollectionExtended < Nanoc::Int::OutdatednessRule
5
+ affects_props :raw_content
6
+
7
+ contract Nanoc::Int::ItemCollection, C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic]
8
+ def apply(_obj, outdatedness_checker)
9
+ new_items = outdatedness_checker.dependency_store.new_items
10
+
11
+ if new_items.any?
12
+ Nanoc::Int::OutdatednessReasons::ItemCollectionExtended.new(new_items)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc::Int::OutdatednessRules
4
+ class LayoutCollectionExtended < Nanoc::Int::OutdatednessRule
5
+ affects_props :raw_content
6
+
7
+ contract Nanoc::Int::LayoutCollection, C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic]
8
+ def apply(_obj, outdatedness_checker)
9
+ new_layouts = outdatedness_checker.dependency_store.new_layouts
10
+
11
+ if new_layouts.any?
12
+ Nanoc::Int::OutdatednessReasons::LayoutCollectionExtended.new(new_layouts)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -46,7 +46,19 @@ module Nanoc
46
46
  # @return [Boolean] true if the given file is excluded, false otherwise
47
47
  def filename_excluded?(filename)
48
48
  pathname = Pathname.new(filename)
49
- @exclude.any? { |e| pathname.__nanoc_include_component?(e) }
49
+ @exclude.any? { |e| pathname_components(pathname).include?(e) }
50
+ end
51
+
52
+ def pathname_components(pathname)
53
+ components = []
54
+ tmp = pathname
55
+ loop do
56
+ old = tmp
57
+ components << File.basename(tmp)
58
+ tmp = File.dirname(tmp)
59
+ break if old == tmp
60
+ end
61
+ components.reverse
50
62
  end
51
63
 
52
64
  # @api private
@@ -30,12 +30,14 @@ module Nanoc
30
30
  #
31
31
  # @return [self]
32
32
  def each
33
+ @context.dependency_tracker.bounce(unwrap, raw_content: true)
33
34
  @objects.each { |i| yield view_class.new(i, @context) }
34
35
  self
35
36
  end
36
37
 
37
38
  # @return [Integer]
38
39
  def size
40
+ @context.dependency_tracker.bounce(unwrap, raw_content: true)
39
41
  @objects.size
40
42
  end
41
43
 
@@ -45,6 +47,17 @@ module Nanoc
45
47
  #
46
48
  # @return [Enumerable]
47
49
  def find_all(arg)
50
+ prop_attribute =
51
+ case arg
52
+ when String, Nanoc::Identifier
53
+ [arg.to_s]
54
+ when Regexp
55
+ [arg]
56
+ else
57
+ true
58
+ end
59
+
60
+ @context.dependency_tracker.bounce(unwrap, raw_content: prop_attribute)
48
61
  @objects.find_all(arg).map { |i| view_class.new(i, @context) }
49
62
  end
50
63
 
@@ -71,6 +84,17 @@ module Nanoc
71
84
  #
72
85
  # @return [#identifier] if an object was found
73
86
  def [](arg)
87
+ prop_attribute =
88
+ case arg
89
+ when String, Nanoc::Identifier
90
+ [arg.to_s]
91
+ when Regexp
92
+ [arg]
93
+ else
94
+ true
95
+ end
96
+
97
+ @context.dependency_tracker.bounce(unwrap, raw_content: prop_attribute)
74
98
  res = @objects[arg]
75
99
  res && view_class.new(res, @context)
76
100
  end
@@ -99,6 +99,10 @@ module Nanoc::CLI::Commands
99
99
  'item'
100
100
  when Nanoc::Int::Configuration
101
101
  'config'
102
+ when Nanoc::Int::ItemCollection
103
+ 'items'
104
+ when Nanoc::Int::LayoutCollection
105
+ 'layouts'
102
106
  else
103
107
  raise Nanoc::Int::Errors::InternalInconsistency, "unexpected pred type #{pred}"
104
108
  end
@@ -17,8 +17,8 @@ module Nanoc
17
17
  @action_sequence = {}
18
18
  @config = Nanoc::Int::Configuration.new.with_defaults
19
19
  @reps = Nanoc::Int::ItemRepRepo.new
20
- @items = Nanoc::Int::IdentifiableCollection.new(@config)
21
- @layouts = Nanoc::Int::IdentifiableCollection.new(@config)
20
+ @items = Nanoc::Int::ItemCollection.new(@config)
21
+ @layouts = Nanoc::Int::LayoutCollection.new(@config)
22
22
  @dependency_tracker = Nanoc::Int::DependencyTracker.new(Object.new)
23
23
  end
24
24
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Nanoc
4
4
  # The current Nanoc version.
5
- VERSION = '4.7.12'
5
+ VERSION = '4.7.13'
6
6
  end
@@ -301,7 +301,7 @@ describe Nanoc::Int::Checksummer do
301
301
  let(:config) { Nanoc::Int::Configuration.new(hash: { 'foo' => 'bar' }) }
302
302
 
303
303
  let(:wrapped) do
304
- Nanoc::Int::IdentifiableCollection.new(
304
+ Nanoc::Int::ItemCollection.new(
305
305
  config,
306
306
  [
307
307
  Nanoc::Int::Item.new('foo', {}, '/foo.md'),
@@ -310,7 +310,7 @@ describe Nanoc::Int::Checksummer do
310
310
  )
311
311
  end
312
312
 
313
- it { is_expected.to eql('Nanoc::ItemCollectionWithRepsView<Nanoc::Int::IdentifiableCollection<Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<foo>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<bar>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,>>') }
313
+ it { is_expected.to eql('Nanoc::ItemCollectionWithRepsView<Nanoc::Int::ItemCollection<Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<foo>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<bar>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,>>') }
314
314
  end
315
315
 
316
316
  context 'Nanoc::ItemCollectionWithoutRepsView' do
@@ -319,7 +319,7 @@ describe Nanoc::Int::Checksummer do
319
319
  let(:config) { Nanoc::Int::Configuration.new(hash: { 'foo' => 'bar' }) }
320
320
 
321
321
  let(:wrapped) do
322
- Nanoc::Int::IdentifiableCollection.new(
322
+ Nanoc::Int::ItemCollection.new(
323
323
  config,
324
324
  [
325
325
  Nanoc::Int::Item.new('foo', {}, '/foo.md'),
@@ -328,7 +328,7 @@ describe Nanoc::Int::Checksummer do
328
328
  )
329
329
  end
330
330
 
331
- it { is_expected.to eql('Nanoc::ItemCollectionWithoutRepsView<Nanoc::Int::IdentifiableCollection<Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<foo>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<bar>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,>>') }
331
+ it { is_expected.to eql('Nanoc::ItemCollectionWithoutRepsView<Nanoc::Int::ItemCollection<Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<foo>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,Nanoc::Int::Item<content=Nanoc::Int::TextualContent<String<bar>>,attributes=Hash<>,identifier=Nanoc::Identifier<String</foo.md>>>,>>') }
332
332
  end
333
333
 
334
334
  context 'Nanoc::RuleDSL::RuleContext' do
@@ -43,11 +43,11 @@ describe Nanoc::Int::Compiler do
43
43
  let(:code_snippets) { [] }
44
44
 
45
45
  let(:items) do
46
- Nanoc::Int::IdentifiableCollection.new(config, [item, other_item])
46
+ Nanoc::Int::ItemCollection.new(config, [item, other_item])
47
47
  end
48
48
 
49
49
  let(:layouts) do
50
- Nanoc::Int::IdentifiableCollection.new(config)
50
+ Nanoc::Int::LayoutCollection.new(config)
51
51
  end
52
52
 
53
53
  let(:memory) do
@@ -3,6 +3,48 @@
3
3
  describe Nanoc::Int::DirectedGraph do
4
4
  subject(:graph) { described_class.new([1, 2, 3]) }
5
5
 
6
+ describe '#inspect' do
7
+ subject { graph.inspect }
8
+
9
+ context 'empty graph' do
10
+ it { is_expected.to eq('Nanoc::Int::DirectedGraph()') }
11
+ end
12
+
13
+ context 'one edge, no props' do
14
+ before do
15
+ graph.add_edge(1, 2)
16
+ end
17
+
18
+ it { is_expected.to eq('Nanoc::Int::DirectedGraph(1 -> 2 props=nil)') }
19
+ end
20
+
21
+ context 'two edges, no props' do
22
+ before do
23
+ graph.add_edge(1, 2)
24
+ graph.add_edge(2, 3)
25
+ end
26
+
27
+ it { is_expected.to eq('Nanoc::Int::DirectedGraph(1 -> 2 props=nil, 2 -> 3 props=nil)') }
28
+ end
29
+
30
+ context 'one edge, props' do
31
+ before do
32
+ graph.add_edge(1, 2, props: 'giraffe')
33
+ end
34
+
35
+ it { is_expected.to eq('Nanoc::Int::DirectedGraph(1 -> 2 props="giraffe")') }
36
+ end
37
+
38
+ context 'two edges, props' do
39
+ before do
40
+ graph.add_edge(1, 2, props: 'donkey')
41
+ graph.add_edge(2, 3, props: 'zebra')
42
+ end
43
+
44
+ it { is_expected.to eq('Nanoc::Int::DirectedGraph(1 -> 2 props="donkey", 2 -> 3 props="zebra")') }
45
+ end
46
+ end
47
+
6
48
  describe '#any_cycle' do
7
49
  subject { graph.any_cycle }
8
50
 
@@ -1,133 +1,150 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Nanoc::Int::IdentifiableCollection do
4
- subject(:identifiable_collection) { described_class.new(config, objects) }
4
+ shared_examples 'a generic identifiable collection' do
5
+ subject(:identifiable_collection) { described_class.new(config, objects) }
5
6
 
6
- let(:config) { Nanoc::Int::Configuration.new }
7
- let(:objects) { [] }
7
+ let(:config) { Nanoc::Int::Configuration.new }
8
+ let(:objects) { [] }
8
9
 
9
- describe '#reject' do
10
- subject { identifiable_collection.reject { |_| false } }
10
+ describe '#reject' do
11
+ subject { identifiable_collection.reject { |_| false } }
11
12
 
12
- it { is_expected.to be_a(described_class) }
13
- end
14
-
15
- describe '#[]' do
16
- let(:objects) do
17
- [
18
- Nanoc::Int::Item.new('asdf', {}, Nanoc::Identifier.new('/one')),
19
- Nanoc::Int::Item.new('asdf', {}, Nanoc::Identifier.new('/two')),
20
- ]
13
+ it { is_expected.to be_a(described_class) }
21
14
  end
22
15
 
23
- context 'string pattern style is glob' do
24
- let(:config) { Nanoc::Int::Configuration.new.with_defaults }
16
+ describe '#[]' do
17
+ let(:objects) do
18
+ [
19
+ Nanoc::Int::Item.new('asdf', {}, Nanoc::Identifier.new('/one')),
20
+ Nanoc::Int::Item.new('asdf', {}, Nanoc::Identifier.new('/two')),
21
+ ]
22
+ end
23
+
24
+ context 'string pattern style is glob' do
25
+ let(:config) { Nanoc::Int::Configuration.new.with_defaults }
25
26
 
26
- it 'handles glob' do
27
- expect(identifiable_collection['/on*']).to equal(objects[0])
28
- expect(identifiable_collection['/*wo']).to equal(objects[1])
27
+ it 'handles glob' do
28
+ expect(identifiable_collection['/on*']).to equal(objects[0])
29
+ expect(identifiable_collection['/*wo']).to equal(objects[1])
30
+ end
29
31
  end
30
- end
31
32
 
32
- context 'string pattern style is glob' do
33
- let(:config) { Nanoc::Int::Configuration.new }
33
+ context 'string pattern style is glob' do
34
+ let(:config) { Nanoc::Int::Configuration.new }
34
35
 
35
- it 'does not handle glob' do
36
- expect(identifiable_collection['/on*']).to be_nil
37
- expect(identifiable_collection['/*wo']).to be_nil
36
+ it 'does not handle glob' do
37
+ expect(identifiable_collection['/on*']).to be_nil
38
+ expect(identifiable_collection['/*wo']).to be_nil
39
+ end
38
40
  end
39
- end
40
41
 
41
- it 'handles identifier' do
42
- expect(identifiable_collection['/one']).to equal(objects[0])
43
- expect(identifiable_collection['/two']).to equal(objects[1])
44
- end
42
+ it 'handles identifier' do
43
+ expect(identifiable_collection['/one']).to equal(objects[0])
44
+ expect(identifiable_collection['/two']).to equal(objects[1])
45
+ end
45
46
 
46
- it 'handles malformed identifier' do
47
- expect(identifiable_collection['one/']).to be_nil
48
- expect(identifiable_collection['/one/']).to be_nil
49
- expect(identifiable_collection['one']).to be_nil
50
- expect(identifiable_collection['//one']).to be_nil
51
- expect(identifiable_collection['/one//']).to be_nil
52
- end
47
+ it 'handles malformed identifier' do
48
+ expect(identifiable_collection['one/']).to be_nil
49
+ expect(identifiable_collection['/one/']).to be_nil
50
+ expect(identifiable_collection['one']).to be_nil
51
+ expect(identifiable_collection['//one']).to be_nil
52
+ expect(identifiable_collection['/one//']).to be_nil
53
+ end
53
54
 
54
- it 'handles regex' do
55
- expect(identifiable_collection[/one/]).to equal(objects[0])
56
- expect(identifiable_collection[/on/]).to equal(objects[0])
57
- expect(identifiable_collection[/\/o/]).to equal(objects[0])
58
- expect(identifiable_collection[/e$/]).to equal(objects[0])
59
- end
55
+ it 'handles regex' do
56
+ expect(identifiable_collection[/one/]).to equal(objects[0])
57
+ expect(identifiable_collection[/on/]).to equal(objects[0])
58
+ expect(identifiable_collection[/\/o/]).to equal(objects[0])
59
+ expect(identifiable_collection[/e$/]).to equal(objects[0])
60
+ end
60
61
 
61
- context 'frozen' do
62
- before { identifiable_collection.freeze }
62
+ context 'frozen' do
63
+ before { identifiable_collection.freeze }
63
64
 
64
- example do
65
- expect(identifiable_collection['/one']).to equal(objects[0])
66
- expect(identifiable_collection['/fifty']).to be_nil
65
+ example do
66
+ expect(identifiable_collection['/one']).to equal(objects[0])
67
+ expect(identifiable_collection['/fifty']).to be_nil
68
+ end
67
69
  end
68
70
  end
69
- end
70
71
 
71
- describe '#find_all' do
72
- let(:objects) do
73
- [
74
- double(:identifiable, identifier: Nanoc::Identifier.new('/about.css')),
75
- double(:identifiable, identifier: Nanoc::Identifier.new('/about.md')),
76
- double(:identifiable, identifier: Nanoc::Identifier.new('/style.css')),
77
- ]
78
- end
72
+ describe '#find_all' do
73
+ let(:objects) do
74
+ [
75
+ double(:identifiable, identifier: Nanoc::Identifier.new('/about.css')),
76
+ double(:identifiable, identifier: Nanoc::Identifier.new('/about.md')),
77
+ double(:identifiable, identifier: Nanoc::Identifier.new('/style.css')),
78
+ ]
79
+ end
79
80
 
80
- let(:arg) { raise 'override me' }
81
+ let(:arg) { raise 'override me' }
81
82
 
82
- subject { identifiable_collection.find_all(arg) }
83
+ subject { identifiable_collection.find_all(arg) }
83
84
 
84
- context 'with string' do
85
- let(:arg) { '/*.css' }
85
+ context 'with string' do
86
+ let(:arg) { '/*.css' }
86
87
 
87
- it 'contains objects' do
88
- expect(subject.size).to eql(2)
89
- expect(subject.find { |iv| iv.identifier == '/about.css' }).to eq(objects[0])
90
- expect(subject.find { |iv| iv.identifier == '/style.css' }).to eq(objects[2])
88
+ it 'contains objects' do
89
+ expect(subject.size).to eql(2)
90
+ expect(subject.find { |iv| iv.identifier == '/about.css' }).to eq(objects[0])
91
+ expect(subject.find { |iv| iv.identifier == '/style.css' }).to eq(objects[2])
92
+ end
91
93
  end
92
- end
93
94
 
94
- context 'with regex' do
95
- let(:arg) { %r{\.css\z} }
95
+ context 'with regex' do
96
+ let(:arg) { %r{\.css\z} }
96
97
 
97
- it 'contains objects' do
98
- expect(subject.size).to eql(2)
99
- expect(subject.find { |iv| iv.identifier == '/about.css' }).to eq(objects[0])
100
- expect(subject.find { |iv| iv.identifier == '/style.css' }).to eq(objects[2])
98
+ it 'contains objects' do
99
+ expect(subject.size).to eql(2)
100
+ expect(subject.find { |iv| iv.identifier == '/about.css' }).to eq(objects[0])
101
+ expect(subject.find { |iv| iv.identifier == '/style.css' }).to eq(objects[2])
102
+ end
101
103
  end
102
104
  end
103
- end
104
105
 
105
- describe '#object_with_identifier' do
106
- let(:objects) do
107
- [
108
- Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/about.css')),
109
- Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/about.md')),
110
- Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/style.css')),
111
- ]
112
- end
106
+ describe '#object_with_identifier' do
107
+ let(:objects) do
108
+ [
109
+ Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/about.css')),
110
+ Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/about.md')),
111
+ Nanoc::Int::Item.new('stuff', {}, Nanoc::Identifier.new('/style.css')),
112
+ ]
113
+ end
113
114
 
114
- let(:arg) { raise 'override me' }
115
+ let(:arg) { raise 'override me' }
115
116
 
116
- subject { identifiable_collection.object_with_identifier(arg) }
117
+ subject { identifiable_collection.object_with_identifier(arg) }
117
118
 
118
- context 'with string' do
119
- let(:arg) { '/about.css' }
120
- it { is_expected.to eq(objects[0]) }
121
- end
119
+ context 'with string' do
120
+ let(:arg) { '/about.css' }
121
+ it { is_expected.to eq(objects[0]) }
122
+ end
122
123
 
123
- context 'with identifier' do
124
- let(:arg) { Nanoc::Identifier.new('/about.css') }
125
- it { is_expected.to eq(objects[0]) }
124
+ context 'with identifier' do
125
+ let(:arg) { Nanoc::Identifier.new('/about.css') }
126
+ it { is_expected.to eq(objects[0]) }
127
+ end
128
+
129
+ context 'with glob string' do
130
+ let(:arg) { '/about.*' }
131
+ it { is_expected.to be_nil }
132
+ end
126
133
  end
127
134
 
128
- context 'with glob string' do
129
- let(:arg) { '/about.*' }
130
- it { is_expected.to be_nil }
135
+ describe '#reference' do
136
+ subject { identifiable_collection.reference }
137
+ it { is_expected.to eql(expected_reference) }
131
138
  end
132
139
  end
140
+
141
+ describe Nanoc::Int::ItemCollection do
142
+ let(:expected_reference) { :items }
143
+ it_behaves_like 'a generic identifiable collection'
144
+ end
145
+
146
+ describe Nanoc::Int::LayoutCollection do
147
+ let(:expected_reference) { :layouts }
148
+ it_behaves_like 'a generic identifiable collection'
149
+ end
133
150
  end