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,327 @@
1
+ describe Nanoc::CLI::Commands::Shell, site: true, stdio: true do
2
+ describe '#run' do
3
+ let(:config) { {} }
4
+
5
+ before do
6
+ # Prevent double-loading
7
+ expect(Nanoc::CLI).to receive(:setup)
8
+
9
+ File.write('nanoc.yaml', YAML.dump(config))
10
+ end
11
+
12
+ shared_examples 'no effective deploy' do
13
+ it 'does not write any files' do
14
+ expect { run rescue nil }.not_to change { Dir['remote/*'] }
15
+ expect(Dir['remote/*']).to be_empty
16
+ end
17
+ end
18
+
19
+ shared_examples 'effective deploy' do
20
+ it 'writes files' do
21
+ expect { run }.to change { Dir['remote/*'] }.from([]).to(['remote/success.txt'])
22
+ expect(File.read('remote/success.txt')).to eql('hurrah')
23
+ end
24
+ end
25
+
26
+ shared_examples 'attempted/effective deploy' do
27
+ context 'no checks' do
28
+ include_examples 'effective deploy'
29
+ end
30
+
31
+ context 'checks fail' do
32
+ before do
33
+ File.write(
34
+ 'Checks',
35
+ "check :donkey do\n" \
36
+ " add_issue('things are broken', subject: 'success.txt')\n" \
37
+ "end\n" \
38
+ "\n" \
39
+ "deploy_check :donkey\n",
40
+ )
41
+ end
42
+
43
+ include_examples 'no effective deploy'
44
+
45
+ context 'checks disabled' do
46
+ context '--no-check' do
47
+ let(:command) { super() + ['--no-check'] }
48
+ include_examples 'effective deploy'
49
+ end
50
+
51
+ context '--Ck' do
52
+ let(:command) { super() + ['-C'] }
53
+ include_examples 'effective deploy'
54
+ end
55
+ end
56
+ end
57
+
58
+ context 'checks pass' do
59
+ before do
60
+ File.write(
61
+ 'Checks',
62
+ "check :donkey do\n" \
63
+ "end\n" \
64
+ "\n" \
65
+ "deploy_check :donkey\n",
66
+ )
67
+ end
68
+
69
+ include_examples 'effective deploy'
70
+ end
71
+ end
72
+
73
+ describe 'listing deployers' do
74
+ shared_examples 'lists all deployers' do
75
+ let(:run) { Nanoc::CLI.run(command) }
76
+
77
+ it 'lists all deployers' do
78
+ expect { run }.to output(/Available deployers:\n fog\n rsync/).to_stdout
79
+ end
80
+
81
+ include_examples 'no effective deploy'
82
+ end
83
+
84
+ context '--list-deployers' do
85
+ let(:command) { %w(deploy --list-deployers) }
86
+ include_examples 'lists all deployers'
87
+ end
88
+
89
+ context '-D' do
90
+ let(:command) { %w(deploy -D) }
91
+ include_examples 'lists all deployers'
92
+ end
93
+ end
94
+
95
+ describe 'listing deployment configurations' do
96
+ shared_examples 'lists all deployment configurations' do
97
+ let(:run) { Nanoc::CLI.run(command) }
98
+
99
+ context 'no deployment configurations' do
100
+ let(:config) { { donkeys: 'lots' } }
101
+
102
+ it 'says nothing is found' do
103
+ expect { run }.to output(/No deployment configurations./).to_stdout
104
+ end
105
+
106
+ include_examples 'no effective deploy'
107
+ end
108
+
109
+ context 'some deployment configurations' do
110
+ let(:config) do
111
+ {
112
+ deploy: {
113
+ production: {
114
+ kind: 'rsync',
115
+ dst: 'remote',
116
+ },
117
+ staging: {
118
+ kind: 'rsync',
119
+ dst: 'remote',
120
+ },
121
+ },
122
+ }
123
+ end
124
+
125
+ it 'says some targets are found' do
126
+ expect { run }.to output(/Available deployment configurations:\n production\n staging/).to_stdout
127
+ end
128
+
129
+ include_examples 'no effective deploy'
130
+ end
131
+ end
132
+
133
+ context '--list' do
134
+ let(:command) { %w(deploy --list) }
135
+ include_examples 'lists all deployment configurations'
136
+ end
137
+
138
+ context '-L' do
139
+ let(:command) { %w(deploy -L) }
140
+ include_examples 'lists all deployment configurations'
141
+ end
142
+ end
143
+
144
+ describe 'deploying' do
145
+ let(:run) { Nanoc::CLI.run(command) }
146
+ let(:command) { %w(deploy) }
147
+
148
+ before do
149
+ FileUtils.mkdir_p('output')
150
+ FileUtils.mkdir_p('remote')
151
+ File.write('output/success.txt', 'hurrah')
152
+ end
153
+
154
+ shared_examples 'missing kind warning' do
155
+ it 'warns about missing kind' do
156
+ expect { run }.to output(/Warning: The specified deploy target does not have a kind attribute. Assuming rsync./).to_stderr
157
+ end
158
+ end
159
+
160
+ context 'no deploy configs' do
161
+ it 'errors' do
162
+ expect { run }.to raise_error(
163
+ Nanoc::Int::Errors::GenericTrivial,
164
+ 'The site has no deployment configurations.',
165
+ )
166
+ end
167
+
168
+ include_examples 'no effective deploy'
169
+
170
+ context 'configuration created in preprocessor' do
171
+ before do
172
+ File.write(
173
+ 'Rules',
174
+ "preprocess do\n" \
175
+ " @config[:deploy] = {\n" \
176
+ " default: { dst: 'remote' },\n" \
177
+ " }\n" \
178
+ "end\n\n" + File.read('Rules'),
179
+ )
180
+ end
181
+
182
+ include_examples 'attempted/effective deploy'
183
+ end
184
+ end
185
+
186
+ context 'some deploy configs' do
187
+ let(:config) do
188
+ {
189
+ deploy: {
190
+ irrelevant: {
191
+ kind: 'rsync',
192
+ dst: 'remote',
193
+ },
194
+ },
195
+ }
196
+ end
197
+
198
+ context 'default target' do
199
+ context 'requested deploy config does not exist' do
200
+ it 'errors' do
201
+ expect { run }.to raise_error(
202
+ Nanoc::Int::Errors::GenericTrivial,
203
+ 'The site has no deployment configuration named `default`.',
204
+ )
205
+ end
206
+
207
+ include_examples 'no effective deploy'
208
+ end
209
+
210
+ context 'requested deploy config exists' do
211
+ let(:config) do
212
+ {
213
+ deploy: {
214
+ default: {
215
+ kind: 'rsync',
216
+ dst: 'remote',
217
+ },
218
+ },
219
+ }
220
+ end
221
+
222
+ include_examples 'attempted/effective deploy'
223
+
224
+ context 'dry run' do
225
+ let(:command) { super() + ['--dry-run'] }
226
+ include_examples 'no effective deploy'
227
+ end
228
+ end
229
+
230
+ context 'requested deploy config exists, but has no kind' do
231
+ let(:config) do
232
+ {
233
+ deploy: {
234
+ default: {
235
+ dst: 'remote',
236
+ },
237
+ },
238
+ }
239
+ end
240
+
241
+ include_examples 'attempted/effective deploy'
242
+ include_examples 'missing kind warning'
243
+
244
+ context 'dry run' do
245
+ let(:command) { super() + ['--dry-run'] }
246
+ include_examples 'no effective deploy'
247
+ end
248
+ end
249
+ end
250
+
251
+ shared_examples 'deploy with non-default target' do
252
+ context 'requested deploy config does not exist' do
253
+ it 'errors' do
254
+ expect { run }.to raise_error(
255
+ Nanoc::Int::Errors::GenericTrivial,
256
+ 'The site has no deployment configuration named `production`.',
257
+ )
258
+ end
259
+
260
+ include_examples 'no effective deploy'
261
+ end
262
+
263
+ context 'requested deploy config exists' do
264
+ let(:config) do
265
+ {
266
+ deploy: {
267
+ production: {
268
+ kind: 'rsync',
269
+ dst: 'remote',
270
+ },
271
+ },
272
+ }
273
+ end
274
+
275
+ include_examples 'attempted/effective deploy'
276
+
277
+ context 'dry run' do
278
+ let(:command) { (super() + ['--dry-run']) }
279
+ include_examples 'no effective deploy'
280
+ end
281
+ end
282
+
283
+ context 'requested deploy config exists, but has no kind' do
284
+ let(:config) do
285
+ {
286
+ deploy: {
287
+ production: {
288
+ dst: 'remote',
289
+ },
290
+ },
291
+ }
292
+ end
293
+
294
+ include_examples 'attempted/effective deploy'
295
+ include_examples 'missing kind warning'
296
+
297
+ context 'dry run' do
298
+ let(:command) { (super() + ['--dry-run']) }
299
+ include_examples 'no effective deploy'
300
+ end
301
+ end
302
+ end
303
+
304
+ context 'non-default target, specified as argument' do
305
+ let(:command) { %w(deploy production) }
306
+ include_examples 'deploy with non-default target'
307
+ end
308
+
309
+ context 'non-default target, specified as option (--target)' do
310
+ let(:command) { %w(deploy --target production) }
311
+ include_examples 'deploy with non-default target'
312
+ end
313
+
314
+ context 'multiple targets specified' do
315
+ let(:command) { %w(deploy --target staging production) }
316
+
317
+ it 'errors' do
318
+ expect { run }.to raise_error(
319
+ Nanoc::Int::Errors::GenericTrivial,
320
+ 'Only one deployment target can be specified on the command line.',
321
+ )
322
+ end
323
+ end
324
+ end
325
+ end
326
+ end
327
+ end
@@ -0,0 +1,54 @@
1
+ describe Nanoc::CLI::Commands::Shell, site: true, stdio: true do
2
+ describe '#run' do
3
+ before do
4
+ # Prevent double-loading
5
+ expect(Nanoc::CLI).to receive(:setup)
6
+ end
7
+
8
+ it 'can be invoked' do
9
+ context = Object.new
10
+ allow(Nanoc::Int::Context).to receive(:new).with(anything).and_return(context)
11
+ expect(context).to receive(:pry)
12
+
13
+ Nanoc::CLI.run(['shell'])
14
+ end
15
+ end
16
+
17
+ describe '#env_for_site' do
18
+ subject { described_class.env_for_site(site) }
19
+
20
+ before do
21
+ File.write('content/hello.md', 'Hello!')
22
+ File.write('layouts/default.erb', '<title>MY SITE!</title><%= yield %>')
23
+ end
24
+
25
+ let(:site) do
26
+ Nanoc::Int::SiteLoader.new.new_from_cwd
27
+ end
28
+
29
+ it 'returns views' do
30
+ expect(subject[:items]).to be_a(Nanoc::ItemCollectionWithRepsView)
31
+ expect(subject[:layouts]).to be_a(Nanoc::LayoutCollectionView)
32
+ expect(subject[:config]).to be_a(Nanoc::ConfigView)
33
+ end
34
+
35
+ it 'returns correct items' do
36
+ expect(subject[:items].size).to eq(1)
37
+ expect(subject[:items].first.identifier.to_s).to eq('/hello.md')
38
+ end
39
+
40
+ it 'returns correct layouts' do
41
+ expect(subject[:layouts].size).to eq(1)
42
+ expect(subject[:layouts].first.identifier.to_s).to eq('/default.erb')
43
+ end
44
+
45
+ it 'returns items with reps' do
46
+ expect(subject[:items].first.reps).not_to be_nil
47
+ expect(subject[:items].first.reps.first.name).to eq(:default)
48
+ end
49
+
50
+ it 'returns items with rep paths' do
51
+ expect(subject[:items].first.reps.first.path).to eq('/hello.md')
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,126 @@
1
+ describe Nanoc::CLI::Commands::ShowData, stdio: true do
2
+ describe '#print_item_dependencies' do
3
+ subject { runner.send(:print_item_dependencies, items, dependency_store) }
4
+
5
+ let(:runner) do
6
+ described_class.new(options, arguments, command)
7
+ end
8
+
9
+ let(:options) { {} }
10
+ let(:arguments) { [] }
11
+ let(:command) { double(:command) }
12
+
13
+ let(:items) do
14
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |ic|
15
+ ic << item_about
16
+ ic << item_dog
17
+ ic << item_other
18
+ end
19
+ end
20
+
21
+ let(:item_about) { Nanoc::Int::Item.new('About Me', {}, '/about.md') }
22
+ let(:item_dog) { Nanoc::Int::Item.new('About My Dog', {}, '/dog.md') }
23
+ let(:item_other) { Nanoc::Int::Item.new('Raw Data', {}, '/other.dat') }
24
+
25
+ let(:config) { Nanoc::Int::Configuration.new }
26
+
27
+ let(:dependency_store) do
28
+ Nanoc::Int::DependencyStore.new(objects)
29
+ end
30
+
31
+ let(:objects) do
32
+ items.to_a + layouts.to_a
33
+ end
34
+
35
+ let(:layouts) do
36
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |ic|
37
+ end
38
+ end
39
+
40
+ it 'prints a legend' do
41
+ expect { subject }.to output(%r{Item dependencies =+\n\nLegend:}).to_stdout
42
+ end
43
+
44
+ context 'no dependencies' do
45
+ it 'outputs no dependencies for /about.md' do
46
+ expect { subject }.to output(%r{^item /about.md depends on:\n \(nothing\)$}m).to_stdout
47
+ end
48
+
49
+ it 'outputs no dependencies for /dog.md' do
50
+ expect { subject }.to output(%r{^item /dog.md depends on:\n \(nothing\)$}m).to_stdout
51
+ end
52
+
53
+ it 'outputs no dependencies for /other.dat' do
54
+ expect { subject }.to output(%r{^item /other.dat depends on:\n \(nothing\)$}m).to_stdout
55
+ end
56
+ end
57
+
58
+ context 'dependency (without props) from about to dog' do
59
+ before do
60
+ dependency_store.record_dependency(item_dog, item_about)
61
+ end
62
+
63
+ it 'outputs no dependencies for /about.md' do
64
+ expect { subject }.to output(%r{^item /about.md depends on:\n \(nothing\)$}m).to_stdout
65
+ end
66
+
67
+ it 'outputs dependencies for /dog.md' do
68
+ expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(racp\) /about.md$}m).to_stdout
69
+ end
70
+
71
+ it 'outputs no dependencies for /other.dat' do
72
+ expect { subject }.to output(%r{^item /other.dat depends on:\n \(nothing\)$}m).to_stdout
73
+ end
74
+ end
75
+
76
+ context 'dependency (with raw_content prop) from about to dog' do
77
+ before do
78
+ dependency_store.record_dependency(item_dog, item_about, raw_content: true)
79
+ end
80
+
81
+ it 'outputs dependencies for /dog.md' do
82
+ expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(r___\) /about.md$}m).to_stdout
83
+ end
84
+ end
85
+
86
+ context 'dependency (with attributes prop) from about to dog' do
87
+ before do
88
+ dependency_store.record_dependency(item_dog, item_about, attributes: true)
89
+ end
90
+
91
+ it 'outputs dependencies for /dog.md' do
92
+ expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(_a__\) /about.md$}m).to_stdout
93
+ end
94
+ end
95
+
96
+ context 'dependency (with compiled_content prop) from about to dog' do
97
+ before do
98
+ dependency_store.record_dependency(item_dog, item_about, compiled_content: true)
99
+ end
100
+
101
+ it 'outputs dependencies for /dog.md' do
102
+ expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(__c_\) /about.md$}m).to_stdout
103
+ end
104
+ end
105
+
106
+ context 'dependency (with path prop) from about to dog' do
107
+ before do
108
+ dependency_store.record_dependency(item_dog, item_about, path: true)
109
+ end
110
+
111
+ it 'outputs dependencies for /dog.md' do
112
+ expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(___p\) /about.md$}m).to_stdout
113
+ end
114
+ end
115
+
116
+ context 'dependency (with multiple props) from about to dog' do
117
+ before do
118
+ dependency_store.record_dependency(item_dog, item_about, attributes: true, raw_content: true)
119
+ end
120
+
121
+ it 'outputs dependencies for /dog.md' do
122
+ expect { subject }.to output(%r{^item /dog.md depends on:\n \[ item \] \(ra__\) /about.md$}m).to_stdout
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,112 @@
1
+ describe Nanoc::CLI::Commands::ShowRules, stdio: true do
2
+ describe '#run' do
3
+ subject { runner.run }
4
+
5
+ let(:runner) do
6
+ described_class.new(options, arguments, command).tap do |runner|
7
+ runner.site = site
8
+ end
9
+ end
10
+
11
+ let(:options) { {} }
12
+
13
+ let(:arguments) { [] }
14
+
15
+ let(:command) { double(:command) }
16
+
17
+ let(:site) do
18
+ double(
19
+ :site,
20
+ items: items,
21
+ layouts: layouts,
22
+ compiler: compiler,
23
+ )
24
+ end
25
+
26
+ let(:items) do
27
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |ic|
28
+ ic << Nanoc::Int::Item.new('About Me', {}, '/about.md')
29
+ ic << Nanoc::Int::Item.new('About My Dog', {}, '/dog.md')
30
+ ic << Nanoc::Int::Item.new('Raw Data', {}, '/other.dat')
31
+ end
32
+ end
33
+
34
+ let(:reps) do
35
+ Nanoc::Int::ItemRepRepo.new.tap do |reps|
36
+ reps << Nanoc::Int::ItemRep.new(items['/about.md'], :default)
37
+ reps << Nanoc::Int::ItemRep.new(items['/about.md'], :text)
38
+ reps << Nanoc::Int::ItemRep.new(items['/dog.md'], :default)
39
+ reps << Nanoc::Int::ItemRep.new(items['/dog.md'], :text)
40
+ reps << Nanoc::Int::ItemRep.new(items['/other.dat'], :default)
41
+ end
42
+ end
43
+
44
+ let(:layouts) do
45
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |ic|
46
+ ic << Nanoc::Int::Layout.new('Default', {}, '/default.erb')
47
+ ic << Nanoc::Int::Layout.new('Article', {}, '/article.haml')
48
+ ic << Nanoc::Int::Layout.new('Other', {}, '/other.xyzzy')
49
+ end
50
+ end
51
+
52
+ let(:config) { Nanoc::Int::Configuration.new }
53
+
54
+ let(:action_provider) { double(:action_provider, rules_collection: rules_collection) }
55
+ let(:compiler) { double(:compiler, action_provider: action_provider, reps: reps) }
56
+
57
+ let(:rules_collection) do
58
+ Nanoc::RuleDSL::RulesCollection.new.tap do |rc|
59
+ rc.add_item_compilation_rule(
60
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/dog.*'), :default, proc {}),
61
+ )
62
+ rc.add_item_compilation_rule(
63
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/*.md'), :default, proc {}),
64
+ )
65
+ rc.add_item_compilation_rule(
66
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/**/*'), :text, proc {}),
67
+ )
68
+
69
+ rc.layout_filter_mapping[Nanoc::Int::Pattern.from('/*.haml')] = [:haml, {}]
70
+ rc.layout_filter_mapping[Nanoc::Int::Pattern.from('/*.erb')] = [:erb, {}]
71
+ end
72
+ end
73
+
74
+ let(:expected_out) do
75
+ <<-EOS
76
+ \e[1m\e[33mItem /about.md\e[0m:
77
+ Rep default: /*.md
78
+ Rep text: /**/*
79
+
80
+ \e[1m\e[33mItem /dog.md\e[0m:
81
+ Rep default: /dog.*
82
+ Rep text: /**/*
83
+
84
+ \e[1m\e[33mItem /other.dat\e[0m:
85
+ Rep default: (none)
86
+
87
+ \e[1m\e[33mLayout /article.haml\e[0m:
88
+ /*.haml
89
+
90
+ \e[1m\e[33mLayout /default.erb\e[0m:
91
+ /*.erb
92
+
93
+ \e[1m\e[33mLayout /other.xyzzy\e[0m:
94
+ (none)
95
+
96
+ EOS
97
+ .gsub(/^ {8}/, '')
98
+ end
99
+
100
+ before do
101
+ expect(compiler).to receive(:build_reps).once
102
+ end
103
+
104
+ it 'writes item and layout rules to stdout' do
105
+ expect { subject }.to output(expected_out).to_stdout
106
+ end
107
+
108
+ it 'writes status informaion to stderr' do
109
+ expect { subject }.to output("Loading site… done\n").to_stderr
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,58 @@
1
+ describe Nanoc::CLI::Commands::View, site: true, stdio: true do
2
+ describe '#run' do
3
+ def run_nanoc_cmd(cmd)
4
+ pid = fork { Nanoc::CLI.run(cmd) }
5
+
6
+ # Wait for server to start up
7
+ 20.times do |i|
8
+ begin
9
+ Net::HTTP.get('127.0.0.1', '/', 50_385)
10
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET
11
+ sleep(0.1 * 1.2**i)
12
+ retry
13
+ end
14
+ break
15
+ end
16
+
17
+ yield
18
+ ensure
19
+ Process.kill('TERM', pid)
20
+ end
21
+
22
+ context 'default configuration' do
23
+ it 'serves /index.html as /' do
24
+ File.write('output/index.html', 'Hello there! Nanoc loves you! <3')
25
+ run_nanoc_cmd(['view', '--port', '50385']) do
26
+ expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql('Hello there! Nanoc loves you! <3')
27
+ end
28
+ end
29
+
30
+ it 'does not serve /index.xhtml as /' do
31
+ File.write('output/index.xhtml', 'Hello there! Nanoc loves you! <3')
32
+ run_nanoc_cmd(['view', '--port', '50385']) do
33
+ expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n")
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'index_filenames including index.xhtml' do
39
+ before do
40
+ File.write('nanoc.yaml', 'index_filenames: [index.xhtml]')
41
+ end
42
+
43
+ it 'serves /index.xhtml as /' do
44
+ File.write('output/index.xhtml', 'Hello there! Nanoc loves you! <3')
45
+ run_nanoc_cmd(['view', '--port', '50385']) do
46
+ expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql('Hello there! Nanoc loves you! <3')
47
+ end
48
+ end
49
+ end
50
+
51
+ it 'does not serve other files as /' do
52
+ File.write('output/index.html666', 'Hello there! Nanoc loves you! <3')
53
+ run_nanoc_cmd(['view', '--port', '50385']) do
54
+ expect(Net::HTTP.get('127.0.0.1', '/', 50_385)).to eql("File not found: /\n")
55
+ end
56
+ end
57
+ end
58
+ end