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,341 @@
1
+ describe Nanoc::ItemWithRepsView do
2
+ let(:entity_class) { Nanoc::Int::Item }
3
+ let(:other_view_class) { Nanoc::LayoutView }
4
+ it_behaves_like 'a document view'
5
+
6
+ let(:view_context) { Nanoc::ViewContext.new(reps: reps, items: items, dependency_tracker: dependency_tracker, compilation_context: compilation_context) }
7
+ let(:reps) { [] }
8
+ let(:items) { [] }
9
+ let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(dependency_store) }
10
+ let(:dependency_store) { Nanoc::Int::DependencyStore.new([]) }
11
+ let(:compilation_context) { double(:compilation_context) }
12
+
13
+ let(:base_item) { Nanoc::Int::Item.new('base', {}, '/base.md') }
14
+
15
+ before do
16
+ dependency_tracker.enter(base_item)
17
+ end
18
+
19
+ describe '#parent' do
20
+ let(:item) do
21
+ Nanoc::Int::Item.new('me', {}, identifier)
22
+ end
23
+
24
+ let(:view) { described_class.new(item, view_context) }
25
+
26
+ let(:items) do
27
+ Nanoc::Int::IdentifiableCollection.new({}).tap do |arr|
28
+ arr << item
29
+ arr << parent_item if parent_item
30
+ end
31
+ end
32
+
33
+ subject { view.parent }
34
+
35
+ context 'with parent' do
36
+ let(:parent_item) do
37
+ Nanoc::Int::Item.new('parent', {}, '/parent/')
38
+ end
39
+
40
+ context 'full identifier' do
41
+ let(:identifier) do
42
+ Nanoc::Identifier.new('/parent/me.md')
43
+ end
44
+
45
+ it 'raises' do
46
+ expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem)
47
+ end
48
+ end
49
+
50
+ context 'legacy identifier' do
51
+ let(:identifier) do
52
+ Nanoc::Identifier.new('/parent/me/', type: :legacy)
53
+ end
54
+
55
+ it 'returns a view for the parent' do
56
+ expect(subject.class).to eql(Nanoc::ItemWithRepsView)
57
+ expect(subject.unwrap).to eql(parent_item)
58
+ end
59
+
60
+ it 'returns a view with the right context' do
61
+ expect(subject._context).to equal(view_context)
62
+ end
63
+
64
+ context 'frozen parent' do
65
+ before { parent_item.freeze }
66
+ it { is_expected.to be_frozen }
67
+ end
68
+
69
+ context 'non-frozen parent' do
70
+ it { is_expected.not_to be_frozen }
71
+ end
72
+
73
+ context 'with root parent' do
74
+ let(:parent_item) { Nanoc::Int::Item.new('parent', {}, '/') }
75
+ let(:identifier) { Nanoc::Identifier.new('/me/', type: :legacy) }
76
+
77
+ it 'returns a view for the parent' do
78
+ expect(subject.class).to eql(Nanoc::ItemWithRepsView)
79
+ expect(subject.unwrap).to eql(parent_item)
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ context 'without parent' do
86
+ let(:parent_item) do
87
+ nil
88
+ end
89
+
90
+ context 'full identifier' do
91
+ let(:identifier) do
92
+ Nanoc::Identifier.new('/me.md')
93
+ end
94
+
95
+ it 'raises' do
96
+ expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem)
97
+ end
98
+ end
99
+
100
+ context 'legacy identifier' do
101
+ let(:identifier) do
102
+ Nanoc::Identifier.new('/me/', type: :legacy)
103
+ end
104
+
105
+ it { is_expected.to be_nil }
106
+ it { is_expected.to be_frozen }
107
+ end
108
+ end
109
+ end
110
+
111
+ describe '#children' do
112
+ let(:item) do
113
+ Nanoc::Int::Item.new('me', {}, identifier)
114
+ end
115
+
116
+ let(:children) do
117
+ [Nanoc::Int::Item.new('child', {}, '/me/child/')]
118
+ end
119
+
120
+ let(:view) { described_class.new(item, view_context) }
121
+
122
+ let(:items) do
123
+ Nanoc::Int::IdentifiableCollection.new({}).tap do |arr|
124
+ arr << item
125
+ children.each { |child| arr << child }
126
+ end
127
+ end
128
+
129
+ subject { view.children }
130
+
131
+ context 'full identifier' do
132
+ let(:identifier) do
133
+ Nanoc::Identifier.new('/me.md')
134
+ end
135
+
136
+ it 'raises' do
137
+ expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetParentOrChildrenOfNonLegacyItem)
138
+ end
139
+ end
140
+
141
+ context 'legacy identifier' do
142
+ let(:identifier) do
143
+ Nanoc::Identifier.new('/me/', type: :legacy)
144
+ end
145
+
146
+ it 'returns views for the children' do
147
+ expect(subject.size).to eql(1)
148
+ expect(subject[0].class).to eql(Nanoc::ItemWithRepsView)
149
+ expect(subject[0].unwrap).to eql(children[0])
150
+ end
151
+
152
+ it { is_expected.to be_frozen }
153
+ end
154
+ end
155
+
156
+ describe '#reps' do
157
+ let(:item) { Nanoc::Int::Item.new('blah', {}, '/foo.md') }
158
+ let(:rep_a) { Nanoc::Int::ItemRep.new(item, :a) }
159
+ let(:rep_b) { Nanoc::Int::ItemRep.new(item, :b) }
160
+
161
+ let(:reps) do
162
+ Nanoc::Int::ItemRepRepo.new.tap do |reps|
163
+ reps << rep_a
164
+ reps << rep_b
165
+ end
166
+ end
167
+
168
+ let(:view) { described_class.new(item, view_context) }
169
+
170
+ subject { view.reps }
171
+
172
+ it 'returns a proper item rep collection' do
173
+ expect(subject.size).to eq(2)
174
+ expect(subject.class).to eql(Nanoc::ItemRepCollectionView)
175
+ end
176
+
177
+ it 'returns a view with the right context' do
178
+ expect(subject._context).to eq(view_context)
179
+ end
180
+ end
181
+
182
+ describe '#compiled_content' do
183
+ subject { view.compiled_content(params) }
184
+
185
+ let(:view) { described_class.new(item, view_context) }
186
+
187
+ let(:item) do
188
+ Nanoc::Int::Item.new('content', {}, '/asdf/')
189
+ end
190
+
191
+ let(:reps) do
192
+ Nanoc::Int::ItemRepRepo.new.tap do |reps|
193
+ reps << rep
194
+ end
195
+ end
196
+
197
+ let(:rep) do
198
+ Nanoc::Int::ItemRep.new(item, :default).tap do |ir|
199
+ ir.compiled = true
200
+ ir.snapshot_defs = [
201
+ Nanoc::Int::SnapshotDef.new(:last),
202
+ Nanoc::Int::SnapshotDef.new(:pre),
203
+ Nanoc::Int::SnapshotDef.new(:post),
204
+ Nanoc::Int::SnapshotDef.new(:specific),
205
+ ]
206
+ ir.snapshot_contents = {
207
+ last: Nanoc::Int::TextualContent.new('Last Hallo'),
208
+ pre: Nanoc::Int::TextualContent.new('Pre Hallo'),
209
+ post: Nanoc::Int::TextualContent.new('Post Hallo'),
210
+ specific: Nanoc::Int::TextualContent.new('Specific Hallo'),
211
+ }
212
+ end
213
+ end
214
+
215
+ context 'requesting implicit default rep' do
216
+ let(:params) { {} }
217
+
218
+ it { is_expected.to eq('Pre Hallo') }
219
+
220
+ it 'creates a dependency' do
221
+ expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item])
222
+ end
223
+
224
+ context 'requesting explicit snapshot' do
225
+ let(:params) { { snapshot: :specific } }
226
+
227
+ it { is_expected.to eq('Specific Hallo') }
228
+
229
+ it 'creates a dependency' do
230
+ expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item])
231
+ end
232
+ end
233
+ end
234
+
235
+ context 'requesting explicit default rep' do
236
+ let(:params) { { rep: :default } }
237
+
238
+ it 'creates a dependency' do
239
+ expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item])
240
+ end
241
+
242
+ it { is_expected.to eq('Pre Hallo') }
243
+
244
+ context 'requesting explicit snapshot' do
245
+ let(:params) { { snapshot: :specific } }
246
+
247
+ it { is_expected.to eq('Specific Hallo') }
248
+ end
249
+ end
250
+
251
+ context 'requesting other rep' do
252
+ let(:params) { { rep: :other } }
253
+
254
+ it 'raises an error' do
255
+ expect { subject }.to raise_error(Nanoc::ItemRepCollectionView::NoSuchItemRepError)
256
+ end
257
+ end
258
+ end
259
+
260
+ describe '#path' do
261
+ subject { view.path(params) }
262
+
263
+ let(:view) { described_class.new(item, view_context) }
264
+
265
+ let(:item) do
266
+ Nanoc::Int::Item.new('content', {}, '/asdf.md')
267
+ end
268
+
269
+ let(:reps) do
270
+ Nanoc::Int::ItemRepRepo.new.tap do |reps|
271
+ reps << rep
272
+ end
273
+ end
274
+
275
+ let(:rep) do
276
+ Nanoc::Int::ItemRep.new(item, :default).tap do |ir|
277
+ ir.paths = {
278
+ last: '/about/',
279
+ specific: '/about.txt',
280
+ }
281
+ end
282
+ end
283
+
284
+ context 'requesting implicit default rep' do
285
+ let(:params) { {} }
286
+
287
+ it 'creates a dependency' do
288
+ expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item])
289
+ end
290
+
291
+ it { is_expected.to eq('/about/') }
292
+
293
+ context 'requesting explicit snapshot' do
294
+ let(:params) { { snapshot: :specific } }
295
+
296
+ it { is_expected.to eq('/about.txt') }
297
+ end
298
+ end
299
+
300
+ context 'requesting explicit default rep' do
301
+ let(:params) { { rep: :default } }
302
+
303
+ it 'creates a dependency' do
304
+ expect { subject }.to change { dependency_store.objects_causing_outdatedness_of(base_item) }.from([]).to([item])
305
+ end
306
+
307
+ it { is_expected.to eq('/about/') }
308
+
309
+ context 'requesting explicit snapshot' do
310
+ let(:params) { { snapshot: :specific } }
311
+
312
+ it { is_expected.to eq('/about.txt') }
313
+ end
314
+ end
315
+
316
+ context 'requesting other rep' do
317
+ let(:params) { { rep: :other } }
318
+
319
+ it 'raises an error' do
320
+ expect { subject }.to raise_error(Nanoc::ItemRepCollectionView::NoSuchItemRepError)
321
+ end
322
+ end
323
+ end
324
+
325
+ describe '#binary?' do
326
+ # TODO: implement
327
+ end
328
+
329
+ describe '#raw_filename' do
330
+ # TODO: implement
331
+ end
332
+
333
+ describe '#inspect' do
334
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
335
+ let(:view) { described_class.new(item, nil) }
336
+
337
+ subject { view.inspect }
338
+
339
+ it { is_expected.to eql('<Nanoc::ItemWithRepsView identifier=/asdf/>') }
340
+ end
341
+ end
@@ -0,0 +1,18 @@
1
+ describe Nanoc::LayoutCollectionView do
2
+ let(:view_class) { Nanoc::LayoutView }
3
+ it_behaves_like 'an identifiable collection'
4
+
5
+ describe '#inspect' do
6
+ let(:wrapped) do
7
+ Nanoc::Int::IdentifiableCollection.new(config)
8
+ end
9
+
10
+ let(:view) { described_class.new(wrapped, view_context) }
11
+ let(:view_context) { double(:view_context) }
12
+ let(:config) { { string_pattern_type: 'glob' } }
13
+
14
+ subject { view.inspect }
15
+
16
+ it { is_expected.to eql('<Nanoc::LayoutCollectionView>') }
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ describe Nanoc::LayoutView do
2
+ let(:entity_class) { Nanoc::Int::Layout }
3
+ let(:other_view_class) { Nanoc::ItemWithRepsView }
4
+ it_behaves_like 'a document view'
5
+
6
+ describe '#inspect' do
7
+ let(:item) { Nanoc::Int::Layout.new('content', {}, '/asdf/') }
8
+ let(:view) { described_class.new(item, nil) }
9
+
10
+ subject { view.inspect }
11
+
12
+ it { is_expected.to eql('<Nanoc::LayoutView identifier=/asdf/>') }
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ describe Nanoc::MutableConfigView do
2
+ let(:config) { {} }
3
+ let(:view) { described_class.new(config, nil) }
4
+
5
+ describe '#[]=' do
6
+ it 'sets attributes' do
7
+ view[:awesomeness] = 'rather high'
8
+ expect(config[:awesomeness]).to eq('rather high')
9
+ end
10
+ end
11
+
12
+ describe '#inspect' do
13
+ subject { view.inspect }
14
+ it { is_expected.to eql('<Nanoc::MutableConfigView>') }
15
+ end
16
+ end
@@ -0,0 +1,92 @@
1
+ shared_examples 'a mutable document view' do
2
+ let(:view) { described_class.new(item, view_context) }
3
+
4
+ let(:view_context) do
5
+ Nanoc::ViewContext.new(
6
+ reps: double(:reps),
7
+ items: double(:items),
8
+ dependency_tracker: dependency_tracker,
9
+ compilation_context: double(:compilation_context),
10
+ )
11
+ end
12
+
13
+ let(:dependency_tracker) { Nanoc::Int::DependencyTracker.new(double(:dependency_store)) }
14
+
15
+ describe '#[]=' do
16
+ # FIXME: rename :item to :document
17
+ let(:item) { entity_class.new('content', {}, '/asdf/') }
18
+
19
+ it 'sets attributes' do
20
+ view[:title] = 'Donkey'
21
+ expect(view[:title]).to eq('Donkey')
22
+ end
23
+
24
+ it 'disallows items' do
25
+ item = Nanoc::Int::Item.new('content', {}, '/foo.md')
26
+ expect { view[:item] = item }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError)
27
+ end
28
+
29
+ it 'disallows layouts' do
30
+ layout = Nanoc::Int::Layout.new('content', {}, '/foo.md')
31
+ expect { view[:layout] = layout }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError)
32
+ end
33
+
34
+ it 'disallows item views' do
35
+ item = Nanoc::ItemWithRepsView.new(Nanoc::Int::Item.new('content', {}, '/foo.md'), nil)
36
+ expect { view[:item] = item }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError)
37
+ end
38
+
39
+ it 'disallows layout views' do
40
+ layout = Nanoc::LayoutView.new(Nanoc::Int::Layout.new('content', {}, '/foo.md'), nil)
41
+ expect { view[:layout] = layout }.to raise_error(Nanoc::MutableDocumentViewMixin::DisallowedAttributeValueError)
42
+ end
43
+ end
44
+
45
+ describe '#identifier=' do
46
+ let(:item) { entity_class.new('content', {}, '/about.md') }
47
+
48
+ subject { view.identifier = arg }
49
+
50
+ context 'given a string' do
51
+ let(:arg) { '/about.adoc' }
52
+
53
+ it 'changes the identifier' do
54
+ subject
55
+ expect(view.identifier).to eq('/about.adoc')
56
+ end
57
+ end
58
+
59
+ context 'given an identifier' do
60
+ let(:arg) { Nanoc::Identifier.new('/about.adoc') }
61
+
62
+ it 'changes the identifier' do
63
+ subject
64
+ expect(view.identifier).to eq('/about.adoc')
65
+ end
66
+ end
67
+
68
+ context 'given anything else' do
69
+ let(:arg) { :donkey }
70
+
71
+ it 'raises' do
72
+ expect { subject }.to raise_error(Nanoc::Identifier::NonCoercibleObjectError)
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '#update_attributes' do
78
+ let(:item) { entity_class.new('content', {}, '/asdf/') }
79
+
80
+ let(:update) { { friend: 'Giraffe' } }
81
+
82
+ subject { view.update_attributes(update) }
83
+
84
+ it 'sets attributes' do
85
+ expect { subject }.to change { view[:friend] }.from(nil).to('Giraffe')
86
+ end
87
+
88
+ it 'returns self' do
89
+ expect(subject).to equal(view)
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,36 @@
1
+ shared_examples 'a mutable identifiable collection' do
2
+ let(:view) { described_class.new(wrapped, view_context) }
3
+
4
+ let(:view_context) { double(:view_context) }
5
+
6
+ let(:config) do
7
+ {}
8
+ end
9
+
10
+ describe '#delete_if' do
11
+ let(:wrapped) do
12
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |coll|
13
+ coll << double(:identifiable, identifier: Nanoc::Identifier.new('/asdf/'))
14
+ end
15
+ end
16
+
17
+ it 'deletes matching' do
18
+ view.delete_if { |i| i.identifier == '/asdf/' }
19
+ expect(wrapped).to be_empty
20
+ end
21
+
22
+ it 'deletes no non-matching' do
23
+ view.delete_if { |i| i.identifier == '/blah/' }
24
+ expect(wrapped).not_to be_empty
25
+ end
26
+
27
+ it 'returns self' do
28
+ ret = view.delete_if { |_i| false }
29
+ expect(ret).to equal(view)
30
+ end
31
+
32
+ it 'yields items with the proper context' do
33
+ view.delete_if { |i| expect(i._context).to equal(view_context) }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,49 @@
1
+ describe Nanoc::MutableItemCollectionView do
2
+ let(:view_class) { Nanoc::MutableItemView }
3
+ it_behaves_like 'an identifiable collection'
4
+ it_behaves_like 'a mutable identifiable collection'
5
+
6
+ let(:config) do
7
+ { string_pattern_type: 'glob' }
8
+ end
9
+
10
+ describe '#create' do
11
+ let(:item) do
12
+ Nanoc::Int::Layout.new('content', {}, '/asdf/')
13
+ end
14
+
15
+ let(:wrapped) do
16
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |coll|
17
+ coll << item
18
+ end
19
+ end
20
+
21
+ let(:view) { described_class.new(wrapped, nil) }
22
+
23
+ it 'creates an object' do
24
+ view.create('new content', { title: 'New Page' }, '/new/')
25
+
26
+ expect(wrapped.size).to eq(2)
27
+ expect(wrapped['/new/'].content.string).to eq('new content')
28
+ end
29
+
30
+ it 'returns self' do
31
+ ret = view.create('new content', { title: 'New Page' }, '/new/')
32
+ expect(ret).to equal(view)
33
+ end
34
+ end
35
+
36
+ describe '#inspect' do
37
+ let(:wrapped) do
38
+ Nanoc::Int::IdentifiableCollection.new(config)
39
+ end
40
+
41
+ let(:view) { described_class.new(wrapped, view_context) }
42
+ let(:view_context) { double(:view_context) }
43
+ let(:config) { { string_pattern_type: 'glob' } }
44
+
45
+ subject { view.inspect }
46
+
47
+ it { is_expected.to eql('<Nanoc::MutableItemCollectionView>') }
48
+ end
49
+ end
@@ -0,0 +1,22 @@
1
+ describe Nanoc::MutableItemView do
2
+ let(:entity_class) { Nanoc::Int::Item }
3
+ it_behaves_like 'a mutable document view'
4
+
5
+ let(:item) { entity_class.new('content', {}, '/asdf/') }
6
+ let(:view) { described_class.new(item, nil) }
7
+
8
+ it 'does have rep access' do
9
+ expect(view).not_to respond_to(:compiled_content)
10
+ expect(view).not_to respond_to(:path)
11
+ expect(view).not_to respond_to(:reps)
12
+ end
13
+
14
+ describe '#inspect' do
15
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
16
+ let(:view) { described_class.new(item, nil) }
17
+
18
+ subject { view.inspect }
19
+
20
+ it { is_expected.to eql('<Nanoc::MutableItemView identifier=/asdf/>') }
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ describe Nanoc::MutableLayoutCollectionView do
2
+ let(:view_class) { Nanoc::MutableLayoutView }
3
+ it_behaves_like 'an identifiable collection'
4
+ it_behaves_like 'a mutable identifiable collection'
5
+
6
+ let(:config) do
7
+ { string_pattern_type: 'glob' }
8
+ end
9
+
10
+ describe '#create' do
11
+ let(:layout) do
12
+ Nanoc::Int::Layout.new('content', {}, '/asdf/')
13
+ end
14
+
15
+ let(:wrapped) do
16
+ Nanoc::Int::IdentifiableCollection.new(config).tap do |coll|
17
+ coll << layout
18
+ end
19
+ end
20
+
21
+ let(:view) { described_class.new(wrapped, nil) }
22
+
23
+ it 'creates an object' do
24
+ view.create('new content', { title: 'New Page' }, '/new/')
25
+
26
+ expect(wrapped.size).to eq(2)
27
+ expect(wrapped['/new/'].content.string).to eq('new content')
28
+ end
29
+
30
+ it 'returns self' do
31
+ ret = view.create('new content', { title: 'New Page' }, '/new/')
32
+ expect(ret).to equal(view)
33
+ end
34
+ end
35
+
36
+ describe '#inspect' do
37
+ let(:wrapped) do
38
+ Nanoc::Int::IdentifiableCollection.new(config)
39
+ end
40
+
41
+ let(:view) { described_class.new(wrapped, view_context) }
42
+ let(:view_context) { double(:view_context) }
43
+ let(:config) { { string_pattern_type: 'glob' } }
44
+
45
+ subject { view.inspect }
46
+
47
+ it { is_expected.to eql('<Nanoc::MutableLayoutCollectionView>') }
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ describe Nanoc::MutableLayoutView do
2
+ let(:entity_class) { Nanoc::Int::Layout }
3
+ it_behaves_like 'a mutable document view'
4
+
5
+ describe '#inspect' do
6
+ let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
7
+ let(:view) { described_class.new(item, nil) }
8
+
9
+ subject { view.inspect }
10
+
11
+ it { is_expected.to eql('<Nanoc::MutableLayoutView identifier=/asdf/>') }
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ describe Nanoc::PostCompileItemRepCollectionView do
2
+ it_behaves_like 'an item rep collection view'
3
+ let(:expected_view_class) { Nanoc::PostCompileItemRepView }
4
+ end