nanoc 4.4.5 → 4.4.6

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 (233) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -2
  3. data/Gemfile.lock +37 -18
  4. data/NEWS.md +6 -0
  5. data/Rakefile +8 -20
  6. data/lib/nanoc/base/entities/code_snippet.rb +0 -2
  7. data/lib/nanoc/base/entities/item_rep.rb +4 -22
  8. data/lib/nanoc/base/entities/processing_actions/snapshot.rb +9 -7
  9. data/lib/nanoc/base/entities/rule_memory.rb +15 -7
  10. data/lib/nanoc/base/entities/snapshot_def.rb +2 -8
  11. data/lib/nanoc/base/repos/store.rb +2 -28
  12. data/lib/nanoc/base/services/checksummer.rb +9 -10
  13. data/lib/nanoc/base/services/compiler.rb +14 -16
  14. data/lib/nanoc/base/services/executor.rb +2 -13
  15. data/lib/nanoc/base/views/mixins/with_reps_view_mixin.rb +1 -1
  16. data/lib/nanoc/checking/checks/external_links.rb +2 -1
  17. data/lib/nanoc/cli/commands/compile.rb +8 -14
  18. data/lib/nanoc/extra/parallel_collection.rb +57 -0
  19. data/lib/nanoc/extra.rb +1 -0
  20. data/lib/nanoc/filters/mustache.rb +1 -1
  21. data/lib/nanoc/rule_dsl/recording_executor.rb +6 -34
  22. data/lib/nanoc/rule_dsl/rule_memory_calculator.rb +42 -12
  23. data/lib/nanoc/spec.rb +1 -1
  24. data/lib/nanoc/version.rb +1 -1
  25. data/nanoc.gemspec +1 -2
  26. data/spec/contributors_spec.rb +18 -0
  27. data/spec/nanoc/base/checksummer_spec.rb +381 -0
  28. data/spec/nanoc/base/compiler_spec.rb +181 -0
  29. data/spec/nanoc/base/entities/configuration_spec.rb +49 -0
  30. data/spec/nanoc/base/entities/content_spec.rb +193 -0
  31. data/spec/nanoc/base/entities/document_spec.rb +206 -0
  32. data/spec/nanoc/base/entities/identifier_spec.rb +460 -0
  33. data/spec/nanoc/base/entities/item_rep_spec.rb +226 -0
  34. data/spec/nanoc/base/entities/item_spec.rb +3 -0
  35. data/spec/nanoc/base/entities/layout_spec.rb +3 -0
  36. data/spec/nanoc/base/entities/lazy_value_spec.rb +106 -0
  37. data/spec/nanoc/base/entities/outdatedness_status_spec.rb +113 -0
  38. data/spec/nanoc/base/entities/pattern_spec.rb +125 -0
  39. data/spec/nanoc/base/entities/processing_action_spec.rb +9 -0
  40. data/spec/nanoc/base/entities/processing_actions/filter_spec.rb +18 -0
  41. data/spec/nanoc/base/entities/processing_actions/layout_spec.rb +18 -0
  42. data/spec/nanoc/base/entities/processing_actions/snapshot_spec.rb +32 -0
  43. data/spec/nanoc/base/entities/props_spec.rb +195 -0
  44. data/spec/nanoc/base/entities/rule_memory_spec.rb +131 -0
  45. data/spec/nanoc/base/entities/site_spec.rb +73 -0
  46. data/spec/nanoc/base/feature_spec.rb +107 -0
  47. data/spec/nanoc/base/filter_spec.rb +99 -0
  48. data/spec/nanoc/base/item_rep_writer_spec.rb +131 -0
  49. data/spec/nanoc/base/plugin_registry_spec.rb +29 -0
  50. data/spec/nanoc/base/repos/checksum_store_spec.rb +133 -0
  51. data/spec/nanoc/base/repos/compiled_content_cache_spec.rb +55 -0
  52. data/spec/nanoc/base/repos/config_loader_spec.rb +243 -0
  53. data/spec/nanoc/base/repos/dependency_store_spec.rb +195 -0
  54. data/spec/nanoc/base/repos/site_loader_spec.rb +214 -0
  55. data/spec/nanoc/base/services/dependency_tracker_spec.rb +238 -0
  56. data/spec/nanoc/base/services/executor_spec.rb +495 -0
  57. data/spec/nanoc/base/services/item_rep_router_spec.rb +134 -0
  58. data/spec/nanoc/base/services/item_rep_selector_spec.rb +169 -0
  59. data/spec/nanoc/base/services/outdatedness_checker_spec.rb +370 -0
  60. data/spec/nanoc/base/services/outdatedness_rules_spec.rb +432 -0
  61. data/spec/nanoc/base/services/pruner_spec.rb +105 -0
  62. data/spec/nanoc/base/services/temp_filename_factory_spec.rb +87 -0
  63. data/spec/nanoc/base/views/config_view_spec.rb +96 -0
  64. data/spec/nanoc/base/views/document_view_spec.rb +332 -0
  65. data/spec/nanoc/base/views/identifiable_collection_view_spec.rb +190 -0
  66. data/spec/nanoc/base/views/item_collection_with_reps_view_spec.rb +18 -0
  67. data/spec/nanoc/base/views/item_collection_without_reps_view_spec.rb +18 -0
  68. data/spec/nanoc/base/views/item_rep_collection_view_spec.rb +143 -0
  69. data/spec/nanoc/base/views/item_rep_view_spec.rb +265 -0
  70. data/spec/nanoc/base/views/item_view_spec.rb +341 -0
  71. data/spec/nanoc/base/views/layout_collection_view_spec.rb +18 -0
  72. data/spec/nanoc/base/views/layout_view_spec.rb +14 -0
  73. data/spec/nanoc/base/views/mutable_config_view_spec.rb +16 -0
  74. data/spec/nanoc/base/views/mutable_document_view_spec.rb +92 -0
  75. data/spec/nanoc/base/views/mutable_identifiable_collection_view_spec.rb +36 -0
  76. data/spec/nanoc/base/views/mutable_item_collection_view_spec.rb +49 -0
  77. data/spec/nanoc/base/views/mutable_item_view_spec.rb +22 -0
  78. data/spec/nanoc/base/views/mutable_layout_collection_view_spec.rb +49 -0
  79. data/spec/nanoc/base/views/mutable_layout_view_spec.rb +13 -0
  80. data/spec/nanoc/base/views/post_compile_item_rep_collection_view_spec.rb +4 -0
  81. data/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb +137 -0
  82. data/spec/nanoc/base/views/post_compile_item_view_spec.rb +56 -0
  83. data/spec/nanoc/cli/commands/compile/file_action_printer_spec.rb +76 -0
  84. data/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb +66 -0
  85. data/spec/nanoc/cli/commands/compile_spec.rb +64 -0
  86. data/spec/nanoc/cli/commands/deploy_spec.rb +327 -0
  87. data/spec/nanoc/cli/commands/shell_spec.rb +54 -0
  88. data/spec/nanoc/cli/commands/show_data_spec.rb +126 -0
  89. data/spec/nanoc/cli/commands/show_rules_spec.rb +112 -0
  90. data/spec/nanoc/cli/commands/view_spec.rb +58 -0
  91. data/spec/nanoc/data_sources/filesystem_spec.rb +56 -0
  92. data/spec/nanoc/deploying/fog_spec.rb +193 -0
  93. data/spec/nanoc/extra/parallel_collection_spec.rb +108 -0
  94. data/spec/nanoc/filters/colorize_syntax/rouge_spec.rb +195 -0
  95. data/spec/nanoc/filters/less_spec.rb +120 -0
  96. data/spec/nanoc/helpers/blogging_spec.rb +216 -0
  97. data/spec/nanoc/helpers/breadcrumbs_spec.rb +133 -0
  98. data/spec/nanoc/helpers/capturing_spec.rb +181 -0
  99. data/spec/nanoc/helpers/child_parent_spec.rb +105 -0
  100. data/spec/nanoc/helpers/filtering_spec.rb +72 -0
  101. data/spec/nanoc/helpers/html_escape_spec.rb +35 -0
  102. data/spec/nanoc/helpers/link_to_spec.rb +275 -0
  103. data/spec/nanoc/helpers/rendering_spec.rb +141 -0
  104. data/spec/nanoc/helpers/tagging_spec.rb +104 -0
  105. data/spec/nanoc/helpers/text_spec.rb +58 -0
  106. data/spec/nanoc/integration/outdatedness_integration_spec.rb +208 -0
  107. data/spec/nanoc/regressions/gh_1015_spec.rb +17 -0
  108. data/spec/nanoc/regressions/gh_1031_spec.rb +54 -0
  109. data/spec/nanoc/regressions/gh_1035_spec.rb +33 -0
  110. data/spec/nanoc/regressions/gh_1040_spec.rb +22 -0
  111. data/spec/nanoc/regressions/gh_761_spec.rb +23 -0
  112. data/spec/nanoc/regressions/gh_767_spec.rb +19 -0
  113. data/spec/nanoc/regressions/gh_769_spec.rb +30 -0
  114. data/spec/nanoc/regressions/gh_776_spec.rb +43 -0
  115. data/spec/nanoc/regressions/gh_787_spec.rb +19 -0
  116. data/spec/nanoc/regressions/gh_795_spec.rb +19 -0
  117. data/spec/nanoc/regressions/gh_804_spec.rb +26 -0
  118. data/spec/nanoc/regressions/gh_807_spec.rb +17 -0
  119. data/spec/nanoc/regressions/gh_809_spec.rb +17 -0
  120. data/spec/nanoc/regressions/gh_813_spec.rb +22 -0
  121. data/spec/nanoc/regressions/gh_815_spec.rb +18 -0
  122. data/spec/nanoc/regressions/gh_828_spec.rb +23 -0
  123. data/spec/nanoc/regressions/gh_833_spec.rb +14 -0
  124. data/spec/nanoc/regressions/gh_841_spec.rb +15 -0
  125. data/spec/nanoc/regressions/gh_867_spec.rb +15 -0
  126. data/spec/nanoc/regressions/gh_882_spec.rb +29 -0
  127. data/spec/nanoc/regressions/gh_885_spec.rb +30 -0
  128. data/spec/nanoc/regressions/gh_891_spec.rb +26 -0
  129. data/spec/nanoc/regressions/gh_913_spec.rb +24 -0
  130. data/spec/nanoc/regressions/gh_928_spec.rb +5 -0
  131. data/spec/nanoc/regressions/gh_937_spec.rb +25 -0
  132. data/spec/nanoc/regressions/gh_942_spec.rb +21 -0
  133. data/spec/nanoc/regressions/gh_947_spec.rb +21 -0
  134. data/spec/nanoc/regressions/gh_948_spec.rb +16 -0
  135. data/spec/nanoc/regressions/gh_951_spec.rb +19 -0
  136. data/spec/nanoc/regressions/gh_954_spec.rb +33 -0
  137. data/spec/nanoc/regressions/gh_970a_spec.rb +17 -0
  138. data/spec/nanoc/regressions/gh_970b_spec.rb +50 -0
  139. data/spec/nanoc/regressions/gh_974_spec.rb +17 -0
  140. data/spec/nanoc/regressions/gh_981_spec.rb +21 -0
  141. data/spec/nanoc/rule_dsl/recording_executor_spec.rb +142 -0
  142. data/spec/nanoc/rule_dsl/rule_context_spec.rb +177 -0
  143. data/spec/nanoc/rule_dsl/rule_memory_calculator_spec.rb +233 -0
  144. data/spec/nanoc/rule_dsl/rules_collection_spec.rb +299 -0
  145. data/spec/regression_filenames_spec.rb +16 -0
  146. data/spec/spec_helper.rb +173 -0
  147. data/test/base/core_ext/array_spec.rb +2 -0
  148. data/test/base/core_ext/hash_spec.rb +2 -0
  149. data/test/base/core_ext/string_spec.rb +2 -0
  150. data/test/base/test_code_snippet.rb +2 -0
  151. data/test/base/test_compiler.rb +2 -0
  152. data/test/base/test_context.rb +4 -2
  153. data/test/base/test_data_source.rb +2 -0
  154. data/test/base/test_dependency_tracker.rb +2 -0
  155. data/test/base/test_directed_graph.rb +2 -0
  156. data/test/base/test_filter.rb +7 -5
  157. data/test/base/test_item.rb +2 -0
  158. data/test/base/test_item_array.rb +3 -1
  159. data/test/base/test_layout.rb +2 -0
  160. data/test/base/test_memoization.rb +2 -0
  161. data/test/base/test_notification_center.rb +2 -0
  162. data/test/base/test_outdatedness_checker.rb +2 -0
  163. data/test/base/test_plugin.rb +2 -0
  164. data/test/base/test_site.rb +2 -0
  165. data/test/base/test_store.rb +2 -0
  166. data/test/checking/checks/test_css.rb +2 -0
  167. data/test/checking/checks/test_external_links.rb +4 -2
  168. data/test/checking/checks/test_html.rb +2 -0
  169. data/test/checking/checks/test_internal_links.rb +5 -3
  170. data/test/checking/checks/test_mixed_content.rb +2 -0
  171. data/test/checking/checks/test_stale.rb +2 -0
  172. data/test/checking/test_check.rb +2 -0
  173. data/test/checking/test_dsl.rb +2 -0
  174. data/test/checking/test_runner.rb +2 -0
  175. data/test/cli/commands/test_check.rb +2 -0
  176. data/test/cli/commands/test_compile.rb +2 -0
  177. data/test/cli/commands/test_create_site.rb +2 -0
  178. data/test/cli/commands/test_help.rb +2 -0
  179. data/test/cli/commands/test_info.rb +2 -0
  180. data/test/cli/commands/test_prune.rb +2 -0
  181. data/test/cli/test_cleaning_stream.rb +2 -0
  182. data/test/cli/test_cli.rb +11 -9
  183. data/test/cli/test_error_handler.rb +2 -0
  184. data/test/cli/test_logger.rb +2 -0
  185. data/test/data_sources/test_filesystem.rb +8 -6
  186. data/test/data_sources/test_filesystem_tools.rb +2 -0
  187. data/test/deploying/test_fog.rb +2 -0
  188. data/test/deploying/test_rsync.rb +4 -2
  189. data/test/extra/core_ext/test_pathname.rb +2 -0
  190. data/test/extra/core_ext/test_time.rb +2 -0
  191. data/test/extra/test_link_collector.rb +2 -0
  192. data/test/extra/test_piper.rb +2 -0
  193. data/test/filters/colorize_syntax/test_coderay.rb +2 -0
  194. data/test/filters/colorize_syntax/test_common.rb +2 -0
  195. data/test/filters/colorize_syntax/test_pygmentize.rb +2 -0
  196. data/test/filters/colorize_syntax/test_pygments.rb +2 -0
  197. data/test/filters/colorize_syntax/test_simon.rb +2 -0
  198. data/test/filters/test_asciidoc.rb +2 -0
  199. data/test/filters/test_bluecloth.rb +2 -0
  200. data/test/filters/test_coffeescript.rb +2 -0
  201. data/test/filters/test_erb.rb +7 -5
  202. data/test/filters/test_erubis.rb +6 -4
  203. data/test/filters/test_haml.rb +7 -5
  204. data/test/filters/test_handlebars.rb +2 -0
  205. data/test/filters/test_kramdown.rb +2 -0
  206. data/test/filters/test_markaby.rb +2 -0
  207. data/test/filters/test_maruku.rb +2 -0
  208. data/test/filters/test_mustache.rb +4 -2
  209. data/test/filters/test_pandoc.rb +2 -0
  210. data/test/filters/test_rainpress.rb +2 -0
  211. data/test/filters/test_rdiscount.rb +2 -0
  212. data/test/filters/test_rdoc.rb +2 -0
  213. data/test/filters/test_redcarpet.rb +2 -0
  214. data/test/filters/test_redcloth.rb +2 -0
  215. data/test/filters/test_relativize_paths.rb +2 -0
  216. data/test/filters/test_rubypants.rb +2 -0
  217. data/test/filters/test_sass.rb +4 -2
  218. data/test/filters/test_slim.rb +4 -2
  219. data/test/filters/test_typogruby.rb +2 -0
  220. data/test/filters/test_uglify_js.rb +2 -0
  221. data/test/filters/test_xsl.rb +2 -0
  222. data/test/filters/test_yui_compressor.rb +5 -3
  223. data/test/helpers/test_blogging.rb +2 -0
  224. data/test/helpers/test_capturing.rb +2 -0
  225. data/test/helpers/test_link_to.rb +2 -0
  226. data/test/helpers/test_xml_sitemap.rb +2 -0
  227. data/test/rule_dsl/test_action_provider.rb +2 -0
  228. data/test/rule_dsl/test_compiler_dsl.rb +6 -4
  229. data/test/rule_dsl/test_rule.rb +2 -0
  230. data/test/rule_dsl/test_rules_collection.rb +2 -0
  231. data/test/test_gem.rb +2 -0
  232. metadata +124 -17
  233. data/test/base/test_item_rep.rb +0 -156
@@ -0,0 +1,56 @@
1
+ describe Nanoc::DataSources::Filesystem do
2
+ let(:data_source) { Nanoc::DataSources::Filesystem.new(site.config, nil, nil, params) }
3
+ let(:params) { {} }
4
+ let(:site) { Nanoc::Int::SiteLoader.new.new_empty }
5
+
6
+ before { Timecop.freeze(now) }
7
+ after { Timecop.return }
8
+
9
+ let(:now) { Time.local(2008, 1, 2, 14, 5, 0) }
10
+
11
+ describe '#load_objects' do
12
+ subject { data_source.send(:load_objects, 'foo', klass) }
13
+
14
+ let(:klass) { raise 'override me' }
15
+
16
+ context 'items' do
17
+ let(:klass) { Nanoc::Int::Item }
18
+
19
+ context 'no files' do
20
+ it 'loads nothing' do
21
+ expect(subject).to be_empty
22
+ end
23
+ end
24
+
25
+ context 'one regular file' do
26
+ before do
27
+ FileUtils.mkdir_p('foo')
28
+ File.write('foo/bar.html', "---\nnum: 1\n---\ntest 1")
29
+ FileUtils.touch('foo/bar.html', mtime: now)
30
+ end
31
+
32
+ let(:expected_attributes) do
33
+ {
34
+ content_filename: 'foo/bar.html',
35
+ extension: 'html',
36
+ filename: 'foo/bar.html',
37
+ meta_filename: nil,
38
+ mtime: now,
39
+ num: 1,
40
+ }
41
+ end
42
+
43
+ it 'loads that file' do
44
+ expect(subject.size).to eq(1)
45
+
46
+ expect(subject[0].content.string).to eq('test 1')
47
+ expect(subject[0].attributes).to eq(expected_attributes)
48
+ expect(subject[0].identifier).to eq(Nanoc::Identifier.new('/bar/'))
49
+ expect(subject[0].checksum_data).to be_nil
50
+ expect(subject[0].content_checksum_data).to eq('test 1')
51
+ expect(subject[0].attributes_checksum_data).to eq("num: 1\n")
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,193 @@
1
+ describe Nanoc::Deploying::Deployers::Fog, stdio: true do
2
+ let(:deployer) do
3
+ Nanoc::Deploying::Deployers::Fog.new(
4
+ 'output/',
5
+ config,
6
+ dry_run: is_dry_run,
7
+ )
8
+ end
9
+
10
+ let(:is_dry_run) { false }
11
+
12
+ let(:config) do
13
+ {
14
+ bucket: 'bucky',
15
+ provider: 'local',
16
+ local_root: 'remote',
17
+ }
18
+ end
19
+
20
+ before do
21
+ # create output
22
+ FileUtils.mkdir_p('output')
23
+ FileUtils.mkdir_p('output/etc')
24
+ File.open('output/woof', 'w') { |io| io.write 'I am a dog!' }
25
+ File.open('output/etc/meow', 'w') { |io| io.write 'I am a cat!' }
26
+
27
+ # create local cloud
28
+ FileUtils.mkdir_p('remote')
29
+ end
30
+
31
+ subject { deployer.run }
32
+
33
+ shared_examples 'no effective deploy' do
34
+ it 'does not modify remote' do
35
+ expect { subject }.not_to change { Dir['remote/**/*'].sort }
36
+ end
37
+ end
38
+
39
+ shared_examples 'effective deploy' do
40
+ it 'modifies remote' do
41
+ expect { subject }.to change { Dir['remote/**/*'].sort }
42
+ .to([
43
+ 'remote/bucky',
44
+ 'remote/bucky/etc',
45
+ 'remote/bucky/etc/meow',
46
+ 'remote/bucky/woof',
47
+ ])
48
+ end
49
+ end
50
+
51
+ context 'dry run' do
52
+ let(:is_dry_run) { true }
53
+
54
+ before do
55
+ FileUtils.mkdir_p('remote/bucky')
56
+ FileUtils.mkdir_p('remote/bucky/tiny')
57
+ File.write('remote/bucky/pig', 'oink?')
58
+ File.write('remote/bucky/tiny/piglet', 'little oink?')
59
+ end
60
+
61
+ include_examples 'no effective deploy'
62
+
63
+ context 'with CDN ID' do
64
+ let(:config) { super().merge(cdn_id: 'donkey-cdn') }
65
+
66
+ let(:cdn) { Object.new }
67
+ let(:distribution) { Object.new }
68
+
69
+ it 'does not actually invalidate' do
70
+ expect(::Fog::CDN).to receive(:new).with(provider: 'local', local_root: 'remote').and_return(cdn)
71
+ expect(cdn).to receive(:get_distribution).with('donkey-cdn').and_return(distribution)
72
+
73
+ subject
74
+ end
75
+ end
76
+ end
77
+
78
+ context 'effective run' do
79
+ include_examples 'effective deploy'
80
+
81
+ context 'custom path' do
82
+ context 'custom path ends with /' do
83
+ let(:config) do
84
+ super().merge(path: 'foo/')
85
+ end
86
+
87
+ it 'raises' do
88
+ expect { subject }.to raise_error('The path `foo/` is not supposed to have a trailing slash')
89
+ end
90
+ end
91
+
92
+ context 'custom path does not end with /' do
93
+ let(:config) do
94
+ super().merge(path: 'foo')
95
+ end
96
+
97
+ it 'modifies remote' do
98
+ expect { subject }.to change { Dir['remote/**/*'].sort }
99
+ .to([
100
+ 'remote/bucky',
101
+ 'remote/bucky/foo',
102
+ 'remote/bucky/foo/etc',
103
+ 'remote/bucky/foo/etc/meow',
104
+ 'remote/bucky/foo/woof',
105
+ ])
106
+ end
107
+ end
108
+ end
109
+
110
+ context 'bucket already exists' do
111
+ before do
112
+ FileUtils.mkdir_p('remote/bucky')
113
+ end
114
+
115
+ include_examples 'effective deploy'
116
+ end
117
+
118
+ context 'remote contains stale file at root' do
119
+ before do
120
+ FileUtils.mkdir_p('remote/bucky')
121
+ File.write('remote/bucky/pig', 'oink?')
122
+ end
123
+
124
+ include_examples 'effective deploy'
125
+
126
+ it 'does not contain stale files' do
127
+ subject
128
+ expect(Dir['remote/**/*'].sort).not_to include('remote/bucky/pig')
129
+ end
130
+ end
131
+
132
+ context 'remote contains stale file in subdirectory' do
133
+ before do
134
+ FileUtils.mkdir_p('remote/bucky/secret')
135
+ File.write('remote/bucky/secret/pig', 'oink?')
136
+ end
137
+
138
+ include_examples 'effective deploy'
139
+
140
+ it 'does not contain stale files' do
141
+ subject
142
+ expect(Dir['remote/**/*'].sort).not_to include('remote/bucky/secret/pig')
143
+ end
144
+ end
145
+
146
+ context 'with CDN ID' do
147
+ let(:config) { super().merge(cdn_id: 'donkey-cdn') }
148
+
149
+ let(:cdn) { Object.new }
150
+ let(:distribution) { Object.new }
151
+
152
+ it 'invalidates' do
153
+ expect(::Fog::CDN).to receive(:new).with(provider: 'local', local_root: 'remote').and_return(cdn)
154
+ expect(cdn).to receive(:get_distribution).with('donkey-cdn').and_return(distribution)
155
+ expect(cdn).to receive(:post_invalidation).with(distribution, contain_exactly('etc/meow', 'woof'))
156
+
157
+ subject
158
+ end
159
+ end
160
+
161
+ context 'remote list consists of truncated sets' do
162
+ before do
163
+ expect(::Fog::Storage).to receive(:new).and_return(fog_storage)
164
+ expect(fog_storage).to receive(:directories).and_return(directories)
165
+ expect(directories).to receive(:get).and_return(directory)
166
+ allow(directory).to receive(:files).and_return(files)
167
+ expect(files).to receive(:get).with('stray').and_return(file_stray).ordered
168
+ expect(files).to receive(:each)
169
+ .and_yield(double(:woof, key: 'woof'))
170
+ .and_yield(double(:meow, key: 'etc/meow'))
171
+ .and_yield(double(:stray, key: 'stray'))
172
+ expect(file_stray).to receive(:destroy)
173
+
174
+ expect(files).to receive(:create).with(key: 'woof', body: anything, public: true) do
175
+ FileUtils.mkdir_p('remote/bucky')
176
+ File.write('remote/bucky/woof', 'hi')
177
+ end
178
+ expect(files).to receive(:create).with(key: 'etc/meow', body: anything, public: true) do
179
+ FileUtils.mkdir_p('remote/bucky/etc')
180
+ File.write('remote/bucky/etc/meow', 'hi')
181
+ end
182
+ end
183
+
184
+ let(:fog_storage) { double(:fog_storage) }
185
+ let(:directories) { double(:directories) }
186
+ let(:directory) { double(:directory) }
187
+ let(:files) { double(:files) }
188
+ let(:file_stray) { double(:file_stray) }
189
+
190
+ include_examples 'effective deploy'
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,108 @@
1
+ describe Nanoc::Extra::ParallelCollection do
2
+ subject(:col) { described_class.new(wrapped, parallelism: parallelism) }
3
+ let(:wrapped) { [1, 2, 3, 4, 5] }
4
+ let(:parallelism) { 5 }
5
+
6
+ describe '#each' do
7
+ subject do
8
+ col.each do |e|
9
+ sleep 0.1
10
+ out << e
11
+ end
12
+ end
13
+ let!(:out) { [] }
14
+
15
+ it 'is fast' do
16
+ expect { subject }.to finish_in_under(0.2).seconds
17
+ end
18
+
19
+ it 'is correct' do
20
+ expect { subject }.to change { out.sort }.from([]).to([1, 2, 3, 4, 5])
21
+ end
22
+
23
+ it 'does not leave threads lingering' do
24
+ expect { subject }.not_to change { Thread.list.size }
25
+ end
26
+
27
+ context 'errors' do
28
+ subject do
29
+ col.each do |e|
30
+ if e == 1
31
+ sleep 0.02
32
+ raise 'ugh'
33
+ else
34
+ sleep 0.1
35
+ out << e
36
+ end
37
+ end
38
+ end
39
+
40
+ let(:parallelism) { 3 }
41
+
42
+ it 'raises' do
43
+ expect { subject }.to raise_error(RuntimeError, 'ugh')
44
+ end
45
+
46
+ it 'aborts early' do
47
+ expect { subject rescue nil }.to change { out.sort }.from([]).to([2, 3])
48
+ end
49
+ end
50
+
51
+ context 'low parallelism' do
52
+ let(:parallelism) { 1 }
53
+
54
+ it 'is not fast' do
55
+ expect { subject }.not_to finish_in_under(0.5).seconds
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#map' do
61
+ subject do
62
+ col.map do |e|
63
+ sleep 0.1
64
+ e * 10
65
+ end
66
+ end
67
+
68
+ it 'is fast' do
69
+ expect { subject }.to finish_in_under(0.2).seconds
70
+ end
71
+
72
+ it 'does not leave threads lingering' do
73
+ expect { subject }.not_to change { Thread.list.size }
74
+ end
75
+
76
+ it 'is correct' do
77
+ expect(subject.sort).to eq([10, 20, 30, 40, 50])
78
+ end
79
+
80
+ context 'errors' do
81
+ subject do
82
+ col.each do |e|
83
+ if e == 1
84
+ sleep 0.02
85
+ raise 'ugh'
86
+ else
87
+ sleep 0.1
88
+ e * 10
89
+ end
90
+ end
91
+ end
92
+
93
+ let(:parallelism) { 3 }
94
+
95
+ it 'raises' do
96
+ expect { subject }.to raise_error(RuntimeError, 'ugh')
97
+ end
98
+ end
99
+
100
+ context 'low parallelism' do
101
+ let(:parallelism) { 1 }
102
+
103
+ it 'is not fast' do
104
+ expect { subject }.not_to finish_in_under(0.5).seconds
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,195 @@
1
+ require 'rouge'
2
+
3
+ describe Nanoc::Filters::ColorizeSyntax, filter: true, rouge: true do
4
+ subject { filter.setup_and_run(input, default_colorizer: :rouge, rouge: params) }
5
+ let(:filter) { ::Nanoc::Filters::ColorizeSyntax.new }
6
+ let(:params) { {} }
7
+ let(:wrap) { false }
8
+ let(:css_class) { 'highlight' }
9
+ let(:input) do
10
+ <<-EOS.freeze
11
+ before
12
+ <pre><code class="language-ruby">
13
+ def foo
14
+ end
15
+ </code></pre>
16
+ after
17
+ EOS
18
+ end
19
+ let(:output) do
20
+ <<-EOS
21
+ before
22
+ <pre><code class=\"language-ruby#{wrap ? " #{css_class}" : ''}\"> <span class=\"k\">def</span> <span class=\"nf\">foo</span>
23
+ <span class=\"k\">end</span></code></pre>
24
+ after
25
+ EOS
26
+ end
27
+
28
+ context 'with Rouge' do
29
+ context 'with 1.x', if: Rouge.version < '2' do
30
+ context 'with default options' do
31
+ it { is_expected.to eql output }
32
+ end
33
+
34
+ context 'with pygments wrapper' do
35
+ let(:wrap) { true }
36
+ let(:params) { super().merge(wrap: wrap) }
37
+
38
+ it { is_expected.to eql output }
39
+
40
+ context 'with css_class' do
41
+ let(:css_class) { 'nanoc' }
42
+ let(:params) { super().merge(css_class: css_class) }
43
+
44
+ it { is_expected.to eql output }
45
+ end
46
+ end
47
+
48
+ context 'with line number' do
49
+ let(:line_numbers) { true }
50
+ let(:params) { super().merge(line_numbers: line_numbers) }
51
+ let(:output) do
52
+ <<-EOS
53
+ before
54
+ <pre><code class="language-ruby"><table style="border-spacing: 0"><tbody><tr>
55
+ <td class="gutter gl" style="text-align: right"><pre class="lineno">1
56
+ 2</pre></td>
57
+ <td class="code"><pre> <span class="k">def</span> <span class="nf">foo</span>
58
+ <span class="k">end</span><span class="w">
59
+ </span></pre></td>
60
+ </tr></tbody></table></code></pre>
61
+ after
62
+ EOS
63
+ end
64
+
65
+ it { is_expected.to eql output }
66
+ end
67
+ end
68
+
69
+ context 'with 2.x', if: Rouge.version >= '2' do
70
+ context 'with default options' do
71
+ it { is_expected.to eql output }
72
+ end
73
+
74
+ context 'with legacy' do
75
+ let(:legacy) { true }
76
+ let(:params) { super().merge(legacy: legacy) }
77
+
78
+ it { is_expected.to eql output }
79
+
80
+ context 'with pygments wrapper' do
81
+ let(:wrap) { true }
82
+ let(:params) { super().merge(wrap: wrap) }
83
+
84
+ it { is_expected.to eql output }
85
+
86
+ context 'with css_class' do
87
+ let(:css_class) { 'nanoc' }
88
+ let(:params) { super().merge(css_class: css_class) }
89
+
90
+ it { is_expected.to eql output }
91
+ end
92
+ end
93
+
94
+ context 'with line number' do
95
+ let(:line_numbers) { true }
96
+ let(:params) { super().merge(line_numbers: line_numbers) }
97
+ let(:output) do
98
+ <<-EOS
99
+ before
100
+ <pre><code class="language-ruby"><table class="rouge-table"><tbody><tr>
101
+ <td class="rouge-gutter gl"><pre class="lineno">1
102
+ 2
103
+ </pre></td>
104
+ <td class="rouge-code"><pre> <span class="k">def</span> <span class="nf">foo</span>
105
+ <span class="k">end</span></pre></td>
106
+ </tr></tbody></table></code></pre>
107
+ after
108
+ EOS
109
+ end
110
+
111
+ it { is_expected.to eql output }
112
+ end
113
+ end
114
+
115
+ context 'with formater' do
116
+ let(:params) { super().merge(formatter: formatter) }
117
+
118
+ context 'with inline' do
119
+ let(:formatter) { Rouge::Formatters::HTMLInline.new(theme) }
120
+
121
+ context 'with github theme' do
122
+ let(:theme) { Rouge::Themes::Github.new }
123
+ let(:output) do
124
+ <<-EOS
125
+ before
126
+ <pre><code class="language-ruby"> <span style="color: #000000;font-weight: bold">def</span> <span style="color: #990000;font-weight: bold">foo</span>
127
+ <span style="color: #000000;font-weight: bold">end</span></code></pre>
128
+ after
129
+ EOS
130
+ end
131
+
132
+ it { is_expected.to eql output }
133
+ end
134
+
135
+ context 'with colorful theme' do
136
+ let(:theme) { Rouge::Themes::Colorful.new }
137
+ let(:output) do
138
+ <<-EOS
139
+ before
140
+ <pre><code class="language-ruby"> <span style="color: #080;font-weight: bold">def</span> <span style="color: #06B;font-weight: bold">foo</span>
141
+ <span style="color: #080;font-weight: bold">end</span></code></pre>
142
+ after
143
+ EOS
144
+ end
145
+
146
+ it { is_expected.to eql output }
147
+ end
148
+ end
149
+
150
+ context 'with linewise' do
151
+ let(:formatter) { Rouge::Formatters::HTMLLinewise.new(Rouge::Formatters::HTML.new) }
152
+ let(:output) do
153
+ <<-EOS
154
+ before
155
+ <pre><code class="language-ruby"><div class="line-1"> <span class="k">def</span> <span class="nf">foo</span>
156
+ </div>
157
+ <div class="line-2"> <span class="k">end</span>
158
+ </div></code></pre>
159
+ after
160
+ EOS
161
+ end
162
+
163
+ it { is_expected.to eql output }
164
+ end
165
+
166
+ context 'with pygments' do
167
+ let(:wrap) { true }
168
+ let(:css_class) { 'codehilite' }
169
+ let(:formatter) { Rouge::Formatters::HTMLPygments.new(Rouge::Formatters::HTML.new) }
170
+
171
+ it { is_expected.to eql output }
172
+ end
173
+
174
+ context 'with table' do
175
+ let(:formatter) { Rouge::Formatters::HTMLTable.new(Rouge::Formatters::HTML.new) }
176
+ let(:output) do
177
+ <<-EOS
178
+ before
179
+ <pre><code class="language-ruby"><table class="rouge-table"><tbody><tr>
180
+ <td class="rouge-gutter gl"><pre class="lineno">1
181
+ 2
182
+ </pre></td>
183
+ <td class="rouge-code"><pre> <span class="k">def</span> <span class="nf">foo</span>
184
+ <span class="k">end</span></pre></td>
185
+ </tr></tbody></table></code></pre>
186
+ after
187
+ EOS
188
+ end
189
+
190
+ it { is_expected.to eql output }
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,120 @@
1
+ describe Nanoc::Filters::Less, site: true, stdio: true, v8: true do
2
+ # These tests are high-level in order to interact well with the compiler. This is important for
3
+ # this :less filter, because of the way it handles fibers.
4
+
5
+ before do
6
+ File.open('Rules', 'w') do |io|
7
+ io.write "compile '/**/*.less' do\n"
8
+ io.write " filter :less\n"
9
+ io.write " write item.identifier.without_ext + '.css'\n"
10
+ io.write "end\n"
11
+ end
12
+ end
13
+
14
+ context 'one file' do
15
+ let(:content_a) { 'p { color: red; }' }
16
+
17
+ before do
18
+ File.write('content/a.less', content_a)
19
+ end
20
+
21
+ it 'compiles a.less' do
22
+ Nanoc::CLI.run(%w(compile))
23
+ expect(File.read('output/a.css')).to match(/^p\s*\{\s*color:\s*red;?\s*\}/)
24
+ end
25
+
26
+ context 'with compression' do
27
+ let(:content_a) { '.foo { bar: a; } .bar { foo: b; }' }
28
+
29
+ before do
30
+ File.open('Rules', 'w') do |io|
31
+ io.write "compile '/*.less' do\n"
32
+ io.write " filter :less, compress: true\n"
33
+ io.write " write item.identifier.without_ext + '.css'\n"
34
+ io.write "end\n"
35
+ end
36
+ end
37
+
38
+ it 'compiles and compresses a.less' do
39
+ Nanoc::CLI.run(%w(compile))
40
+ expect(File.read('output/a.css')).to match(/^\.foo\{bar:a\}\n?\.bar\{foo:b\}/)
41
+ end
42
+ end
43
+ end
44
+
45
+ context 'two files' do
46
+ let(:content_a) { '@import "b.less";' }
47
+ let(:content_b) { 'p { color: red; }' }
48
+
49
+ before do
50
+ File.write('content/a.less', content_a)
51
+ File.write('content/b.less', content_b)
52
+ end
53
+
54
+ it 'compiles a.less' do
55
+ Nanoc::CLI.run(%w(compile))
56
+ expect(File.read('output/a.css')).to match(/^p\s*\{\s*color:\s*red;?\s*\}/)
57
+ end
58
+
59
+ it 'recompiles a.less if b.less has changed' do
60
+ Nanoc::CLI.run(%w(compile))
61
+
62
+ File.write('content/b.less', 'p { color: blue; }')
63
+
64
+ Nanoc::CLI.run(%w(compile))
65
+ expect(File.read('output/a.css')).to match(/^p\s*\{\s*color:\s*blue;?\s*\}/)
66
+ end
67
+ end
68
+
69
+ context 'paths relative to site directory' do
70
+ let(:content_a) { '@import "content/foo/bar/imported_file.less";' }
71
+ let(:content_b) { 'p { color: red; }' }
72
+
73
+ before do
74
+ FileUtils.mkdir_p('content/foo/bar')
75
+
76
+ File.write('content/a.less', content_a)
77
+ File.write('content/foo/bar/imported_file.less', content_b)
78
+ end
79
+
80
+ it 'compiles a.less' do
81
+ Nanoc::CLI.run(%w(compile))
82
+ expect(File.read('output/a.css')).to match(/^p\s*\{\s*color:\s*red;?\s*\}/)
83
+ end
84
+
85
+ it 'recompiles a.less if b.less has changed' do
86
+ Nanoc::CLI.run(%w(compile))
87
+
88
+ File.write('content/foo/bar/imported_file.less', 'p { color: blue; }')
89
+
90
+ Nanoc::CLI.run(%w(compile))
91
+ expect(File.read('output/a.css')).to match(/^p\s*\{\s*color:\s*blue;?\s*\}/)
92
+ end
93
+ end
94
+
95
+ context 'paths relative to current file' do
96
+ let(:content_a) { '@import "bar/imported_file.less";' }
97
+ let(:content_b) { 'p { color: red; }' }
98
+
99
+ before do
100
+ FileUtils.mkdir_p('content/foo/bar')
101
+
102
+ File.write('content/foo/a.less', content_a)
103
+ File.write('content/foo/bar/imported_file.less', content_b)
104
+ end
105
+
106
+ it 'compiles a.less' do
107
+ Nanoc::CLI.run(%w(compile))
108
+ expect(File.read('output/foo/a.css')).to match(/^p\s*\{\s*color:\s*red;?\s*\}/)
109
+ end
110
+
111
+ it 'recompiles a.less if b.less has changed' do
112
+ Nanoc::CLI.run(%w(compile))
113
+
114
+ File.write('content/foo/bar/imported_file.less', 'p { color: blue; }')
115
+
116
+ Nanoc::CLI.run(%w(compile))
117
+ expect(File.read('output/foo/a.css')).to match(/^p\s*\{\s*color:\s*blue;?\s*\}/)
118
+ end
119
+ end
120
+ end