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,177 @@
1
+ describe(Nanoc::RuleDSL::RuleContext) do
2
+ subject(:rule_context) do
3
+ described_class.new(rep: rep, site: site, executor: executor, view_context: view_context)
4
+ end
5
+
6
+ let(:item_identifier) { Nanoc::Identifier.new('/foo.md') }
7
+ let(:item) { Nanoc::Int::Item.new('content', {}, item_identifier) }
8
+ let(:config) { Nanoc::Int::Configuration.new }
9
+ let(:items) { Nanoc::Int::IdentifiableCollection.new(config) }
10
+ let(:layouts) { Nanoc::Int::IdentifiableCollection.new(config) }
11
+
12
+ let(:rep) { double(:rep, item: item) }
13
+ let(:site) { double(:site, items: items, layouts: layouts, config: config) }
14
+ let(:executor) { double(:executor) }
15
+ let(:reps) { double(:reps) }
16
+ let(:compilation_context) { double(:compilation_context) }
17
+ let(:view_context) { Nanoc::ViewContext.new(reps: reps, items: items, dependency_tracker: dependency_tracker, compilation_context: compilation_context) }
18
+ let(:dependency_tracker) { double(:dependency_tracker) }
19
+
20
+ describe '#initialize' do
21
+ it 'wraps objects in view classes' do
22
+ expect(subject.rep.class).to eql(Nanoc::ItemRepView)
23
+ expect(subject.item.class).to eql(Nanoc::ItemWithoutRepsView)
24
+ expect(subject.config.class).to eql(Nanoc::ConfigView)
25
+ expect(subject.layouts.class).to eql(Nanoc::LayoutCollectionView)
26
+ expect(subject.items.class).to eql(Nanoc::ItemCollectionWithoutRepsView)
27
+ end
28
+
29
+ it 'contains the right objects' do
30
+ expect(rule_context.rep.unwrap).to eql(rep)
31
+ expect(rule_context.item.unwrap).to eql(item)
32
+ expect(rule_context.config.unwrap).to eql(config)
33
+ expect(rule_context.layouts.unwrap).to eql(layouts)
34
+ expect(rule_context.items.unwrap).to eql(items)
35
+ end
36
+ end
37
+
38
+ describe '#item' do
39
+ subject { rule_context.item }
40
+
41
+ it 'is a view without reps access' do
42
+ expect(subject.class).to eql(Nanoc::ItemWithoutRepsView)
43
+ end
44
+
45
+ it 'contains the right item' do
46
+ expect(subject.unwrap).to eql(item)
47
+ end
48
+
49
+ context 'with legacy identifier and children/parent' do
50
+ let(:item_identifier) { Nanoc::Identifier.new('/foo/', type: :legacy) }
51
+
52
+ let(:parent_identifier) { Nanoc::Identifier.new('/', type: :legacy) }
53
+ let(:parent) { Nanoc::Int::Item.new('parent', {}, parent_identifier) }
54
+
55
+ let(:child_identifier) { Nanoc::Identifier.new('/foo/bar/', type: :legacy) }
56
+ let(:child) { Nanoc::Int::Item.new('child', {}, child_identifier) }
57
+
58
+ before do
59
+ items << item
60
+ items << parent
61
+ items << child
62
+ end
63
+
64
+ it 'has a parent' do
65
+ expect(subject.parent.unwrap).to eql(parent)
66
+ end
67
+
68
+ it 'wraps the parent in a view without reps access' do
69
+ expect(subject.parent.class).to eql(Nanoc::ItemWithoutRepsView)
70
+ expect(subject.parent).not_to respond_to(:compiled_content)
71
+ expect(subject.parent).not_to respond_to(:path)
72
+ expect(subject.parent).not_to respond_to(:reps)
73
+ end
74
+
75
+ it 'has children' do
76
+ expect(subject.children.map(&:unwrap)).to eql([child])
77
+ end
78
+
79
+ it 'wraps the children in a view without reps access' do
80
+ expect(subject.children.map(&:class)).to eql([Nanoc::ItemWithoutRepsView])
81
+ expect(subject.children[0]).not_to respond_to(:compiled_content)
82
+ expect(subject.children[0]).not_to respond_to(:path)
83
+ expect(subject.children[0]).not_to respond_to(:reps)
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '#items' do
89
+ subject { rule_context.items }
90
+
91
+ let(:item_identifier) { Nanoc::Identifier.new('/foo/', type: :legacy) }
92
+
93
+ let(:parent_identifier) { Nanoc::Identifier.new('/', type: :legacy) }
94
+ let(:parent) { Nanoc::Int::Item.new('parent', {}, parent_identifier) }
95
+
96
+ let(:child_identifier) { Nanoc::Identifier.new('/foo/bar/', type: :legacy) }
97
+ let(:child) { Nanoc::Int::Item.new('child', {}, child_identifier) }
98
+
99
+ before do
100
+ items << item
101
+ items << parent
102
+ items << child
103
+ end
104
+
105
+ it 'is a view without reps access' do
106
+ expect(subject.class).to eql(Nanoc::ItemCollectionWithoutRepsView)
107
+ end
108
+
109
+ it 'contains all items' do
110
+ expect(subject.unwrap).to match_array([item, parent, child])
111
+ end
112
+
113
+ it 'provides no rep access' do
114
+ expect(subject['/']).not_to be_nil
115
+ expect(subject['/']).not_to respond_to(:compiled_content)
116
+ expect(subject['/']).not_to respond_to(:path)
117
+ expect(subject['/']).not_to respond_to(:reps)
118
+
119
+ expect(subject['/foo/']).not_to be_nil
120
+ expect(subject['/foo/']).not_to respond_to(:compiled_content)
121
+ expect(subject['/foo/']).not_to respond_to(:path)
122
+ expect(subject['/foo/']).not_to respond_to(:reps)
123
+
124
+ expect(subject['/foo/bar/']).not_to be_nil
125
+ expect(subject['/foo/bar/']).not_to respond_to(:compiled_content)
126
+ expect(subject['/foo/bar/']).not_to respond_to(:path)
127
+ expect(subject['/foo/bar/']).not_to respond_to(:reps)
128
+ end
129
+ end
130
+
131
+ describe '#filter' do
132
+ subject { rule_context.filter(filter_name, filter_args) }
133
+
134
+ let(:filter_name) { :donkey }
135
+ let(:filter_args) { { color: 'grey' } }
136
+
137
+ it 'makes a request to the executor' do
138
+ expect(executor).to receive(:filter).with(filter_name, filter_args)
139
+ subject
140
+ end
141
+ end
142
+
143
+ describe '#layout' do
144
+ subject { rule_context.layout(layout_identifier, extra_filter_args) }
145
+
146
+ let(:layout_identifier) { '/default.*' }
147
+ let(:extra_filter_args) { { color: 'grey' } }
148
+
149
+ it 'makes a request to the executor' do
150
+ expect(executor).to receive(:layout).with(layout_identifier, extra_filter_args)
151
+ subject
152
+ end
153
+ end
154
+
155
+ describe '#snapshot' do
156
+ subject { rule_context.snapshot(snapshot_name, path: path) }
157
+
158
+ let(:snapshot_name) { :for_snippet }
159
+ let(:path) { '/foo.html' }
160
+
161
+ it 'makes a request to the executor' do
162
+ expect(executor).to receive(:snapshot).with(:for_snippet, path: '/foo.html')
163
+ subject
164
+ end
165
+ end
166
+
167
+ describe '#write' do
168
+ subject { rule_context.write(path) }
169
+
170
+ let(:path) { '/foo.html' }
171
+
172
+ it 'makes a request to the executor' do
173
+ expect(executor).to receive(:snapshot).with(:last, path: '/foo.html')
174
+ subject
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,233 @@
1
+ describe(Nanoc::RuleDSL::RuleMemoryCalculator) do
2
+ subject(:rule_memory_calculator) do
3
+ described_class.new(site: site, rules_collection: rules_collection)
4
+ end
5
+
6
+ let(:rules_collection) { Nanoc::RuleDSL::RulesCollection.new }
7
+ let(:site) { double(:site) }
8
+
9
+ describe '#[]' do
10
+ subject { rule_memory_calculator[obj] }
11
+
12
+ context 'with item rep' do
13
+ let(:obj) { Nanoc::Int::ItemRep.new(item, :csv) }
14
+
15
+ let(:item) { Nanoc::Int::Item.new('content', {}, Nanoc::Identifier.from('/list.md')) }
16
+ let(:config) { Nanoc::Int::Configuration.new.with_defaults }
17
+ let(:items) { Nanoc::Int::IdentifiableCollection.new(config) }
18
+ let(:layouts) { Nanoc::Int::IdentifiableCollection.new(config) }
19
+ let(:site) { double(:site, items: items, layouts: layouts, config: config, compiler: compiler) }
20
+ let(:compiler) { double(:compiler, compilation_context: compilation_context) }
21
+ let(:compilation_context) { double(:compilation_context) }
22
+ let(:view_context) { double(:view_context) }
23
+
24
+ before do
25
+ expect(compilation_context).to receive(:create_view_context).and_return(view_context)
26
+ end
27
+
28
+ context 'no rules exist' do
29
+ it 'raises error' do
30
+ error = Nanoc::RuleDSL::RuleMemoryCalculator::NoRuleMemoryForItemRepException
31
+ expect { subject }.to raise_error(error)
32
+ end
33
+ end
34
+
35
+ context 'rules exist' do
36
+ before do
37
+ rules_proc = proc do
38
+ filter :erb, speed: :over_9000
39
+ layout '/default.*'
40
+ filter :typohero
41
+ end
42
+ rule = Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, rules_proc)
43
+ rules_collection.add_item_compilation_rule(rule)
44
+ end
45
+
46
+ example do
47
+ subject
48
+
49
+ expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
50
+ expect(subject[0].snapshot_name).to eql(:raw)
51
+ expect(subject[0].path).to be_nil
52
+
53
+ expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Filter)
54
+ expect(subject[1].filter_name).to eql(:erb)
55
+ expect(subject[1].params).to eql(speed: :over_9000)
56
+
57
+ expect(subject[2]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
58
+ expect(subject[2].snapshot_name).to eql(:pre)
59
+ expect(subject[2].path).to be_nil
60
+
61
+ expect(subject[3]).to be_a(Nanoc::Int::ProcessingActions::Layout)
62
+ expect(subject[3].layout_identifier).to eql('/default.*')
63
+ expect(subject[3].params).to be_nil
64
+
65
+ expect(subject[4]).to be_a(Nanoc::Int::ProcessingActions::Filter)
66
+ expect(subject[4].filter_name).to eql(:typohero)
67
+ expect(subject[4].params).to eql({})
68
+
69
+ expect(subject[5]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
70
+ expect(subject[5].snapshot_name).to eql(:post)
71
+ expect(subject[5].path).to be_nil
72
+
73
+ expect(subject[6]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
74
+ expect(subject[6].snapshot_name).to eql(:last)
75
+ expect(subject[6].path).to be_nil
76
+
77
+ expect(subject.size).to eql(7)
78
+ end
79
+ end
80
+
81
+ context 'no routing rule exists' do
82
+ before do
83
+ # Add compilation rule
84
+ compilation_rule = Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc {})
85
+ rules_collection.add_item_compilation_rule(compilation_rule)
86
+ end
87
+
88
+ example do
89
+ subject
90
+
91
+ expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
92
+ expect(subject[0].snapshot_name).to eql(:raw)
93
+ expect(subject[0].path).to be_nil
94
+
95
+ expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
96
+ expect(subject[1].snapshot_name).to eql(:last)
97
+ expect(subject[1].path).to be_nil
98
+
99
+ expect(subject.size).to eql(2)
100
+ end
101
+ end
102
+
103
+ context 'routing rule exists' do
104
+ before do
105
+ # Add compilation rule
106
+ compilation_rule = Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc {})
107
+ rules_collection.add_item_compilation_rule(compilation_rule)
108
+
109
+ # Add routing rule
110
+ routing_rule = Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc { '/foo.md' }, snapshot_name: :last)
111
+ rules_collection.add_item_routing_rule(routing_rule)
112
+ end
113
+
114
+ example do
115
+ subject
116
+
117
+ expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
118
+ expect(subject[0].snapshot_name).to eql(:raw)
119
+ expect(subject[0].path).to be_nil
120
+
121
+ expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
122
+ expect(subject[1].snapshot_name).to eql(:last)
123
+ expect(subject[1].path).to eq('/foo.md')
124
+
125
+ expect(subject.size).to eql(2)
126
+ end
127
+ end
128
+
129
+ context 'routing rule for other rep exists' do
130
+ before do
131
+ # Add compilation rule
132
+ compilation_rule = Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, proc {})
133
+ rules_collection.add_item_compilation_rule(compilation_rule)
134
+
135
+ # Add routing rule
136
+ routing_rule = Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/list.*'), :abc, proc { '/foo.md' }, snapshot_name: :last)
137
+ rules_collection.add_item_routing_rule(routing_rule)
138
+ end
139
+
140
+ example do
141
+ subject
142
+
143
+ expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
144
+ expect(subject[0].snapshot_name).to eql(:raw)
145
+ expect(subject[0].path).to be_nil
146
+
147
+ expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
148
+ expect(subject[1].snapshot_name).to eql(:last)
149
+ expect(subject[1].path).to be_nil
150
+
151
+ expect(subject.size).to eql(2)
152
+ end
153
+ end
154
+ end
155
+
156
+ context 'with layout' do
157
+ let(:obj) { Nanoc::Int::Layout.new('content', {}, '/default.erb') }
158
+
159
+ context 'no rules exist' do
160
+ it 'raises error' do
161
+ error = Nanoc::RuleDSL::RuleMemoryCalculator::NoRuleMemoryForLayoutException
162
+ expect { subject }.to raise_error(error)
163
+ end
164
+ end
165
+
166
+ context 'rule exists' do
167
+ before do
168
+ pat = Nanoc::Int::Pattern.from('/*.erb')
169
+ rules_collection.layout_filter_mapping[pat] = [:erb, { x: 123 }]
170
+ end
171
+
172
+ it 'contains memory for the rule' do
173
+ expect(subject.size).to eql(1)
174
+ expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Filter)
175
+ expect(subject[0].filter_name).to eql(:erb)
176
+ expect(subject[0].params).to eql(x: 123)
177
+ end
178
+ end
179
+ end
180
+
181
+ context 'with something else' do
182
+ let(:obj) { :donkey }
183
+
184
+ it 'errors' do
185
+ error = Nanoc::RuleDSL::RuleMemoryCalculator::UnsupportedObjectTypeException
186
+ expect { subject }.to raise_error(error)
187
+ end
188
+ end
189
+ end
190
+
191
+ describe '#snapshots_defs_for' do
192
+ subject { rule_memory_calculator.snapshots_defs_for(rep) }
193
+
194
+ let(:rep) { Nanoc::Int::ItemRep.new(item, :csv) }
195
+
196
+ let(:item) { Nanoc::Int::Item.new('content', {}, Nanoc::Identifier.from('/list.md')) }
197
+ let(:config) { Nanoc::Int::Configuration.new.with_defaults }
198
+ let(:items) { Nanoc::Int::IdentifiableCollection.new(config) }
199
+ let(:layouts) { Nanoc::Int::IdentifiableCollection.new(config) }
200
+ let(:site) { double(:site, items: items, layouts: layouts, config: config, compiler: compiler) }
201
+ let(:compiler) { double(:compiler, compilation_context: compilation_context) }
202
+ let(:compilation_context) { double(:compilation_context) }
203
+ let(:view_context) { double(:view_context) }
204
+
205
+ before do
206
+ rules_proc = proc do
207
+ filter :erb, speed: :over_9000
208
+ layout '/default.*'
209
+ filter :typohero
210
+ end
211
+ rule = Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/list.*'), :csv, rules_proc)
212
+ rules_collection.add_item_compilation_rule(rule)
213
+
214
+ expect(compilation_context).to receive(:create_view_context).and_return(view_context)
215
+ end
216
+
217
+ example do
218
+ expect(subject[0]).to be_a(Nanoc::Int::SnapshotDef)
219
+ expect(subject[0].name).to eql(:raw)
220
+
221
+ expect(subject[1]).to be_a(Nanoc::Int::SnapshotDef)
222
+ expect(subject[1].name).to eql(:pre)
223
+
224
+ expect(subject[2]).to be_a(Nanoc::Int::SnapshotDef)
225
+ expect(subject[2].name).to eql(:post)
226
+
227
+ expect(subject[3]).to be_a(Nanoc::Int::SnapshotDef)
228
+ expect(subject[3].name).to eql(:last)
229
+
230
+ expect(subject.size).to eql(4)
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,299 @@
1
+ describe Nanoc::RuleDSL::RulesCollection do
2
+ let(:rules_collection) { described_class.new }
3
+
4
+ describe '#data' do
5
+ subject { rules_collection.data }
6
+
7
+ it 'is nil by default' do
8
+ expect(subject).to be_nil
9
+ end
10
+
11
+ it 'can be set' do
12
+ rules_collection.data = 'asdf'
13
+ expect(subject).to eq('asdf')
14
+ end
15
+ end
16
+
17
+ describe '#compilation_rule_for' do
18
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') }
19
+
20
+ let(:rep) { Nanoc::Int::ItemRep.new(item, rep_name) }
21
+
22
+ let(:rep_name) { :default }
23
+
24
+ subject { rules_collection.compilation_rule_for(rep) }
25
+
26
+ context 'no rules' do
27
+ it 'is nil' do
28
+ expect(subject).to be_nil
29
+ end
30
+ end
31
+
32
+ context 'some rules, none matching' do
33
+ before do
34
+ rules_collection.add_item_compilation_rule(rule)
35
+ end
36
+
37
+ let(:rule) do
38
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {})
39
+ end
40
+
41
+ it 'is nil' do
42
+ expect(subject).to be_nil
43
+ end
44
+ end
45
+
46
+ context 'some rules, one matching' do
47
+ before do
48
+ rules_collection.add_item_compilation_rule(rule_a)
49
+ rules_collection.add_item_compilation_rule(rule_b)
50
+ end
51
+
52
+ let(:rule_a) do
53
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {})
54
+ end
55
+
56
+ let(:rule_b) do
57
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {})
58
+ end
59
+
60
+ context 'rep name does not match' do
61
+ let(:rep_name) { :platypus }
62
+
63
+ it 'is nil' do
64
+ expect(subject).to be_nil
65
+ end
66
+ end
67
+
68
+ context 'rep name matches' do
69
+ it 'is the rule' do
70
+ expect(subject).to equal(rule_a)
71
+ end
72
+ end
73
+ end
74
+
75
+ context 'some rules, multiple matching' do
76
+ before do
77
+ rules_collection.add_item_compilation_rule(rule_a)
78
+ rules_collection.add_item_compilation_rule(rule_b)
79
+ rules_collection.add_item_compilation_rule(rule_c)
80
+ end
81
+
82
+ let(:rule_a) do
83
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {})
84
+ end
85
+
86
+ let(:rule_b) do
87
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/*.*'), :default, proc {})
88
+ end
89
+
90
+ let(:rule_c) do
91
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/*.*'), :foo, proc {})
92
+ end
93
+
94
+ context 'no rep name matches' do
95
+ let(:rep_name) { :platypus }
96
+
97
+ it 'is the first matching rule' do
98
+ expect(subject).to be_nil
99
+ end
100
+ end
101
+
102
+ context 'one rep name matches' do
103
+ let(:rep_name) { :foo }
104
+
105
+ it 'is the first matching rule' do
106
+ expect(subject).to equal(rule_c)
107
+ end
108
+ end
109
+
110
+ context 'multiple rep names match' do
111
+ it 'is the first matching rule' do
112
+ expect(subject).to equal(rule_a)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '#item_compilation_rules_for' do
119
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') }
120
+
121
+ subject { rules_collection.item_compilation_rules_for(item) }
122
+
123
+ context 'no rules' do
124
+ it 'is none' do
125
+ expect(subject).to be_empty
126
+ end
127
+ end
128
+
129
+ context 'some rules, none matching' do
130
+ before do
131
+ rules_collection.add_item_compilation_rule(rule)
132
+ end
133
+
134
+ let(:rule) do
135
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {})
136
+ end
137
+
138
+ it 'is none' do
139
+ expect(subject).to be_empty
140
+ end
141
+ end
142
+
143
+ context 'some rules, one matching' do
144
+ before do
145
+ rules_collection.add_item_compilation_rule(rule_a)
146
+ rules_collection.add_item_compilation_rule(rule_b)
147
+ end
148
+
149
+ let(:rule_a) do
150
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {})
151
+ end
152
+
153
+ let(:rule_b) do
154
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/bar.*'), :default, proc {})
155
+ end
156
+
157
+ it 'is the single rule' do
158
+ expect(subject).to contain_exactly(rule_a)
159
+ end
160
+ end
161
+
162
+ context 'some rules, multiple matching' do
163
+ before do
164
+ rules_collection.add_item_compilation_rule(rule_a)
165
+ rules_collection.add_item_compilation_rule(rule_b)
166
+ end
167
+
168
+ let(:rule_a) do
169
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/foo.*'), :default, proc {})
170
+ end
171
+
172
+ let(:rule_b) do
173
+ Nanoc::RuleDSL::Rule.new(Nanoc::Int::Pattern.from('/*.*'), :default, proc {})
174
+ end
175
+
176
+ it 'is all matching rule' do
177
+ expect(subject).to contain_exactly(rule_a, rule_b)
178
+ end
179
+ end
180
+ end
181
+
182
+ describe '#routing_rules_for' do
183
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/foo.md') }
184
+
185
+ let(:rep) { Nanoc::Int::ItemRep.new(item, :default) }
186
+
187
+ subject { rules_collection.routing_rules_for(rep) }
188
+
189
+ let(:rules) do
190
+ [
191
+ # Matching item, matching rep
192
+ Nanoc::RuleDSL::Rule.new(
193
+ Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}, snapshot_name: :a
194
+ ),
195
+ Nanoc::RuleDSL::Rule.new(
196
+ Nanoc::Int::Pattern.from('/foo.*'), :default, proc {}, snapshot_name: :b
197
+ ),
198
+
199
+ # Matching item, non-matching rep
200
+ Nanoc::RuleDSL::Rule.new(
201
+ Nanoc::Int::Pattern.from('/foo.*'), :raw, proc {}, snapshot_name: :a
202
+ ),
203
+ Nanoc::RuleDSL::Rule.new(
204
+ Nanoc::Int::Pattern.from('/foo.*'), :raw, proc {}, snapshot_name: :b
205
+ ),
206
+
207
+ # Non-matching item, matching rep
208
+ Nanoc::RuleDSL::Rule.new(
209
+ Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}, snapshot_name: :a
210
+ ),
211
+ Nanoc::RuleDSL::Rule.new(
212
+ Nanoc::Int::Pattern.from('/bar.*'), :default, proc {}, snapshot_name: :b
213
+ ),
214
+
215
+ # Non-matching item, non-matching rep
216
+ Nanoc::RuleDSL::Rule.new(
217
+ Nanoc::Int::Pattern.from('/bar.*'), :raw, proc {}, snapshot_name: :a
218
+ ),
219
+ Nanoc::RuleDSL::Rule.new(
220
+ Nanoc::Int::Pattern.from('/bar.*'), :raw, proc {}, snapshot_name: :b
221
+ ),
222
+
223
+ # Matching item, matching rep, but not the first
224
+ Nanoc::RuleDSL::Rule.new(
225
+ Nanoc::Int::Pattern.from('/*.*'), :default, proc {}, snapshot_name: :a
226
+ ),
227
+ Nanoc::RuleDSL::Rule.new(
228
+ Nanoc::Int::Pattern.from('/*.*'), :default, proc {}, snapshot_name: :b
229
+ ),
230
+ ]
231
+ end
232
+
233
+ before do
234
+ rules.each do |rule|
235
+ rules_collection.add_item_routing_rule(rule)
236
+ end
237
+ end
238
+
239
+ it 'returns the first matching rule for every snapshot' do
240
+ expect(subject).to eq(
241
+ a: rules[0],
242
+ b: rules[1],
243
+ )
244
+ end
245
+ end
246
+
247
+ describe '#filter_for_layout' do
248
+ let(:layout) { Nanoc::Int::Layout.new('Some content', {}, '/foo.md') }
249
+
250
+ subject { rules_collection.filter_for_layout(layout) }
251
+
252
+ let(:mapping) { {} }
253
+
254
+ before do
255
+ mapping.each_pair do |key, value|
256
+ rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(key)] = value
257
+ end
258
+ end
259
+
260
+ context 'no rules' do
261
+ it { is_expected.to be_nil }
262
+ end
263
+
264
+ context 'one non-matching rule' do
265
+ let(:mapping) do
266
+ {
267
+ '/default.*' => [:erb, {}],
268
+ }
269
+ end
270
+
271
+ it { is_expected.to be_nil }
272
+ end
273
+
274
+ context 'one matching rule' do
275
+ let(:mapping) do
276
+ {
277
+ '/foo.*' => [:erb, {}],
278
+ }
279
+ end
280
+
281
+ it 'is the single one' do
282
+ expect(subject).to eq([:erb, {}])
283
+ end
284
+ end
285
+
286
+ context 'multiple matching rules' do
287
+ let(:mapping) do
288
+ {
289
+ '/foo.*' => [:erb, {}],
290
+ '/*' => [:haml, {}],
291
+ }
292
+ end
293
+
294
+ it 'is the first one' do
295
+ expect(subject).to eq([:erb, {}])
296
+ end
297
+ end
298
+ end
299
+ end