nanoc 3.7.5 → 3.8.0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +2 -2
  3. data/Gemfile +1 -1
  4. data/NEWS.md +24 -3
  5. data/README.md +1 -1
  6. data/bin/nanoc +1 -1
  7. data/lib/nanoc/base/compilation/dependency_tracker.rb +1 -1
  8. data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +1 -1
  9. data/lib/nanoc/base/compilation/rule.rb +15 -1
  10. data/lib/nanoc/base/result_data/item_rep.rb +27 -10
  11. data/lib/nanoc/base/source_data/item_array.rb +2 -0
  12. data/lib/nanoc/base/source_data/site.rb +1 -0
  13. data/lib/nanoc/cli.rb +16 -7
  14. data/lib/nanoc/cli/commands/autocompile.rb +1 -1
  15. data/lib/nanoc/cli/commands/create-site.rb +2 -2
  16. data/lib/nanoc/cli/commands/show-rules.rb +3 -6
  17. data/lib/nanoc/cli/commands/watch.rb +3 -3
  18. data/lib/nanoc/cli/error_handler.rb +1 -1
  19. data/lib/nanoc/cli/logger.rb +3 -5
  20. data/lib/nanoc/data_sources/filesystem.rb +2 -2
  21. data/lib/nanoc/extra/auto_compiler.rb +1 -1
  22. data/lib/nanoc/extra/checking/checks.rb +2 -0
  23. data/lib/nanoc/extra/checking/checks/mixed_content.rb +31 -0
  24. data/lib/nanoc/extra/deployers/fog.rb +24 -0
  25. data/lib/nanoc/extra/link_collector.rb +42 -9
  26. data/lib/nanoc/extra/pruner.rb +1 -1
  27. data/lib/nanoc/filters/colorize_syntax.rb +4 -4
  28. data/lib/nanoc/filters/pandoc.rb +23 -4
  29. data/lib/nanoc/filters/sass/sass_filesystem_importer.rb +4 -2
  30. data/lib/nanoc/helpers/blogging.rb +17 -6
  31. data/lib/nanoc/helpers/tagging.rb +1 -1
  32. data/lib/nanoc/helpers/text.rb +1 -1
  33. data/lib/nanoc/version.rb +1 -1
  34. data/tasks/test.rake +1 -1
  35. data/test/base/test_item_array.rb +8 -0
  36. data/test/base/test_item_rep.rb +51 -0
  37. data/test/base/test_item_rep_recorder_proxy.rb +19 -0
  38. data/test/base/test_rule.rb +10 -0
  39. data/test/cli/commands/test_create_site.rb +13 -0
  40. data/test/cli/test_cli.rb +30 -0
  41. data/test/extra/checking/checks/test_mixed_content.rb +188 -0
  42. data/test/extra/deployers/test_fog.rb +32 -0
  43. data/test/filters/test_pandoc.rb +17 -3
  44. data/test/filters/test_sass.rb +11 -0
  45. data/test/helper.rb +3 -3
  46. data/test/helpers/test_blogging.rb +30 -0
  47. metadata +6 -3
@@ -18,6 +18,19 @@ class Nanoc::CLI::Commands::CreateSiteTest < Nanoc::TestCase
18
18
  end
19
19
  end
20
20
 
21
+ def test_can_compile_new_site_with_binary_items
22
+ Nanoc::CLI.run %w( create_site foo )
23
+
24
+ FileUtils.cd('foo') do
25
+ File.open('content/blah', 'w') { |io| io << 'asdf' }
26
+ site = Nanoc::Site.new('.')
27
+ site.load_data
28
+ site.compile
29
+
30
+ assert File.file?('output/blah')
31
+ end
32
+ end
33
+
21
34
  def test_default_encoding
22
35
  unless defined?(Encoding)
23
36
  skip 'No Encoding class'
data/test/cli/test_cli.rb CHANGED
@@ -74,6 +74,36 @@ EOS
74
74
  end
75
75
  end
76
76
 
77
+ def test_load_custom_commands_non_default_commands_dirs
78
+ Nanoc::CLI.run %w( create_site foo )
79
+ FileUtils.cd('foo') do
80
+ File.open('nanoc.yaml', 'w') { |io| io.write('commands_dirs: [commands, commands_alt]') }
81
+
82
+ # Create command
83
+ FileUtils.mkdir_p('commands_alt')
84
+ File.open('commands_alt/_test.rb', 'w') do |io|
85
+ io.write(COMMAND_CODE)
86
+ end
87
+
88
+ # Create subcommand
89
+ FileUtils.mkdir_p('commands_alt/_test')
90
+ File.open('commands_alt/_test/_sub.rb', 'w') do |io|
91
+ io.write(SUBCOMMAND_CODE)
92
+ end
93
+
94
+ # Run command
95
+ begin
96
+ Nanoc::CLI.run %w( _test _sub )
97
+ rescue SystemExit
98
+ assert false, 'Running _test sub should not cause system exit'
99
+ end
100
+
101
+ # Check
102
+ assert File.file?('_test_sub.out')
103
+ assert_equal 'It works sub!', File.read('_test_sub.out')
104
+ end
105
+ end
106
+
77
107
  def test_load_custom_commands_broken
78
108
  Nanoc::CLI.run %w( create_site foo )
79
109
 
@@ -0,0 +1,188 @@
1
+ # encoding: utf-8
2
+
3
+ class Nanoc::Extra::Checking::Checks::MixedContentTest < Nanoc::TestCase
4
+ def create_output_file(name, lines)
5
+ FileUtils.mkdir_p('output')
6
+ File.open('output/' + name, 'w') { |io|
7
+ io.write(lines.join('\n'))
8
+ }
9
+ end
10
+
11
+ def assert_include(haystack, needle)
12
+ assert haystack.include?(needle), "Expected to find '#{needle}' in #{haystack}"
13
+ end
14
+
15
+ def test_https_content
16
+ with_site do |site|
17
+ create_output_file('foo.html', [
18
+ '<img src="https://nanoc.ws/logo.png" />',
19
+ '<img src="HTTPS://nanoc.ws/logo.png" />',
20
+ '<link href="https://nanoc.ws/style.css" />',
21
+ '<script src="https://nanoc.ws/app.js"></script>',
22
+ '<form action="https://nanoc.ws/process.cgi"></form>',
23
+ '<iframe src="https://nanoc.ws/preview.html"></iframe>',
24
+ '<audio src="https://nanoc.ws/theme-song.flac"></audio>',
25
+ '<video src="https://nanoc.ws/screen-cast.mkv"></video>'
26
+ ])
27
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
28
+ check.run
29
+
30
+ assert check.issues.empty?
31
+ end
32
+ end
33
+
34
+ def test_root_relative_content
35
+ with_site do |site|
36
+ create_output_file('foo.html', [
37
+ '<img src="/logo.png" />',
38
+ '<link href="/style.css" />',
39
+ '<script src="/app.js"></script>',
40
+ '<form action="/process.cgi"></form>',
41
+ '<iframe src="/preview.html"></iframe>',
42
+ '<audio src="/theme-song.flac"></audio>',
43
+ '<video src="/screen-cast.mkv"></video>'
44
+ ])
45
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
46
+ check.run
47
+
48
+ assert check.issues.empty?
49
+ end
50
+ end
51
+
52
+ def test_protocol_relative_content
53
+ with_site do |site|
54
+ create_output_file('foo.html', [
55
+ '<img src="//nanoc.ws/logo.png" />',
56
+ '<link href="//nanoc.ws/style.css" />',
57
+ '<script src="//nanoc.ws/app.js"></script>',
58
+ '<form action="//nanoc.ws/process.cgi"></form>',
59
+ '<iframe src="//nanoc.ws/preview.html"></iframe>',
60
+ '<audio src="//nanoc.ws/theme-song.flac"></audio>',
61
+ '<video src="//nanoc.ws/screen-cast.mkv"></video>'
62
+ ])
63
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
64
+ check.run
65
+
66
+ assert check.issues.empty?
67
+ end
68
+ end
69
+
70
+ def test_document_relative_content
71
+ with_site do |site|
72
+ create_output_file('foo.html', [
73
+ '<img src="logo.png" />',
74
+ '<link href="style.css" />',
75
+ '<script src="app.js"></script>',
76
+ '<form action="process.cgi"></form>',
77
+ '<iframe src="preview.html"></iframe>',
78
+ '<audio src="theme-song.flac"></audio>',
79
+ '<video src="screen-cast.mkv"></video>'
80
+ ])
81
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
82
+ check.run
83
+
84
+ assert check.issues.empty?
85
+ end
86
+ end
87
+
88
+ def test_query_relative_content
89
+ with_site do |site|
90
+ create_output_file('foo.html', [
91
+ '<img src="?query-string" />',
92
+ '<link href="?query-string" />',
93
+ '<script src="?query-string"></script>',
94
+ '<form action="?query-string"></form>',
95
+ '<iframe src="?query-string"></iframe>',
96
+ '<audio src="?query-string"></audio>',
97
+ '<video src="?query-string"></video>'
98
+ ])
99
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
100
+ check.run
101
+
102
+ assert check.issues.empty?
103
+ end
104
+ end
105
+
106
+ def test_fragment_relative_content
107
+ with_site do |site|
108
+ create_output_file('foo.html', [
109
+ '<img src="#fragment" />',
110
+ '<link href="#fragment" />',
111
+ '<script src="#fragment"></script>',
112
+ '<form action="#fragment"></form>',
113
+ '<iframe src="#fragment"></iframe>',
114
+ '<audio src="#fragment"></audio>',
115
+ '<video src="#fragment"></video>'
116
+ ])
117
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
118
+ check.run
119
+
120
+ assert check.issues.empty?
121
+ end
122
+ end
123
+
124
+ def test_http_content
125
+ with_site do |site|
126
+ create_output_file('foo.html', [
127
+ '<img src="http://nanoc.ws/logo.png" />',
128
+ '<img src="HTTP://nanoc.ws/logo.png" />',
129
+ '<link href="http://nanoc.ws/style.css" />',
130
+ '<script src="http://nanoc.ws/app.js"></script>',
131
+ '<form action="http://nanoc.ws/process.cgi"></form>',
132
+ '<iframe src="http://nanoc.ws/preview.html"></iframe>',
133
+ '<audio src="http://nanoc.ws/theme-song.flac"></audio>',
134
+ '<video src="http://nanoc.ws/screencast.mkv"></video>'
135
+ ])
136
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
137
+ check.run
138
+
139
+ issues = check.issues.to_a
140
+ assert_equal 8, issues.count
141
+
142
+ descriptions = issues.map { |issue| issue.description }
143
+ issues.each do |issue|
144
+ assert_equal 'output/foo.html', issue.subject
145
+ end
146
+
147
+ # The order of the reported issues is not important, so use this class's
148
+ # `assert_include` helper to avoid asserting those details
149
+ assert_include descriptions, 'mixed content include: http://nanoc.ws/logo.png'
150
+
151
+ assert_include descriptions, 'mixed content include: HTTP://nanoc.ws/logo.png'
152
+
153
+ assert_include descriptions, 'mixed content include: http://nanoc.ws/style.css'
154
+
155
+ assert_include descriptions, 'mixed content include: http://nanoc.ws/app.js'
156
+
157
+ assert_include descriptions, 'mixed content include: http://nanoc.ws/process.cgi'
158
+
159
+ assert_include descriptions, 'mixed content include: http://nanoc.ws/preview.html'
160
+
161
+ assert_include descriptions, 'mixed content include: http://nanoc.ws/theme-song.flac'
162
+
163
+ assert_include descriptions, 'mixed content include: http://nanoc.ws/screencast.mkv'
164
+ end
165
+ end
166
+
167
+ def test_inert_content
168
+ with_site do |site|
169
+ create_output_file('foo.html', [
170
+ '<a href="http://nanoc.ws">The homepage</a>',
171
+ '<a name="Not a link">Content</a>',
172
+ '<script>// inline JavaScript</script>',
173
+ '<img href="http://nanoc.ws/logo.png" />',
174
+ '<link src="http://nanoc.ws/style.css" />',
175
+ '<script href="http://nanoc.ws/app.js"></script>',
176
+ '<form src="http://nanoc.ws/process.cgi"></form>',
177
+ '<iframe href="http://nanoc.ws/preview.html"></iframe>',
178
+ '<audio href="http://nanoc.ws/theme-song.flac"></audio>',
179
+ '<video target="http://nanoc.ws/screen-cast.mkv"></video>',
180
+ '<p>http://nanoc.ws/harmless-text</p>'
181
+ ])
182
+ check = Nanoc::Extra::Checking::Checks::MixedContent.new(site)
183
+ check.run
184
+
185
+ assert check.issues.empty?
186
+ end
187
+ end
188
+ end
@@ -61,6 +61,38 @@ class Nanoc::Extra::Deployers::FogTest < Nanoc::TestCase
61
61
  end
62
62
  end
63
63
 
64
+ def test_run_cdn_with_dry_run
65
+ if_have 'fog' do
66
+ begin
67
+ # Create deployer
68
+ fog = Nanoc::Extra::Deployers::Fog.new(
69
+ 'output/',
70
+ {
71
+ :provider => 'aws',
72
+ :cdn_id => 'id-cdn',
73
+ # FIXME bucket is necessary for deployer but fog doesn't like it
74
+ :bucket_name => 'doesntmatter',
75
+ :aws_access_key_id => 'meh',
76
+ :aws_secret_access_key => 'dontcare'},
77
+ :dry_run => true)
78
+
79
+ # Create site
80
+ FileUtils.mkdir_p('output')
81
+ File.open('output/meow', 'w') { |io| io.write "I am a cat!" }
82
+ File.open('output/bark', 'w') { |io| io.write "I am a dog!" }
83
+
84
+ # Create local cloud (but not bucket)
85
+ FileUtils.mkdir_p('mylocalcloud')
86
+
87
+ # Run
88
+ fog.run
89
+ ensure
90
+ # Hack :(
91
+ ::Fog.instance_eval { @mocking = false }
92
+ end
93
+ end
94
+ end
95
+
64
96
  def test_run_delete_stray
65
97
  if_have 'fog' do
66
98
  # Create deployer
@@ -14,7 +14,7 @@ class Nanoc::Filters::PandocTest < Nanoc::TestCase
14
14
  end
15
15
  end
16
16
 
17
- def test_params
17
+ def test_params_old
18
18
  if_have 'pandoc-ruby' do
19
19
  skip_unless_have_command 'pandoc'
20
20
 
@@ -22,8 +22,22 @@ class Nanoc::Filters::PandocTest < Nanoc::TestCase
22
22
  filter = ::Nanoc::Filters::Pandoc.new
23
23
 
24
24
  # Run filter
25
- opts = [:s, { f: :markdown, to: :html }, 'no-wrap', :toc]
26
- result = filter.setup_and_run("# Heading\n", *opts)
25
+ args = { f: :markdown, to: :html }
26
+ result = filter.setup_and_run("# Heading\n", args)
27
+ assert_match(%r{<h1 id=\"heading\">Heading</h1>\s*}, result)
28
+ end
29
+ end
30
+
31
+ def test_params_new
32
+ if_have 'pandoc-ruby' do
33
+ skip_unless_have_command 'pandoc'
34
+
35
+ # Create filter
36
+ filter = ::Nanoc::Filters::Pandoc.new
37
+
38
+ # Run filter
39
+ args = [:s, { f: :markdown, to: :html }, 'no-wrap', :toc]
40
+ result = filter.setup_and_run("# Heading\n", args: args)
27
41
  assert_match '<div id="TOC">', result
28
42
  assert_match(%r{<h1 id=\"heading\">Heading</h1>\s*}, result)
29
43
  end
@@ -270,6 +270,17 @@ class Nanoc::Filters::SassTest < Nanoc::TestCase
270
270
  end
271
271
  end
272
272
 
273
+ def test_sass_without_filter
274
+ if_have 'sass' do
275
+ File.open('_morestuff.sass', 'w') do |io|
276
+ io.write("p\n color: blue")
277
+ end
278
+
279
+ options = { :filename => File.join(Dir.getwd, 'test.sass') }
280
+ ::Sass::Engine.new('@import "morestuff"', options).render
281
+ end
282
+ end
283
+
273
284
  private
274
285
 
275
286
  def create_filter(params = {})
data/test/helper.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  require File.dirname(__FILE__) + '/gem_loader.rb'
5
5
 
6
6
  # Load unit testing stuff
7
- require 'minitest/unit'
7
+ require 'minitest/test'
8
8
  require 'minitest/spec'
9
9
  require 'minitest/mock'
10
10
  require 'mocha/setup'
@@ -256,12 +256,12 @@ EOS
256
256
  end
257
257
  end
258
258
 
259
- class Nanoc::TestCase < MiniTest::Unit::TestCase
259
+ class Nanoc::TestCase < Minitest::Test
260
260
  include Nanoc::TestHelpers
261
261
  end
262
262
 
263
263
  # Unexpected system exit is unexpected
264
- ::MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS.delete(SystemExit)
264
+ ::Minitest::Test::PASSTHROUGH_EXCEPTIONS.delete(SystemExit)
265
265
 
266
266
  # A more precise inspect method for Time improves assert failure messages.
267
267
  #
@@ -503,6 +503,36 @@ class Nanoc::Helpers::BloggingTest < Nanoc::TestCase
503
503
  end
504
504
  end
505
505
 
506
+ def test_atom_feed_preserve_order
507
+ if_have 'builder' do
508
+ # Mock articles
509
+ @items = [mock_article, mock_article]
510
+ @items.each_with_index do |article, i|
511
+ article.stubs(:[]).with(:title).returns("Article #{i}")
512
+ end
513
+ @items[0].stubs(:[]).with(:created_at).returns('01-01-2015')
514
+ @items[1].stubs(:[]).with(:created_at).returns('01-01-2014')
515
+
516
+ # Mock site
517
+ @site = mock
518
+ @site.stubs(:config).returns({ base_url: 'http://example.com' })
519
+
520
+ # Create feed item
521
+ @item = mock
522
+ @item.stubs(:[]).with(:title).returns('My Blog Or Something')
523
+ @item.stubs(:[]).with(:author_name).returns('J. Doe')
524
+ @item.stubs(:[]).with(:author_uri).returns('http://example.com/~jdoe')
525
+ @item.stubs(:[]).with(:feed_url).returns('http://example.com/feed')
526
+
527
+ # Check
528
+ result = atom_feed(preserve_order: true)
529
+ assert_match(
530
+ Regexp.new('Article 1.*Article 0', Regexp::MULTILINE),
531
+ result
532
+ )
533
+ end
534
+ end
535
+
506
536
  def test_atom_feed_with_content_proc_param
507
537
  if_have 'builder' do
508
538
  # Mock article
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nanoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.5
4
+ version: 3.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Defreyne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-12 00:00:00.000000000 Z
11
+ date: 2015-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cri
@@ -154,6 +154,7 @@ files:
154
154
  - lib/nanoc/extra/checking/checks/external_links.rb
155
155
  - lib/nanoc/extra/checking/checks/html.rb
156
156
  - lib/nanoc/extra/checking/checks/internal_links.rb
157
+ - lib/nanoc/extra/checking/checks/mixed_content.rb
157
158
  - lib/nanoc/extra/checking/checks/stale.rb
158
159
  - lib/nanoc/extra/checking/dsl.rb
159
160
  - lib/nanoc/extra/checking/issue.rb
@@ -254,6 +255,7 @@ files:
254
255
  - test/base/test_item.rb
255
256
  - test/base/test_item_array.rb
256
257
  - test/base/test_item_rep.rb
258
+ - test/base/test_item_rep_recorder_proxy.rb
257
259
  - test/base/test_layout.rb
258
260
  - test/base/test_memoization.rb
259
261
  - test/base/test_notification_center.rb
@@ -287,6 +289,7 @@ files:
287
289
  - test/extra/checking/checks/test_external_links.rb
288
290
  - test/extra/checking/checks/test_html.rb
289
291
  - test/extra/checking/checks/test_internal_links.rb
292
+ - test/extra/checking/checks/test_mixed_content.rb
290
293
  - test/extra/checking/checks/test_stale.rb
291
294
  - test/extra/checking/test_check.rb
292
295
  - test/extra/checking/test_dsl.rb
@@ -372,7 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
372
375
  version: '0'
373
376
  requirements: []
374
377
  rubyforge_project:
375
- rubygems_version: 2.4.5
378
+ rubygems_version: 2.4.6
376
379
  signing_key:
377
380
  specification_version: 4
378
381
  summary: a web publishing system written in Ruby for building small to medium-sized