nanoc 4.1.6 → 4.2.0b1

Sign up to get free protection for your applications and to get access to all the features.
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