nanoc 4.1.6 → 4.2.0b1

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -1
  4. data/NEWS.md +11 -4
  5. data/lib/nanoc/base/checksummer.rb +135 -46
  6. data/lib/nanoc/base/compilation/compiler.rb +18 -28
  7. data/lib/nanoc/base/compilation/dependency_tracker.rb +22 -32
  8. data/lib/nanoc/base/compilation/filter.rb +2 -4
  9. data/lib/nanoc/base/entities.rb +1 -0
  10. data/lib/nanoc/base/entities/content.rb +14 -3
  11. data/lib/nanoc/base/entities/document.rb +14 -6
  12. data/lib/nanoc/base/entities/item.rb +0 -31
  13. data/lib/nanoc/base/entities/item_rep.rb +1 -1
  14. data/lib/nanoc/base/entities/lazy_value.rb +36 -0
  15. data/lib/nanoc/base/entities/pattern.rb +3 -2
  16. data/lib/nanoc/base/entities/site.rb +2 -0
  17. data/lib/nanoc/base/memoization.rb +17 -10
  18. data/lib/nanoc/base/repos/compiled_content_cache.rb +1 -1
  19. data/lib/nanoc/base/repos/data_source.rb +10 -6
  20. data/lib/nanoc/base/services/executor.rb +22 -22
  21. data/lib/nanoc/base/services/item_rep_router.rb +4 -5
  22. data/lib/nanoc/base/views.rb +0 -1
  23. data/lib/nanoc/base/views/item_rep_view.rb +3 -9
  24. data/lib/nanoc/base/views/mixins/document_view_mixin.rb +4 -11
  25. data/lib/nanoc/base/views/view.rb +1 -0
  26. data/lib/nanoc/base/views/view_context.rb +5 -1
  27. data/lib/nanoc/cli/commands/compile.rb +0 -6
  28. data/lib/nanoc/data_sources.rb +5 -5
  29. data/lib/nanoc/data_sources/filesystem.rb +219 -90
  30. data/lib/nanoc/extra/checking/check.rb +1 -2
  31. data/lib/nanoc/extra/checking/checks.rb +2 -0
  32. data/lib/nanoc/extra/checking/checks/css.rb +6 -14
  33. data/lib/nanoc/extra/checking/checks/html.rb +6 -14
  34. data/lib/nanoc/extra/checking/checks/internal_links.rb +14 -3
  35. data/lib/nanoc/extra/checking/checks/w3c_validator.rb +28 -0
  36. data/lib/nanoc/extra/deployers/fog.rb +134 -78
  37. data/lib/nanoc/extra/link_collector.rb +14 -18
  38. data/lib/nanoc/filters/sass.rb +3 -3
  39. data/lib/nanoc/helpers.rb +1 -0
  40. data/lib/nanoc/helpers/capturing.rb +16 -58
  41. data/lib/nanoc/helpers/child_parent.rb +51 -0
  42. data/lib/nanoc/helpers/filtering.rb +0 -1
  43. data/lib/nanoc/helpers/html_escape.rb +5 -0
  44. data/lib/nanoc/helpers/link_to.rb +2 -0
  45. data/lib/nanoc/helpers/rendering.rb +3 -4
  46. data/lib/nanoc/rule_dsl/action_provider.rb +20 -4
  47. data/lib/nanoc/rule_dsl/recording_executor.rb +3 -1
  48. data/lib/nanoc/rule_dsl/rule_context.rb +0 -1
  49. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +4 -1
  50. data/lib/nanoc/spec.rb +217 -0
  51. data/lib/nanoc/version.rb +1 -1
  52. data/test/base/test_data_source.rb +4 -2
  53. data/test/base/test_dependency_tracker.rb +5 -11
  54. data/test/data_sources/test_filesystem.rb +605 -69
  55. data/test/extra/checking/checks/test_internal_links.rb +25 -0
  56. data/test/extra/deployers/test_fog.rb +0 -177
  57. data/test/filters/test_less.rb +9 -4
  58. data/test/helpers/test_capturing.rb +38 -212
  59. data/test/helpers/test_link_to.rb +0 -205
  60. data/test/helpers/test_xml_sitemap.rb +2 -1
  61. metadata +7 -12
  62. data/lib/nanoc/base/views/site_view.rb +0 -14
  63. data/lib/nanoc/data_sources/filesystem_unified.rb +0 -101
  64. data/test/data_sources/test_filesystem_unified.rb +0 -559
  65. data/test/helpers/test_breadcrumbs.rb +0 -60
  66. data/test/helpers/test_filtering.rb +0 -112
  67. data/test/helpers/test_html_escape.rb +0 -26
  68. data/test/helpers/test_rendering.rb +0 -147
  69. data/test/helpers/test_tagging.rb +0 -92
  70. data/test/helpers/test_text.rb +0 -18
@@ -1,60 +0,0 @@
1
- class Nanoc::Helpers::BreadcrumbsTest < Nanoc::TestCase
2
- include Nanoc::Helpers::Breadcrumbs
3
-
4
- def test_breadcrumbs_trail_at_root
5
- @items = Nanoc::Int::IdentifiableCollection.new({})
6
- item = Nanoc::Int::Item.new('root', {}, Nanoc::Identifier.new('/', type: :legacy))
7
- @items << item
8
- @item = item
9
-
10
- assert_equal [item], breadcrumbs_trail
11
- end
12
-
13
- def test_breadcrumbs_trail_with_1_parent
14
- @items = Nanoc::Int::IdentifiableCollection.new({})
15
- parent_item = Nanoc::Int::Item.new('parent', {}, Nanoc::Identifier.new('/', type: :legacy))
16
- child_item = Nanoc::Int::Item.new('child', {}, Nanoc::Identifier.new('/foo/', type: :legacy))
17
- @items << parent_item
18
- @items << child_item
19
- @item = child_item
20
-
21
- assert_equal [parent_item, child_item], breadcrumbs_trail
22
- end
23
-
24
- def test_breadcrumbs_trail_with_many_parents
25
- @items = Nanoc::Int::IdentifiableCollection.new({})
26
- grandparent_item = Nanoc::Int::Item.new('grandparent', {}, Nanoc::Identifier.new('/', type: :legacy))
27
- parent_item = Nanoc::Int::Item.new('parent', {}, Nanoc::Identifier.new('/foo/', type: :legacy))
28
- child_item = Nanoc::Int::Item.new('child', {}, Nanoc::Identifier.new('/foo/bar/', type: :legacy))
29
- @items << grandparent_item
30
- @items << parent_item
31
- @items << child_item
32
- @item = child_item
33
-
34
- assert_equal [grandparent_item, parent_item, child_item], breadcrumbs_trail
35
- end
36
-
37
- def test_breadcrumbs_trail_with_nils
38
- @items = Nanoc::Int::IdentifiableCollection.new({})
39
- grandparent_item = Nanoc::Int::Item.new('grandparent', {}, Nanoc::Identifier.new('/', type: :legacy))
40
- child_item = Nanoc::Int::Item.new('child', {}, Nanoc::Identifier.new('/foo/bar/', type: :legacy))
41
- @items << grandparent_item
42
- @items << child_item
43
- @item = child_item
44
-
45
- assert_equal [grandparent_item, nil, child_item], breadcrumbs_trail
46
- end
47
-
48
- def test_breadcrumbs_trail_with_non_legacy_identifiers
49
- @items = Nanoc::Int::IdentifiableCollection.new({})
50
- parent_item = Nanoc::Int::Item.new('parent', {}, '/')
51
- child_item = Nanoc::Int::Item.new('child', {}, '/foo/')
52
- @items << parent_item
53
- @items << child_item
54
- @item = child_item
55
-
56
- assert_raises Nanoc::Helpers::Breadcrumbs::CannotGetBreadcrumbsForNonLegacyItem do
57
- breadcrumbs_trail
58
- end
59
- end
60
- end
@@ -1,112 +0,0 @@
1
- class Nanoc::Helpers::FilteringTest < Nanoc::TestCase
2
- include Nanoc::Helpers::Filtering
3
-
4
- def test_filter_simple
5
- if_have 'rubypants' do
6
- # Build content to be evaluated
7
- content = "<p>Foo...</p>\n" \
8
- "<% filter :rubypants do %>\n" \
9
- " <p>Bar...</p>\n" \
10
- "<% end %>\n"
11
-
12
- # Mock item and rep
13
- @item_rep = mock
14
- @item_rep = Nanoc::ItemRepView.new(@item_rep, nil)
15
-
16
- # Evaluate content
17
- result = ::ERB.new(content).result(binding)
18
-
19
- # Check
20
- assert_match('<p>Foo...</p>', result)
21
- assert_match('<p>Bar&#8230;</p>', result)
22
- end
23
- end
24
-
25
- def test_filter_with_assigns
26
- if_have 'rubypants' do
27
- content = "<p>Foo...</p>\n" \
28
- "<% filter :erb do %>\n" \
29
- " <p><%%= @item[:title] %></p>\n" \
30
- "<% end %>\n"
31
-
32
- item = Nanoc::Int::Item.new('stuff', { title: 'Bar...' }, '/foo.md')
33
- item_rep = Nanoc::Int::ItemRep.new(item, :default)
34
-
35
- @item = Nanoc::ItemWithRepsView.new(item, nil)
36
- @item_rep = Nanoc::ItemRepView.new(item_rep, nil)
37
-
38
- result = ::ERB.new(content).result(binding)
39
-
40
- assert_match('<p>Foo...</p>', result)
41
- assert_match('<p>Bar...</p>', result)
42
- end
43
- end
44
-
45
- def test_filter_with_unknown_filter_name
46
- # Build content to be evaluated
47
- content = "<p>Foo...</p>\n" \
48
- "<% filter :askjdflkawgjlkwaheflnvz do %>\n" \
49
- " <p>Blah blah blah.</p>\n" \
50
- "<% end %>\n"
51
-
52
- # Evaluate content
53
- assert_raises(Nanoc::Int::Errors::UnknownFilter) do
54
- ::ERB.new(content).result(binding)
55
- end
56
- end
57
-
58
- def test_filter_with_arguments
59
- if_have 'coderay' do
60
- # Build content to be evaluated
61
- content = "<% filter :erb, locals: { sheep: 'baah' } do %>\n" \
62
- " Sheep says <%%= @sheep %>!\n" \
63
- "<% end %>\n"
64
-
65
- # Mock item and rep
66
- @item_rep = mock
67
- @item_rep = Nanoc::ItemRepView.new(@item_rep, nil)
68
-
69
- # Evaluate content
70
- result = ::ERB.new(content).result(binding)
71
- assert_match(%r{Sheep says baah!}, result)
72
- end
73
- end
74
-
75
- def test_with_haml
76
- if_have 'haml' do
77
- # Build content to be evaluated
78
- content = "%p Foo.\n" \
79
- "- filter(:erb) do\n" \
80
- " <%= 'abc' + 'xyz' %>\n" \
81
- "%p Bar.\n"
82
-
83
- # Mock item and rep
84
- @item_rep = mock
85
- @item_rep = Nanoc::ItemRepView.new(@item_rep, nil)
86
-
87
- # Evaluate content
88
- result = ::Haml::Engine.new(content).render(binding)
89
- assert_match(%r{^<p>Foo.</p>\s*abcxyz\s*<p>Bar.</p>$}, result)
90
- end
91
- end
92
-
93
- def test_notifications
94
- notifications = Set.new
95
- Nanoc::Int::NotificationCenter.on(:filtering_started) { notifications << :filtering_started }
96
- Nanoc::Int::NotificationCenter.on(:filtering_ended) { notifications << :filtering_ended }
97
-
98
- # Build content to be evaluated
99
- content = "<% filter :erb do %>\n" \
100
- " ... stuff ...\n" \
101
- "<% end %>\n"
102
-
103
- # Mock item and rep
104
- @item_rep = mock
105
- @item_rep = Nanoc::ItemRepView.new(@item_rep, nil)
106
-
107
- ::ERB.new(content).result(binding)
108
-
109
- assert notifications.include?(:filtering_started)
110
- assert notifications.include?(:filtering_ended)
111
- end
112
- end
@@ -1,26 +0,0 @@
1
- class Nanoc::Helpers::HTMLEscapeTest < Nanoc::TestCase
2
- include Nanoc::Helpers::HTMLEscape
3
-
4
- def test_html_escape_with_string
5
- assert_equal('&lt;', html_escape('<'))
6
- assert_equal('&gt;', html_escape('>'))
7
- assert_equal('&amp;', html_escape('&'))
8
- assert_equal('&quot;', html_escape('"'))
9
- end
10
-
11
- def test_html_escape_with_block
12
- _erbout = 'moo'
13
-
14
- html_escape do
15
- _erbout << '<h1>Looks like a header</h1>'
16
- end
17
-
18
- assert_equal 'moo&lt;h1&gt;Looks like a header&lt;/h1&gt;', _erbout
19
- end
20
-
21
- def test_html_escape_without_string_or_block
22
- assert_raises RuntimeError do
23
- h
24
- end
25
- end
26
- end
@@ -1,147 +0,0 @@
1
- class Nanoc::Helpers::RenderingTest < Nanoc::TestCase
2
- include Nanoc::Helpers::Rendering
3
-
4
- def test_render
5
- with_site do |site|
6
- File.open('Rules', 'w') do |io|
7
- io.write("layout '/foo/', :erb\n")
8
- end
9
-
10
- File.open('layouts/foo.erb', 'w') do |io|
11
- io.write 'This is the <%= @layout.identifier %> layout.'
12
- end
13
-
14
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
15
- @site = Nanoc::SiteView.new(site, nil)
16
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
17
-
18
- assert_equal('This is the /foo/ layout.', render('/foo/'))
19
- end
20
- end
21
-
22
- def test_render_with_non_cleaned_identifier
23
- with_site do |site|
24
- File.open('Rules', 'w') do |io|
25
- io.write("layout '/foo/', :erb\n")
26
- end
27
-
28
- File.open('layouts/foo.erb', 'w') do |io|
29
- io.write 'This is the <%= @layout.identifier %> layout.'
30
- end
31
-
32
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
33
- @site = Nanoc::SiteView.new(site, nil)
34
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
35
-
36
- assert_equal('This is the /foo/ layout.', render('/foo'))
37
- end
38
- end
39
-
40
- def test_render_class
41
- with_site do |site|
42
- File.open('Rules', 'w') do |io|
43
- io.write("layout '/foo/', :erb\n")
44
- end
45
-
46
- File.open('layouts/foo.erb', 'w') do |io|
47
- io.write 'I am the <%= @layout.class %> class.'
48
- end
49
-
50
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
51
- @site = Nanoc::SiteView.new(site, nil)
52
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
53
-
54
- assert_equal('I am the Nanoc::LayoutView class.', render('/foo/'))
55
- end
56
- end
57
-
58
- def test_render_wrapped_class
59
- with_site do |site|
60
- File.open('Rules', 'w') do |io|
61
- io.write("layout '/foo/', :erb\n")
62
- end
63
-
64
- File.open('layouts/foo.erb', 'w') do |io|
65
- io.write 'I am the <%= @layout.unwrap.class %> class.'
66
- end
67
-
68
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
69
- @site = Nanoc::SiteView.new(site, nil)
70
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
71
-
72
- assert_equal('I am the Nanoc::Int::Layout class.', render('/foo/'))
73
- end
74
- end
75
-
76
- def test_render_with_unknown_layout
77
- with_site do |site|
78
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
79
- @site = Nanoc::SiteView.new(site, nil)
80
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
81
-
82
- assert_raises(Nanoc::Int::Errors::UnknownLayout) do
83
- render '/dsfghjkl/'
84
- end
85
- end
86
- end
87
-
88
- def test_render_without_filter
89
- with_site do |site|
90
- File.open('Rules', 'w') do |io|
91
- io.write("layout '/foo/', nil\n")
92
- end
93
-
94
- File.open('layouts/foo.erb', 'w').close
95
-
96
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
97
- @site = Nanoc::SiteView.new(site, nil)
98
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
99
-
100
- assert_raises(Nanoc::Int::Errors::CannotDetermineFilter) do
101
- render '/foo/'
102
- end
103
- end
104
- end
105
-
106
- def test_render_with_unknown_filter
107
- with_site do |site|
108
- File.open('Rules', 'w') do |io|
109
- io.write("layout '/foo/', :asdf\n")
110
- end
111
-
112
- File.open('layouts/foo.erb', 'w').close
113
-
114
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
115
- @site = Nanoc::SiteView.new(site, nil)
116
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
117
-
118
- assert_raises(Nanoc::Int::Errors::UnknownFilter) do
119
- render '/foo/'
120
- end
121
- end
122
- end
123
-
124
- def test_render_with_block
125
- with_site do |site|
126
- File.open('Rules', 'w') do |io|
127
- io.write("layout '/foo/', :erb\n")
128
- end
129
-
130
- File.open('layouts/foo.erb', 'w') do |io|
131
- io.write '[partial-before]<%= yield %>[partial-after]'
132
- end
133
-
134
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
135
- @site = Nanoc::SiteView.new(site, nil)
136
- @layouts = Nanoc::LayoutCollectionView.new(site.layouts, nil)
137
-
138
- _erbout = '[erbout-before]'
139
- result = render '/foo/' do
140
- _erbout << 'This is some extra content'
141
- end
142
-
143
- assert_equal('[erbout-before][partial-before]This is some extra content[partial-after]', _erbout)
144
- assert_equal '', result
145
- end
146
- end
147
- end
@@ -1,92 +0,0 @@
1
- class Nanoc::Helpers::TaggingTest < Nanoc::TestCase
2
- include Nanoc::Helpers::Tagging
3
-
4
- def test_tags_for_without_tags
5
- # Create item
6
- item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('content', {}, '/path/'), nil)
7
-
8
- # Check
9
- assert_equal(
10
- '(none)',
11
- tags_for(item, base_url: 'http://example.com/tag/'),
12
- )
13
- end
14
-
15
- def test_tags_for_with_custom_base_url
16
- # Create item
17
- item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('content', { tags: %w(foo bar) }, '/path/'), nil)
18
-
19
- # Check
20
- assert_equal(
21
- "#{link_for_tag('foo', 'http://stoneship.org/tag/')}, " \
22
- "#{link_for_tag('bar', 'http://stoneship.org/tag/')}",
23
- tags_for(item, base_url: 'http://stoneship.org/tag/'),
24
- )
25
- end
26
-
27
- def test_tags_for_with_custom_none_text
28
- # Create item
29
- item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('content', { tags: [] }, '/path/'), nil)
30
-
31
- # Check
32
- assert_equal(
33
- 'no tags for you, fool',
34
- tags_for(item, none_text: 'no tags for you, fool', base_url: 'http://example.com/tag/'),
35
- )
36
- end
37
-
38
- def test_tags_for_with_custom_separator
39
- # Create item
40
- item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('content', { tags: %w(foo bar) }, '/path/'), nil)
41
-
42
- # Check
43
- assert_equal(
44
- "#{link_for_tag('foo', 'http://example.com/tag/')} ++ " \
45
- "#{link_for_tag('bar', 'http://example.com/tag/')}",
46
- tags_for(item, separator: ' ++ ', base_url: 'http://example.com/tag/'),
47
- )
48
- end
49
-
50
- def test_tags_for_without_base_url
51
- # Create item
52
- item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('content', { tags: %w(foo bar) }, '/path/'), nil)
53
-
54
- # Check
55
- assert_equal('foo, bar', tags_for(item))
56
- end
57
-
58
- def test_items_with_tag
59
- # Create items
60
- @items = Nanoc::ItemCollectionWithRepsView.new(
61
- [
62
- Nanoc::Int::Item.new('item 1', { tags: [:foo] }, '/item1/'),
63
- Nanoc::Int::Item.new('item 2', { tags: [:bar] }, '/item2/'),
64
- Nanoc::Int::Item.new('item 3', { tags: [:foo, :bar] }, '/item3/'),
65
- ],
66
- nil,
67
- )
68
-
69
- # Find items
70
- items_with_foo_tag = items_with_tag(:foo)
71
-
72
- # Check
73
- assert_equal(
74
- [@items[0], @items[2]],
75
- items_with_foo_tag,
76
- )
77
- end
78
-
79
- def test_link_for_tag
80
- assert_equal(
81
- %(<a href="http://stoneship.org/tags/foobar" rel="tag">foobar</a>),
82
- link_for_tag('foobar', 'http://stoneship.org/tags/'),
83
- )
84
- end
85
-
86
- def test_link_for_tag_escape
87
- assert_equal(
88
- %(<a href="http://stoneship.org/tags&amp;stuff/foo&amp;bar" rel="tag">foo&amp;bar</a>),
89
- link_for_tag('foo&bar', 'http://stoneship.org/tags&stuff/'),
90
- )
91
- end
92
- end
@@ -1,18 +0,0 @@
1
- class Nanoc::Helpers::TextTest < Nanoc::TestCase
2
- include Nanoc::Helpers::Text
3
-
4
- def test_excerpt_length
5
- assert_equal('...', excerptize('Foo bar baz quux meow woof', length: 3))
6
- assert_equal('Foo ...', excerptize('Foo bar baz quux meow woof', length: 7))
7
- assert_equal('Foo bar baz quux meow woof', excerptize('Foo bar baz quux meow woof', length: 26))
8
- assert_equal('Foo bar baz quux meow woof', excerptize('Foo bar baz quux meow woof', length: 8_623_785))
9
- end
10
-
11
- def test_excerpt_omission
12
- assert_equal('Foo [continued]', excerptize('Foo bar baz quux meow woof', length: 15, omission: '[continued]'))
13
- end
14
-
15
- def test_strip_html
16
- # TODO: implement
17
- end
18
- end