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,131 @@
1
+ describe Nanoc::Int::RuleMemory do
2
+ let(:rule_memory) { described_class.new(rep) }
3
+ let(:rep) { double(:rep) }
4
+
5
+ describe '#size' do
6
+ subject { rule_memory.size }
7
+
8
+ context 'no actions' do
9
+ it { is_expected.to eql(0) }
10
+ end
11
+
12
+ context 'some actions' do
13
+ before do
14
+ rule_memory.add_filter(:foo, {})
15
+ end
16
+
17
+ it { is_expected.to eql(1) }
18
+ end
19
+ end
20
+
21
+ describe '#[]' do
22
+ subject { rule_memory[index] }
23
+ let(:index) { 0 }
24
+
25
+ context 'no actions' do
26
+ it { is_expected.to be_nil }
27
+ end
28
+
29
+ context 'some actions' do
30
+ before do
31
+ rule_memory.add_filter(:foo, {})
32
+ end
33
+
34
+ it { is_expected.to be_a(Nanoc::Int::ProcessingActions::Filter) }
35
+ end
36
+ end
37
+
38
+ describe '#add_filter' do
39
+ example do
40
+ rule_memory.add_filter(:foo, donkey: 123)
41
+
42
+ expect(rule_memory.size).to eql(1)
43
+ expect(rule_memory[0]).to be_a(Nanoc::Int::ProcessingActions::Filter)
44
+ expect(rule_memory[0].filter_name).to eql(:foo)
45
+ expect(rule_memory[0].params).to eql(donkey: 123)
46
+ end
47
+ end
48
+
49
+ describe '#add_layout' do
50
+ example do
51
+ rule_memory.add_layout('/foo.*', donkey: 123)
52
+
53
+ expect(rule_memory.size).to eql(1)
54
+ expect(rule_memory[0]).to be_a(Nanoc::Int::ProcessingActions::Layout)
55
+ expect(rule_memory[0].layout_identifier).to eql('/foo.*')
56
+ expect(rule_memory[0].params).to eql(donkey: 123)
57
+ end
58
+ end
59
+
60
+ describe '#add_snapshot' do
61
+ context 'snapshot does not yet exist' do
62
+ example do
63
+ rule_memory.add_snapshot(:before_layout, '/foo.md')
64
+
65
+ expect(rule_memory.size).to eql(1)
66
+ expect(rule_memory[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
67
+ expect(rule_memory[0].snapshot_name).to eql(:before_layout)
68
+ expect(rule_memory[0].path).to eql('/foo.md')
69
+ end
70
+ end
71
+
72
+ context 'snapshot already exist' do
73
+ before do
74
+ rule_memory.add_snapshot(:before_layout, '/bar.md')
75
+ end
76
+
77
+ it 'raises' do
78
+ expect { rule_memory.add_snapshot(:before_layout, '/foo.md') }
79
+ .to raise_error(Nanoc::Int::Errors::CannotCreateMultipleSnapshotsWithSameName)
80
+ end
81
+ end
82
+ end
83
+
84
+ describe '#each' do
85
+ before do
86
+ rule_memory.add_filter(:erb, awesomeness: 'high')
87
+ rule_memory.add_snapshot(:bar, '/foo.md')
88
+ rule_memory.add_layout('/default.erb', somelayoutparam: 'yes')
89
+ end
90
+
91
+ example do
92
+ actions = []
93
+ rule_memory.each { |a| actions << a }
94
+ expect(actions.size).to eq(3)
95
+ end
96
+ end
97
+
98
+ describe '#map' do
99
+ before do
100
+ rule_memory.add_filter(:erb, awesomeness: 'high')
101
+ rule_memory.add_snapshot(:bar, '/foo.md')
102
+ rule_memory.add_layout('/default.erb', somelayoutparam: 'yes')
103
+ end
104
+
105
+ example do
106
+ res = rule_memory.map { Nanoc::Int::ProcessingActions::Filter.new(:donkey, {}) }
107
+ expect(res.to_a.size).to eq(3)
108
+ expect(res.to_a).to all(be_a(Nanoc::Int::ProcessingActions::Filter))
109
+ end
110
+ end
111
+
112
+ describe '#serialize' do
113
+ subject { rule_memory.serialize }
114
+
115
+ before do
116
+ rule_memory.add_filter(:erb, awesomeness: 'high')
117
+ rule_memory.add_snapshot(:bar, '/foo.md')
118
+ rule_memory.add_layout('/default.erb', somelayoutparam: 'yes')
119
+ end
120
+
121
+ example do
122
+ expect(subject).to eql(
123
+ [
124
+ [:filter, :erb, 'PeWUm2PtXYtqeHJdTqnY7kkwAow='],
125
+ [:snapshot, :bar, true, '/foo.md'],
126
+ [:layout, '/default.erb', '97LAe1pYTLKczxBsu+x4MmvqdkU='],
127
+ ],
128
+ )
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,73 @@
1
+ describe Nanoc::Int::Site do
2
+ describe '#freeze' do
3
+ let(:site) do
4
+ described_class.new(
5
+ config: config,
6
+ code_snippets: code_snippets,
7
+ items: items,
8
+ layouts: layouts,
9
+ )
10
+ end
11
+
12
+ let(:config) do
13
+ Nanoc::Int::Configuration.new.with_defaults
14
+ end
15
+
16
+ let(:code_snippets) do
17
+ [
18
+ Nanoc::Int::CodeSnippet.new('FOO = 123', 'hello.rb'),
19
+ Nanoc::Int::CodeSnippet.new('BAR = 123', 'hi.rb'),
20
+ ]
21
+ end
22
+
23
+ let(:items) do
24
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |coll|
25
+ coll << Nanoc::Int::Item.new('foo', {}, '/foo.md')
26
+ coll << Nanoc::Int::Item.new('bar', {}, '/bar.md')
27
+ end
28
+ end
29
+
30
+ let(:layouts) do
31
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |coll|
32
+ coll << Nanoc::Int::Layout.new('foo', {}, '/foo.md')
33
+ coll << Nanoc::Int::Layout.new('bar', {}, '/bar.md')
34
+ end
35
+ end
36
+
37
+ before do
38
+ site.freeze
39
+ end
40
+
41
+ it 'freezes the configuration' do
42
+ expect(site.config).to be_frozen
43
+ end
44
+
45
+ it 'freezes the configuration contents' do
46
+ expect(site.config[:output_dir]).to be_frozen
47
+ end
48
+
49
+ it 'freezes items collection' do
50
+ expect(site.items).to be_frozen
51
+ end
52
+
53
+ it 'freezes individual items' do
54
+ expect(site.items).to all(be_frozen)
55
+ end
56
+
57
+ it 'freezes layouts collection' do
58
+ expect(site.layouts).to be_frozen
59
+ end
60
+
61
+ it 'freezes individual layouts' do
62
+ expect(site.layouts).to all(be_frozen)
63
+ end
64
+
65
+ it 'freezes code snippets collection' do
66
+ expect(site.code_snippets).to be_frozen
67
+ end
68
+
69
+ it 'freezes individual code snippets' do
70
+ expect(site.code_snippets).to all(be_frozen)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,107 @@
1
+ describe Nanoc::Feature do
2
+ describe '.enabled?' do
3
+ subject { described_class.enabled?(feature_name) }
4
+
5
+ let(:feature_name) { 'magic' }
6
+
7
+ before do
8
+ Nanoc::Feature.reset_caches
9
+ ENV['NANOC_FEATURES'] = ''
10
+ end
11
+
12
+ context 'not set' do
13
+ it { is_expected.not_to be }
14
+ end
15
+
16
+ context 'set to list not including feature' do
17
+ before { ENV['NANOC_FEATURES'] = 'foo,bar' }
18
+ it { is_expected.not_to be }
19
+ end
20
+
21
+ context 'set to all' do
22
+ before { ENV['NANOC_FEATURES'] = 'all' }
23
+ it { is_expected.to be }
24
+ end
25
+
26
+ context 'set to list including feature' do
27
+ before { ENV['NANOC_FEATURES'] = 'foo,magic,bar' }
28
+ it { is_expected.to be }
29
+ end
30
+ end
31
+
32
+ describe '.enable' do
33
+ subject do
34
+ described_class.enable(feature_name) do
35
+ Nanoc::Feature.enabled?(feature_name)
36
+ end
37
+ end
38
+
39
+ let(:feature_name) { 'magic' }
40
+
41
+ before do
42
+ Nanoc::Feature.reset_caches
43
+ ENV['NANOC_FEATURES'] = ''
44
+ end
45
+
46
+ context 'not set' do
47
+ it { is_expected.to be }
48
+
49
+ it 'unsets afterwards' do
50
+ expect(Nanoc::Feature.enabled?(feature_name)).not_to be
51
+ end
52
+ end
53
+
54
+ context 'set to list not including feature' do
55
+ before { ENV['NANOC_FEATURES'] = 'foo,bar' }
56
+ it { is_expected.to be }
57
+
58
+ it 'unsets afterwards' do
59
+ expect(Nanoc::Feature.enabled?(feature_name)).not_to be
60
+ end
61
+ end
62
+
63
+ context 'set to all' do
64
+ before { ENV['NANOC_FEATURES'] = 'all' }
65
+ it { is_expected.to be }
66
+ end
67
+
68
+ context 'set to list including feature' do
69
+ before { ENV['NANOC_FEATURES'] = 'foo,magic,bar' }
70
+ it { is_expected.to be }
71
+ end
72
+ end
73
+
74
+ describe '.all_outdated' do
75
+ it 'refuses outdated features' do
76
+ # If this spec fails, there are features marked as experimental in the previous minor or major
77
+ # release, but not in the current one. Either remove the feature, or mark it as experimental
78
+ # in the current release.
79
+ expect(Nanoc::Feature.all_outdated).to be_empty
80
+ end
81
+
82
+ describe 'fake outdated features' do
83
+ before { Nanoc::Feature.define('abc', version: '4.2.x') }
84
+ after { Nanoc::Feature.undefine('abc') }
85
+
86
+ it 'detects outdated features' do
87
+ expect(Nanoc::Feature.all_outdated).to eq(['abc'])
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '.define and .undefine' do
93
+ let(:feature_name) { 'testing123' }
94
+ after { Nanoc::Feature.undefine(feature_name) if defined?(Nanoc::Feature::TESTING123) }
95
+
96
+ it 'can define' do
97
+ Nanoc::Feature.define(feature_name, version: '4.3.x')
98
+ expect(Nanoc::Feature::TESTING123).not_to be_nil
99
+ end
100
+
101
+ it 'can undefine' do
102
+ Nanoc::Feature.define(feature_name, version: '4.3.x')
103
+ Nanoc::Feature.undefine(feature_name)
104
+ expect { Nanoc::Feature::TESTING123 }.to raise_error(NameError)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,99 @@
1
+ describe Nanoc::Filter do
2
+ describe '.define' do
3
+ context 'simple filter' do
4
+ let(:filter_name) { 'b5355bbb4d772b9853d21be57da614dba521dbbb' }
5
+ let(:filter_class) { Nanoc::Filter.named(filter_name) }
6
+
7
+ before do
8
+ Nanoc::Filter.define(filter_name) do |content, _params|
9
+ content.upcase
10
+ end
11
+ end
12
+
13
+ it 'defines a filter' do
14
+ expect(filter_class).not_to be_nil
15
+ end
16
+
17
+ it 'defines a callable filter' do
18
+ expect(filter_class.new.run('foo', {})).to eql('FOO')
19
+ end
20
+ end
21
+
22
+ context 'filter that accesses assigns' do
23
+ let(:filter_name) { 'd7ed105d460e99a3d38f46af023d9490c140fdd9' }
24
+ let(:filter_class) { Nanoc::Filter.named(filter_name) }
25
+ let(:filter) { filter_class.new(assigns) }
26
+ let(:assigns) { { animal: 'Giraffe' } }
27
+
28
+ before do
29
+ Nanoc::Filter.define(filter_name) do |_content, _params|
30
+ @animal
31
+ end
32
+ end
33
+
34
+ it 'can access assigns' do
35
+ expect(filter.setup_and_run(:__irrelevant__, {})).to eq('Giraffe')
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#depend_on' do
41
+ subject { filter.depend_on(item_views) }
42
+
43
+ let(:filter) { Nanoc::Filters::ERB.new(assigns) }
44
+ let(:item_views) { [item_view] }
45
+
46
+ let(:item) { Nanoc::Int::Item.new('foo', {}, '/stuff.md') }
47
+ let(:item_view) { Nanoc::ItemWithRepsView.new(item, view_context) }
48
+ let(:rep) { Nanoc::Int::ItemRep.new(item, :default) }
49
+
50
+ let(:view_context) do
51
+ Nanoc::ViewContext.new(
52
+ reps: reps,
53
+ items: double(:items),
54
+ dependency_tracker: dependency_tracker,
55
+ compilation_context: double(:compilation_context),
56
+ )
57
+ end
58
+
59
+ let(:dependency_tracker) { double(:dependency_tracker) }
60
+
61
+ let(:reps) { Nanoc::Int::ItemRepRepo.new }
62
+
63
+ let(:assigns) do
64
+ {
65
+ item: item_view,
66
+ }
67
+ end
68
+
69
+ before do
70
+ reps << rep
71
+
72
+ expect(dependency_tracker).to receive(:bounce).with(item, compiled_content: true)
73
+ end
74
+
75
+ context 'rep is compiled' do
76
+ before do
77
+ rep.compiled = true
78
+ end
79
+
80
+ example do
81
+ expect { subject }.not_to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
82
+ end
83
+ end
84
+
85
+ context 'rep is not compiled' do
86
+ example do
87
+ fiber = Fiber.new { subject }
88
+
89
+ # resume 1
90
+ res = fiber.resume
91
+ expect(res).to be_a(Nanoc::Int::Errors::UnmetDependency)
92
+ expect(res.rep).to eql(rep)
93
+
94
+ # resume 2
95
+ expect(fiber.resume).not_to be_a(Nanoc::Int::Errors::UnmetDependency)
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,131 @@
1
+ describe Nanoc::Int::ItemRepWriter do
2
+ describe '#write' do
3
+ let(:raw_path) { 'output/blah.dat' }
4
+
5
+ let(:item) { Nanoc::Int::Item.new(orig_content, {}, '/') }
6
+
7
+ let(:item_rep) do
8
+ Nanoc::Int::ItemRep.new(item, :default).tap do |ir|
9
+ ir.snapshot_contents = snapshot_contents
10
+ ir.raw_paths = raw_paths
11
+ end
12
+ end
13
+
14
+ let(:snapshot_contents) do
15
+ {
16
+ last: Nanoc::Int::TextualContent.new('last content'),
17
+ donkey: Nanoc::Int::TextualContent.new('donkey content'),
18
+ }
19
+ end
20
+
21
+ let(:snapshot_name) { :donkey }
22
+
23
+ let(:raw_paths) do
24
+ { snapshot_name => raw_path }
25
+ end
26
+
27
+ subject { described_class.new.write(item_rep, snapshot_name) }
28
+
29
+ before do
30
+ expect(File.directory?('output')).to be_falsy
31
+ end
32
+
33
+ context 'binary item rep' do
34
+ let(:orig_content) { Nanoc::Int::BinaryContent.new(File.expand_path('foo.dat')) }
35
+
36
+ let(:snapshot_contents) do
37
+ {
38
+ last: Nanoc::Int::BinaryContent.new(File.expand_path('input-last.dat')),
39
+ donkey: Nanoc::Int::BinaryContent.new(File.expand_path('input-donkey.dat')),
40
+ }
41
+ end
42
+
43
+ before do
44
+ File.write(snapshot_contents[:last].filename, 'binary last stuff')
45
+ File.write(snapshot_contents[:donkey].filename, 'binary donkey stuff')
46
+ end
47
+
48
+ it 'copies' do
49
+ expect(Nanoc::Int::NotificationCenter).to receive(:post)
50
+ .with(:will_write_rep, item_rep, 'output/blah.dat')
51
+ expect(Nanoc::Int::NotificationCenter).to receive(:post)
52
+ .with(:rep_written, item_rep, 'output/blah.dat', true, true)
53
+
54
+ subject
55
+
56
+ expect(File.read('output/blah.dat')).to eql('binary donkey stuff')
57
+ end
58
+
59
+ context 'output file already exists' do
60
+ let(:old_mtime) { Time.at((Time.now - 600).to_i) }
61
+
62
+ before do
63
+ FileUtils.mkdir_p('output')
64
+ File.write('output/blah.dat', old_content)
65
+ FileUtils.touch('output/blah.dat', mtime: old_mtime)
66
+ end
67
+
68
+ context 'file is identical' do
69
+ let(:old_content) { 'binary donkey stuff' }
70
+
71
+ it 'keeps mtime' do
72
+ subject
73
+ expect(File.mtime('output/blah.dat')).to eql(old_mtime)
74
+ end
75
+ end
76
+
77
+ context 'file is not identical' do
78
+ let(:old_content) { 'other binary donkey stuff' }
79
+
80
+ it 'updates mtime' do
81
+ subject
82
+ expect(File.mtime('output/blah.dat')).to be > (Time.now - 1)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ context 'textual item rep' do
89
+ let(:orig_content) { Nanoc::Int::TextualContent.new('Hallo Welt') }
90
+
91
+ it 'writes' do
92
+ expect(Nanoc::Int::NotificationCenter).to receive(:post)
93
+ .with(:will_write_rep, item_rep, 'output/blah.dat')
94
+ expect(Nanoc::Int::NotificationCenter).to receive(:post)
95
+ .with(:rep_written, item_rep, 'output/blah.dat', true, true)
96
+
97
+ subject
98
+
99
+ expect(File.read('output/blah.dat')).to eql('donkey content')
100
+ end
101
+
102
+ context 'output file already exists' do
103
+ let(:old_mtime) { Time.at((Time.now - 600).to_i) }
104
+
105
+ before do
106
+ FileUtils.mkdir_p('output')
107
+ File.write('output/blah.dat', old_content)
108
+ FileUtils.touch('output/blah.dat', mtime: old_mtime)
109
+ end
110
+
111
+ context 'file is identical' do
112
+ let(:old_content) { 'donkey content' }
113
+
114
+ it 'keeps mtime' do
115
+ subject
116
+ expect(File.mtime('output/blah.dat')).to eql(old_mtime)
117
+ end
118
+ end
119
+
120
+ context 'file is not identical' do
121
+ let(:old_content) { 'other donkey content' }
122
+
123
+ it 'updates mtime' do
124
+ subject
125
+ expect(File.mtime('output/blah.dat')).to be > (Time.now - 1)
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,29 @@
1
+ describe Nanoc::Int::PluginRegistry do
2
+ describe '.identifier(s)' do
3
+ let(:identifier) { :ce79f6b8ddb22233e9aaf7d8f011689492acf02f }
4
+
5
+ context 'direct subclass' do
6
+ example do
7
+ klass =
8
+ Class.new(Nanoc::Filter) do
9
+ identifier :plugin_registry_spec
10
+ end
11
+
12
+ expect(klass.identifier).to eql(:plugin_registry_spec)
13
+ end
14
+ end
15
+
16
+ context 'indirect subclass' do
17
+ example do
18
+ superclass = Class.new(Nanoc::Filter)
19
+
20
+ klass =
21
+ Class.new(superclass) do
22
+ identifier :plugin_registry_spec
23
+ end
24
+
25
+ expect(klass.identifier).to eql(:plugin_registry_spec)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,133 @@
1
+ describe Nanoc::Int::ChecksumStore do
2
+ let(:store) { described_class.new(objects: objects) }
3
+
4
+ let(:objects) { [item, code_snippet] }
5
+
6
+ let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') }
7
+ let(:other_item) { Nanoc::Int::Item.new('asdf', {}, '/sneaky.md') }
8
+
9
+ let(:code_snippet) { Nanoc::Int::CodeSnippet.new('def hi ; end', 'lib/foo.rb') }
10
+ let(:other_code_snippet) { Nanoc::Int::CodeSnippet.new('def ho ; end', 'lib/bar.rb') }
11
+
12
+ context 'nothing added' do
13
+ it 'has no checksum' do
14
+ expect(store[item]).to be_nil
15
+ end
16
+
17
+ it 'has no content checksum' do
18
+ expect(store.content_checksum_for(item)).to be_nil
19
+ end
20
+
21
+ it 'has no attributes checksum' do
22
+ expect(store.attributes_checksum_for(item)).to be_nil
23
+ end
24
+ end
25
+
26
+ context 'setting content on known non-document' do
27
+ before { store.add(code_snippet) }
28
+
29
+ it 'has checksum' do
30
+ expect(store[code_snippet]).not_to be_nil
31
+ end
32
+
33
+ it 'has no content checksum' do
34
+ expect(store.content_checksum_for(code_snippet)).to be_nil
35
+ end
36
+
37
+ it 'has no attributes checksum' do
38
+ expect(store.attributes_checksum_for(code_snippet)).to be_nil
39
+ end
40
+
41
+ context 'after storing and loading' do
42
+ before do
43
+ store.store
44
+ store.load
45
+ end
46
+
47
+ it 'has checksum' do
48
+ expect(store[code_snippet]).not_to be_nil
49
+ end
50
+ end
51
+ end
52
+
53
+ context 'setting content on unknown non-document' do
54
+ before { store.add(other_code_snippet) }
55
+
56
+ it 'has checksum' do
57
+ expect(store[other_code_snippet]).not_to be_nil
58
+ end
59
+
60
+ it 'has no content checksum' do
61
+ expect(store.content_checksum_for(other_code_snippet)).to be_nil
62
+ end
63
+
64
+ it 'has no attributes checksum' do
65
+ expect(store.attributes_checksum_for(other_code_snippet)).to be_nil
66
+ end
67
+
68
+ context 'after storing and loading' do
69
+ before do
70
+ store.store
71
+ store.load
72
+ end
73
+
74
+ it 'has no checksum' do
75
+ expect(store[other_code_snippet]).to be_nil
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'setting content on known item' do
81
+ before { store.add(item) }
82
+
83
+ it 'has checksum' do
84
+ expect(store[item]).not_to be_nil
85
+ end
86
+
87
+ it 'has content checksum' do
88
+ expect(store.content_checksum_for(item)).not_to be_nil
89
+ end
90
+
91
+ it 'has attributes checksum' do
92
+ expect(store.attributes_checksum_for(item)).not_to be_nil
93
+ end
94
+
95
+ context 'after storing and loading' do
96
+ before do
97
+ store.store
98
+ store.load
99
+ end
100
+
101
+ it 'has checksum' do
102
+ expect(store[item]).not_to be_nil
103
+ end
104
+ end
105
+ end
106
+
107
+ context 'setting content on unknown item' do
108
+ before { store.add(other_item) }
109
+
110
+ it 'has checksum' do
111
+ expect(store[other_item]).not_to be_nil
112
+ end
113
+
114
+ it 'has content checksum' do
115
+ expect(store.content_checksum_for(other_item)).not_to be_nil
116
+ end
117
+
118
+ it 'has attributes checksum' do
119
+ expect(store.attributes_checksum_for(other_item)).not_to be_nil
120
+ end
121
+
122
+ context 'after storing and loading' do
123
+ before do
124
+ store.store
125
+ store.load
126
+ end
127
+
128
+ it 'has no checksum' do
129
+ expect(store[other_item]).to be_nil
130
+ end
131
+ end
132
+ end
133
+ end