nanoc 4.7.12 → 4.7.13

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