nanoc 4.8.2 → 4.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +13 -1
  3. data/lib/nanoc/base/entities/document.rb +6 -1
  4. data/lib/nanoc/base/entities/identifier.rb +10 -3
  5. data/lib/nanoc/cli/command_runner.rb +27 -4
  6. data/lib/nanoc/cli/commands/view.rb +6 -2
  7. data/lib/nanoc/spec.rb +10 -0
  8. data/lib/nanoc/version.rb +1 -1
  9. data/spec/nanoc/base/entities/document_spec.rb +30 -0
  10. data/spec/nanoc/base/entities/identifier_spec.rb +13 -3
  11. data/spec/nanoc/base/item_rep_writer_spec.rb +1 -1
  12. data/spec/nanoc/base/services/executor_spec.rb +1 -1
  13. data/spec/nanoc/base/views/document_view_spec.rb +13 -13
  14. data/spec/nanoc/base/views/item_rep_view_spec.rb +15 -15
  15. data/spec/nanoc/base/views/item_view_spec.rb +21 -12
  16. data/spec/nanoc/base/views/layout_view_spec.rb +2 -2
  17. data/spec/nanoc/base/views/mutable_document_view_spec.rb +3 -3
  18. data/spec/nanoc/base/views/mutable_identifiable_collection_view_spec.rb +4 -4
  19. data/spec/nanoc/base/views/mutable_item_collection_view_spec.rb +5 -5
  20. data/spec/nanoc/base/views/mutable_item_view_spec.rb +3 -3
  21. data/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb +5 -5
  22. data/spec/nanoc/base/views/mutable_layout_view_spec.rb +2 -2
  23. data/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb +1 -1
  24. data/spec/nanoc/cli/command_runner_spec.rb +90 -0
  25. data/spec/nanoc/cli/commands/show_rules_spec.rb +1 -0
  26. data/spec/nanoc/cli/commands/view_spec.rb +13 -0
  27. data/spec/nanoc/cli_spec.rb +1 -1
  28. data/spec/nanoc/data_sources/filesystem_spec.rb +1 -1
  29. data/spec/nanoc/helpers/blogging_spec.rb +18 -18
  30. data/spec/nanoc/helpers/link_to_spec.rb +8 -8
  31. data/spec/spec_helper.rb +7 -8
  32. data/test/base/test_data_source.rb +8 -8
  33. data/test/base/test_item_array.rb +11 -11
  34. data/test/cli/commands/test_compile.rb +2 -2
  35. data/test/filters/test_handlebars.rb +3 -3
  36. data/test/filters/test_mustache.rb +2 -2
  37. data/test/filters/test_relativize_paths.rb +29 -29
  38. data/test/filters/test_sass.rb +1 -1
  39. data/test/filters/test_xsl.rb +6 -6
  40. data/test/helpers/test_capturing.rb +1 -1
  41. data/test/helpers/test_xml_sitemap.rb +15 -15
  42. metadata +4 -3
@@ -53,15 +53,15 @@ describe Nanoc::ItemWithRepsView do
53
53
  subject { view.parent }
54
54
 
55
55
  context 'with parent' do
56
- let(:parent_item) do
57
- Nanoc::Int::Item.new('parent', {}, '/parent/')
58
- end
59
-
60
56
  context 'full identifier' do
61
57
  let(:identifier) do
62
58
  Nanoc::Identifier.new('/parent/me.md')
63
59
  end
64
60
 
61
+ let(:parent_item) do
62
+ Nanoc::Int::Item.new('parent', {}, '/parent.md')
63
+ end
64
+
65
65
  it 'raises' do
66
66
  expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem)
67
67
  end
@@ -72,6 +72,10 @@ describe Nanoc::ItemWithRepsView do
72
72
  Nanoc::Identifier.new('/parent/me/', type: :legacy)
73
73
  end
74
74
 
75
+ let(:parent_item) do
76
+ Nanoc::Int::Item.new('parent', {}, Nanoc::Identifier.new('/parent/', type: :legacy))
77
+ end
78
+
75
79
  it 'returns a view for the parent' do
76
80
  expect(subject.class).to eql(Nanoc::ItemWithRepsView)
77
81
  expect(subject.unwrap).to eql(parent_item)
@@ -91,8 +95,9 @@ describe Nanoc::ItemWithRepsView do
91
95
  end
92
96
 
93
97
  context 'with root parent' do
94
- let(:parent_item) { Nanoc::Int::Item.new('parent', {}, '/') }
98
+ let(:parent_item) { Nanoc::Int::Item.new('parent', {}, parent_identifier) }
95
99
  let(:identifier) { Nanoc::Identifier.new('/me/', type: :legacy) }
100
+ let(:parent_identifier) { Nanoc::Identifier.new('/', type: :legacy) }
96
101
 
97
102
  it 'returns a view for the parent' do
98
103
  expect(subject.class).to eql(Nanoc::ItemWithRepsView)
@@ -133,10 +138,6 @@ describe Nanoc::ItemWithRepsView do
133
138
  Nanoc::Int::Item.new('me', {}, identifier)
134
139
  end
135
140
 
136
- let(:children) do
137
- [Nanoc::Int::Item.new('child', {}, '/me/child/')]
138
- end
139
-
140
141
  let(:view) { described_class.new(item, view_context) }
141
142
 
142
143
  let(:items) do
@@ -156,6 +157,10 @@ describe Nanoc::ItemWithRepsView do
156
157
  Nanoc::Identifier.new('/me.md')
157
158
  end
158
159
 
160
+ let(:children) do
161
+ [Nanoc::Int::Item.new('child', {}, '/me/child.md')]
162
+ end
163
+
159
164
  it 'raises' do
160
165
  expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem)
161
166
  end
@@ -166,6 +171,10 @@ describe Nanoc::ItemWithRepsView do
166
171
  Nanoc::Identifier.new('/me/', type: :legacy)
167
172
  end
168
173
 
174
+ let(:children) do
175
+ [Nanoc::Int::Item.new('child', {}, Nanoc::Identifier.new('/me/child/', type: :legacy))]
176
+ end
177
+
169
178
  it 'returns views for the children' do
170
179
  expect(subject.size).to eql(1)
171
180
  expect(subject[0].class).to eql(Nanoc::ItemWithRepsView)
@@ -208,7 +217,7 @@ describe Nanoc::ItemWithRepsView do
208
217
  let(:view) { described_class.new(item, view_context) }
209
218
 
210
219
  let(:item) do
211
- Nanoc::Int::Item.new('content', {}, '/asdf/')
220
+ Nanoc::Int::Item.new('content', {}, '/asdf')
212
221
  end
213
222
 
214
223
  let(:reps) do
@@ -355,11 +364,11 @@ describe Nanoc::ItemWithRepsView do
355
364
  end
356
365
 
357
366
  describe '#inspect' do
358
- let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
367
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf') }
359
368
  let(:view) { described_class.new(item, nil) }
360
369
 
361
370
  subject { view.inspect }
362
371
 
363
- it { is_expected.to eql('<Nanoc::ItemWithRepsView identifier=/asdf/>') }
372
+ it { is_expected.to eql('<Nanoc::ItemWithRepsView identifier=/asdf>') }
364
373
  end
365
374
  end
@@ -6,11 +6,11 @@ describe Nanoc::LayoutView do
6
6
  it_behaves_like 'a document view'
7
7
 
8
8
  describe '#inspect' do
9
- let(:item) { Nanoc::Int::Layout.new('content', {}, '/asdf/') }
9
+ let(:item) { Nanoc::Int::Layout.new('content', {}, '/asdf') }
10
10
  let(:view) { described_class.new(item, nil) }
11
11
 
12
12
  subject { view.inspect }
13
13
 
14
- it { is_expected.to eql('<Nanoc::LayoutView identifier=/asdf/>') }
14
+ it { is_expected.to eql('<Nanoc::LayoutView identifier=/asdf>') }
15
15
  end
16
16
  end
@@ -17,7 +17,7 @@ shared_examples 'a mutable document view' do
17
17
  let(:snapshot_repo) { double(:snapshot_repo) }
18
18
 
19
19
  describe '#raw_content=' do
20
- let(:document) { entity_class.new('content', {}, '/asdf/') }
20
+ let(:document) { entity_class.new('content', {}, '/asdf') }
21
21
 
22
22
  it 'sets raw content' do
23
23
  expect { view.raw_content = 'donkey' }
@@ -28,7 +28,7 @@ shared_examples 'a mutable document view' do
28
28
  end
29
29
 
30
30
  describe '#[]=' do
31
- let(:document) { entity_class.new('content', {}, '/asdf/') }
31
+ let(:document) { entity_class.new('content', {}, '/asdf') }
32
32
 
33
33
  it 'sets attributes' do
34
34
  view[:title] = 'Donkey'
@@ -89,7 +89,7 @@ shared_examples 'a mutable document view' do
89
89
  end
90
90
 
91
91
  describe '#update_attributes' do
92
- let(:document) { entity_class.new('content', {}, '/asdf/') }
92
+ let(:document) { entity_class.new('content', {}, '/asdf') }
93
93
 
94
94
  let(:update) { { friend: 'Giraffe' } }
95
95
 
@@ -13,22 +13,22 @@ shared_examples 'a mutable identifiable collection' do
13
13
  let(:wrapped) do
14
14
  collection_class.new(
15
15
  config,
16
- [double(:identifiable, identifier: Nanoc::Identifier.new('/asdf/'))],
16
+ [double(:identifiable, identifier: Nanoc::Identifier.new('/asdf'))],
17
17
  )
18
18
  end
19
19
 
20
20
  it 'deletes matching' do
21
- view.delete_if { |i| i.identifier == '/asdf/' }
21
+ view.delete_if { |i| i.identifier == '/asdf' }
22
22
  expect(view.unwrap).to be_empty
23
23
  end
24
24
 
25
25
  it 'does not mutate' do
26
- view.delete_if { |i| i.identifier == '/asdf/' }
26
+ view.delete_if { |i| i.identifier == '/asdf' }
27
27
  expect(wrapped).not_to be_empty
28
28
  end
29
29
 
30
30
  it 'deletes no non-matching' do
31
- view.delete_if { |i| i.identifier == '/blah/' }
31
+ view.delete_if { |i| i.identifier == '/blah' }
32
32
  expect(wrapped).not_to be_empty
33
33
  end
34
34
 
@@ -12,7 +12,7 @@ describe Nanoc::MutableItemCollectionView do
12
12
 
13
13
  describe '#create' do
14
14
  let(:item) do
15
- Nanoc::Int::Layout.new('content', {}, '/asdf/')
15
+ Nanoc::Int::Layout.new('content', {}, '/asdf')
16
16
  end
17
17
 
18
18
  let(:wrapped) do
@@ -22,21 +22,21 @@ describe Nanoc::MutableItemCollectionView do
22
22
  let(:view) { described_class.new(wrapped, nil) }
23
23
 
24
24
  it 'creates an object' do
25
- view.create('new content', { title: 'New Page' }, '/new/')
25
+ view.create('new content', { title: 'New Page' }, '/new')
26
26
 
27
27
  expect(view.unwrap.size).to eq(2)
28
- expect(view.unwrap['/new/'].content.string).to eq('new content')
28
+ expect(view.unwrap['/new'].content.string).to eq('new content')
29
29
  end
30
30
 
31
31
  it 'does not update wrapped' do
32
- view.create('new content', { title: 'New Page' }, '/new/')
32
+ view.create('new content', { title: 'New Page' }, '/new')
33
33
 
34
34
  expect(wrapped.size).to eq(1)
35
35
  expect(wrapped['/new']).to be_nil
36
36
  end
37
37
 
38
38
  it 'returns self' do
39
- ret = view.create('new content', { title: 'New Page' }, '/new/')
39
+ ret = view.create('new content', { title: 'New Page' }, '/new')
40
40
  expect(ret).to equal(view)
41
41
  end
42
42
  end
@@ -4,7 +4,7 @@ describe Nanoc::MutableItemView do
4
4
  let(:entity_class) { Nanoc::Int::Item }
5
5
  it_behaves_like 'a mutable document view'
6
6
 
7
- let(:item) { entity_class.new('content', {}, '/asdf/') }
7
+ let(:item) { entity_class.new('content', {}, '/asdf') }
8
8
  let(:view) { described_class.new(item, nil) }
9
9
 
10
10
  it 'does have rep access' do
@@ -14,11 +14,11 @@ describe Nanoc::MutableItemView do
14
14
  end
15
15
 
16
16
  describe '#inspect' do
17
- let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
17
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf') }
18
18
  let(:view) { described_class.new(item, nil) }
19
19
 
20
20
  subject { view.inspect }
21
21
 
22
- it { is_expected.to eql('<Nanoc::MutableItemView identifier=/asdf/>') }
22
+ it { is_expected.to eql('<Nanoc::MutableItemView identifier=/asdf>') }
23
23
  end
24
24
  end
@@ -12,7 +12,7 @@ describe Nanoc::MutableLayoutCollectionView do
12
12
 
13
13
  describe '#create' do
14
14
  let(:layout) do
15
- Nanoc::Int::Layout.new('content', {}, '/asdf/')
15
+ Nanoc::Int::Layout.new('content', {}, '/asdf')
16
16
  end
17
17
 
18
18
  let(:wrapped) do
@@ -22,21 +22,21 @@ describe Nanoc::MutableLayoutCollectionView do
22
22
  let(:view) { described_class.new(wrapped, nil) }
23
23
 
24
24
  it 'creates an object' do
25
- view.create('new content', { title: 'New Page' }, '/new/')
25
+ view.create('new content', { title: 'New Page' }, '/new')
26
26
 
27
27
  expect(view.unwrap.size).to eq(2)
28
- expect(view.unwrap['/new/'].content.string).to eq('new content')
28
+ expect(view.unwrap['/new'].content.string).to eq('new content')
29
29
  end
30
30
 
31
31
  it 'does not update wrapped' do
32
- view.create('new content', { title: 'New Page' }, '/new/')
32
+ view.create('new content', { title: 'New Page' }, '/new')
33
33
 
34
34
  expect(wrapped.size).to eq(1)
35
35
  expect(wrapped['/new']).to be_nil
36
36
  end
37
37
 
38
38
  it 'returns self' do
39
- ret = view.create('new content', { title: 'New Page' }, '/new/')
39
+ ret = view.create('new content', { title: 'New Page' }, '/new')
40
40
  expect(ret).to equal(view)
41
41
  end
42
42
  end
@@ -5,11 +5,11 @@ describe Nanoc::MutableLayoutView do
5
5
  it_behaves_like 'a mutable document view'
6
6
 
7
7
  describe '#inspect' do
8
- let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
8
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf') }
9
9
  let(:view) { described_class.new(item, nil) }
10
10
 
11
11
  subject { view.inspect }
12
12
 
13
- it { is_expected.to eql('<Nanoc::MutableLayoutView identifier=/asdf/>') }
13
+ it { is_expected.to eql('<Nanoc::MutableLayoutView identifier=/asdf>') }
14
14
  end
15
15
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  describe Nanoc::PostCompileItemRepView do
4
4
  let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) }
5
- let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo/') }
5
+ let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo') }
6
6
  let(:view) { described_class.new(item_rep, view_context) }
7
7
 
8
8
  let(:view_context) do
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Nanoc::CLI::CommandRunner, stdio: true do
4
+ describe '.find_site_dir' do
5
+ subject { described_class.find_site_dir }
6
+
7
+ context 'config file in current dir' do
8
+ before { File.write('nanoc.yaml', 'hi') }
9
+
10
+ it 'returns the current dir' do
11
+ expect(subject).to eq(File.expand_path(Dir.getwd))
12
+ end
13
+ end
14
+
15
+ context 'config file in parent dir' do
16
+ around do |ex|
17
+ FileUtils.mkdir_p('root/sub')
18
+ File.write('root/nanoc.yaml', 'hi')
19
+ chdir('root/sub') { ex.run }
20
+ end
21
+
22
+ it 'returns the parent dir' do
23
+ expect(subject).to match(/root$/)
24
+ end
25
+ end
26
+
27
+ context 'config file in grandparent dir' do
28
+ around do |ex|
29
+ FileUtils.mkdir_p('root/sub1/sub2')
30
+ File.write('root/nanoc.yaml', 'hi')
31
+ chdir('root/sub1/sub2') { ex.run }
32
+ end
33
+
34
+ it 'returns the parent dir' do
35
+ expect(subject).to match(/root$/)
36
+ end
37
+ end
38
+
39
+ context 'no config file in ancestral paths' do
40
+ it 'returns nil' do
41
+ expect(subject).to be_nil
42
+ end
43
+ end
44
+ end
45
+
46
+ describe '.enter_site_dir' do
47
+ subject do
48
+ described_class.enter_site_dir
49
+ Dir.getwd
50
+ end
51
+
52
+ context 'config file in current dir' do
53
+ before { File.write('nanoc.yaml', 'hi') }
54
+
55
+ it 'returns the current dir' do
56
+ expect(subject).to eq(File.expand_path(Dir.getwd))
57
+ end
58
+ end
59
+
60
+ context 'config file in parent dir' do
61
+ around do |ex|
62
+ FileUtils.mkdir_p('root/sub')
63
+ File.write('root/nanoc.yaml', 'hi')
64
+ chdir('root/sub') { ex.run }
65
+ end
66
+
67
+ it 'returns the parent dir' do
68
+ expect(subject).to match(/root$/)
69
+ end
70
+ end
71
+
72
+ context 'config file in grandparent dir' do
73
+ around do |ex|
74
+ FileUtils.mkdir_p('root/sub1/sub2')
75
+ File.write('root/nanoc.yaml', 'hi')
76
+ chdir('root/sub1/sub2') { ex.run }
77
+ end
78
+
79
+ it 'enters the parent dir' do
80
+ expect(subject).to match(/root$/)
81
+ end
82
+ end
83
+
84
+ context 'no config file in ancestral paths' do
85
+ it 'raises' do
86
+ expect { subject }.to raise_error(::Nanoc::Int::Errors::GenericTrivial, 'The current working directory, nor any of its parents, seems to be a Nanoc site.')
87
+ end
88
+ end
89
+ end
90
+ end
@@ -107,6 +107,7 @@ describe Nanoc::CLI::Commands::ShowRules, stdio: true do
107
107
 
108
108
  before do
109
109
  expect(compiler).to receive(:build_reps).once
110
+ expect(Nanoc::CLI::CommandRunner).to receive(:find_site_dir).and_return(Dir.getwd)
110
111
  end
111
112
 
112
113
  it 'writes item and layout rules to stdout' do
@@ -58,5 +58,18 @@ describe Nanoc::CLI::Commands::View, site: true, stdio: true do
58
58
  expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n")
59
59
  end
60
60
  end
61
+
62
+ it 'does not listen on non-local interfaces' do
63
+ addresses = Socket.getifaddrs.map(&:addr).select(&:ipv4?).map(&:ip_address)
64
+ non_local_addresses = addresses - ['127.0.0.1']
65
+
66
+ if non_local_addresses.empty?
67
+ skip 'Need non-local network interfaces for this spec'
68
+ end
69
+
70
+ run_nanoc_cmd(['view', '--port', '50385']) do
71
+ expect { Net::HTTP.get(non_local_addresses[0], '/', 50_385) }.to raise_error(Errno::ECONNREFUSED)
72
+ end
73
+ end
61
74
  end
62
75
  end
@@ -6,7 +6,7 @@ describe Nanoc::CLI do
6
6
  end
7
7
 
8
8
  let(:exceptions) do
9
- # FIXME: Get rid of these exceptions by Nanoc 5.0
9
+ # FIXME: [Nanoc 5] Get rid of these exceptions
10
10
  [
11
11
  ['deploy', ['C']],
12
12
  ['help', ['v']],
@@ -47,7 +47,7 @@ describe Nanoc::DataSources::Filesystem do
47
47
 
48
48
  expect(subject[0].content.string).to eq('test 1')
49
49
  expect(subject[0].attributes).to eq(expected_attributes)
50
- expect(subject[0].identifier).to eq(Nanoc::Identifier.new('/bar/'))
50
+ expect(subject[0].identifier).to eq(Nanoc::Identifier.new('/bar/', type: :legacy))
51
51
  expect(subject[0].checksum_data).to be_nil
52
52
  expect(subject[0].attributes_checksum_data).to be_a(String)
53
53
  expect(subject[0].attributes_checksum_data.size).to eq(20)
@@ -10,13 +10,13 @@ describe Nanoc::Helpers::Blogging, helper: true do
10
10
  subject { helper.articles }
11
11
 
12
12
  before do
13
- ctx.create_item('blah', { kind: 'item' }, '/0/')
14
- ctx.create_item('blah blah', { kind: 'article' }, '/1/')
15
- ctx.create_item('blah blah blah', { kind: 'article' }, '/2/')
13
+ ctx.create_item('blah', { kind: 'item' }, '/0')
14
+ ctx.create_item('blah blah', { kind: 'article' }, '/1')
15
+ ctx.create_item('blah blah blah', { kind: 'article' }, '/2')
16
16
  end
17
17
 
18
18
  it 'returns the two articles' do
19
- expect(subject.map(&:identifier)).to match_array(['/1/', '/2/'])
19
+ expect(subject.map(&:identifier)).to match_array(['/1', '/2'])
20
20
  end
21
21
  end
22
22
 
@@ -25,28 +25,28 @@ describe Nanoc::Helpers::Blogging, helper: true do
25
25
 
26
26
  before do
27
27
  attrs = { kind: 'item' }
28
- ctx.create_item('blah', attrs, '/0/')
28
+ ctx.create_item('blah', attrs, '/0')
29
29
 
30
30
  attrs = { kind: 'article', created_at: (Date.today - 1).to_s }
31
- ctx.create_item('blah blah', attrs, '/1/')
31
+ ctx.create_item('blah blah', attrs, '/1')
32
32
 
33
33
  attrs = { kind: 'article', created_at: (Time.now - 500).to_s }
34
- ctx.create_item('blah blah blah', attrs, '/2/')
34
+ ctx.create_item('blah blah blah', attrs, '/2')
35
35
  end
36
36
 
37
37
  it 'returns the two articles in descending order' do
38
- expect(subject.map(&:identifier)).to eq(['/2/', '/1/'])
38
+ expect(subject.map(&:identifier)).to eq(['/2', '/1'])
39
39
  end
40
40
  end
41
41
 
42
42
  describe '#url_for' do
43
- subject { helper.url_for(ctx.items['/stuff/']) }
43
+ subject { helper.url_for(ctx.items['/stuff']) }
44
44
 
45
45
  let(:item_attributes) { {} }
46
46
 
47
47
  before do
48
- ctx.create_item('Stuff', item_attributes, '/stuff/')
49
- ctx.create_rep(ctx.items['/stuff/'], '/rep/path/stuff.html')
48
+ ctx.create_item('Stuff', item_attributes, '/stuff')
49
+ ctx.create_rep(ctx.items['/stuff'], '/rep/path/stuff.html')
50
50
 
51
51
  ctx.config[:base_url] = base_url
52
52
  end
@@ -98,10 +98,10 @@ describe Nanoc::Helpers::Blogging, helper: true do
98
98
  let(:item_attributes) { {} }
99
99
 
100
100
  before do
101
- ctx.create_item('Feed', item_attributes, '/feed/')
102
- ctx.create_rep(ctx.items['/feed/'], '/feed.xml')
101
+ ctx.create_item('Feed', item_attributes, '/feed')
102
+ ctx.create_rep(ctx.items['/feed'], '/feed.xml')
103
103
 
104
- ctx.item = ctx.items['/feed/']
104
+ ctx.item = ctx.items['/feed']
105
105
  ctx.config[:base_url] = base_url
106
106
  end
107
107
 
@@ -166,15 +166,15 @@ describe Nanoc::Helpers::Blogging, helper: true do
166
166
  end
167
167
 
168
168
  describe '#atom_tag_for' do
169
- subject { helper.atom_tag_for(ctx.items['/stuff/']) }
169
+ subject { helper.atom_tag_for(ctx.items['/stuff']) }
170
170
 
171
171
  let(:item_attributes) { { created_at: '2015-05-19 12:34:56' } }
172
172
  let(:item_rep_path) { '/stuff.xml' }
173
173
  let(:base_url) { 'http://url.base' }
174
174
 
175
175
  before do
176
- ctx.create_item('Stuff', item_attributes, '/stuff/')
177
- ctx.create_rep(ctx.items['/stuff/'], item_rep_path)
176
+ ctx.create_item('Stuff', item_attributes, '/stuff')
177
+ ctx.create_rep(ctx.items['/stuff'], item_rep_path)
178
178
 
179
179
  ctx.config[:base_url] = base_url
180
180
  end
@@ -186,7 +186,7 @@ describe Nanoc::Helpers::Blogging, helper: true do
186
186
 
187
187
  context 'item without path' do
188
188
  let(:item_rep_path) { nil }
189
- it { is_expected.to eql('tag:url.base,2015-05-19:/stuff/') }
189
+ it { is_expected.to eql('tag:url.base,2015-05-19:/stuff') }
190
190
  end
191
191
 
192
192
  context 'bare URL without subdir' do