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,460 @@
1
+ describe Nanoc::Identifier do
2
+ describe '.from' do
3
+ subject { described_class.from(arg) }
4
+
5
+ context 'given an identifier' do
6
+ let(:arg) { Nanoc::Identifier.new('/foo.md') }
7
+
8
+ it 'returns an identifier' do
9
+ expect(subject).to be_a(Nanoc::Identifier)
10
+ expect(subject.to_s).to eq('/foo.md')
11
+ expect(subject).to be_full
12
+ end
13
+ end
14
+
15
+ context 'given a string' do
16
+ let(:arg) { '/foo.md' }
17
+
18
+ it 'returns an identifier' do
19
+ expect(subject).to be_a(Nanoc::Identifier)
20
+ expect(subject.to_s).to eq('/foo.md')
21
+ expect(subject).to be_full
22
+ end
23
+ end
24
+
25
+ context 'given something else' do
26
+ let(:arg) { 12_345 }
27
+
28
+ it 'raises' do
29
+ expect { subject }.to raise_error(Nanoc::Identifier::NonCoercibleObjectError)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe '#initialize' do
35
+ context 'legacy type' do
36
+ it 'does not convert already clean paths' do
37
+ expect(described_class.new('/foo/bar/', type: :legacy).to_s).to eql('/foo/bar/')
38
+ end
39
+
40
+ it 'prepends slash if necessary' do
41
+ expect(described_class.new('foo/bar/', type: :legacy).to_s).to eql('/foo/bar/')
42
+ end
43
+
44
+ it 'appends slash if necessary' do
45
+ expect(described_class.new('/foo/bar', type: :legacy).to_s).to eql('/foo/bar/')
46
+ end
47
+
48
+ it 'removes double slashes at start' do
49
+ expect(described_class.new('//foo/bar/', type: :legacy).to_s).to eql('/foo/bar/')
50
+ end
51
+
52
+ it 'removes double slashes at end' do
53
+ expect(described_class.new('/foo/bar//', type: :legacy).to_s).to eql('/foo/bar/')
54
+ end
55
+
56
+ it 'freezes' do
57
+ identifier = described_class.new('/foo/bar/', type: :legacy)
58
+ expect { identifier.to_s << 'bbq' }.to raise_frozen_error
59
+ end
60
+ end
61
+
62
+ context 'full type' do
63
+ it 'refuses string not starting with a slash' do
64
+ expect { described_class.new('foo') }
65
+ .to raise_error(Nanoc::Identifier::InvalidIdentifierError)
66
+ end
67
+
68
+ it 'has proper string representation' do
69
+ expect(described_class.new('/foo').to_s).to eql('/foo')
70
+ end
71
+
72
+ it 'freezes' do
73
+ identifier = described_class.new('/foo/bar')
74
+ expect { identifier.to_s << 'bbq' }.to raise_frozen_error
75
+ end
76
+ end
77
+
78
+ context 'other type' do
79
+ it 'errors' do
80
+ expect { described_class.new('foo', type: :donkey) }
81
+ .to raise_error(Nanoc::Identifier::InvalidTypeError)
82
+ end
83
+ end
84
+
85
+ context 'default type' do
86
+ it 'is full' do
87
+ expect(described_class.new('/foo')).to be_full
88
+ end
89
+ end
90
+
91
+ context 'other args specified' do
92
+ it 'errors' do
93
+ expect { described_class.new('?', animal: :donkey) }
94
+ .to raise_error(ArgumentError)
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '#to_s' do
100
+ it 'returns immutable string' do
101
+ expect { described_class.new('foo/', type: :legacy).to_s << 'lols' }.to raise_frozen_error
102
+ expect { described_class.new('/foo').to_s << 'lols' }.to raise_frozen_error
103
+ end
104
+ end
105
+
106
+ describe '#to_str' do
107
+ it 'returns immutable string' do
108
+ expect { described_class.new('/foo/bar').to_str << 'lols' }.to raise_frozen_error
109
+ end
110
+ end
111
+
112
+ describe 'Comparable' do
113
+ it 'can be compared' do
114
+ expect(described_class.new('/foo/bar') <= '/qux').to eql(true)
115
+ end
116
+ end
117
+
118
+ describe '#inspect' do
119
+ let(:identifier) { described_class.new('/foo/bar') }
120
+
121
+ subject { identifier.inspect }
122
+
123
+ it { should == '<Nanoc::Identifier type=full "/foo/bar">' }
124
+ end
125
+
126
+ describe '#== and #eql?' do
127
+ context 'comparing with equal identifier' do
128
+ let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) }
129
+ let(:identifier_b) { described_class.new('/foo/bar//', type: :legacy) }
130
+
131
+ it 'is ==' do
132
+ expect(identifier_a).to eq(identifier_b)
133
+ end
134
+
135
+ it 'is eql?' do
136
+ expect(identifier_a).to eql(identifier_b)
137
+ end
138
+ end
139
+
140
+ context 'comparing with equal string' do
141
+ let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) }
142
+ let(:identifier_b) { '/foo/bar/' }
143
+
144
+ it 'is ==' do
145
+ expect(identifier_a).to eq(identifier_b.to_s)
146
+ end
147
+
148
+ it 'is not eql?' do
149
+ expect(identifier_a).not_to eql(identifier_b.to_s)
150
+ end
151
+ end
152
+
153
+ context 'comparing with different identifier' do
154
+ let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) }
155
+ let(:identifier_b) { described_class.new('/baz/qux//', type: :legacy) }
156
+
157
+ it 'is not ==' do
158
+ expect(identifier_a).not_to eq(identifier_b)
159
+ end
160
+
161
+ it 'is not eql?' do
162
+ expect(identifier_a).not_to eql(identifier_b)
163
+ end
164
+ end
165
+
166
+ context 'comparing with different string' do
167
+ let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) }
168
+ let(:identifier_b) { '/baz/qux/' }
169
+
170
+ it 'is not equal' do
171
+ expect(identifier_a).not_to eq(identifier_b)
172
+ end
173
+
174
+ it 'is not eql?' do
175
+ expect(identifier_a).not_to eql(identifier_b)
176
+ end
177
+ end
178
+
179
+ context 'comparing with something that is not an identifier' do
180
+ let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) }
181
+ let(:identifier_b) { :donkey }
182
+
183
+ it 'is not equal' do
184
+ expect(identifier_a).not_to eq(identifier_b)
185
+ expect(identifier_a).not_to eql(identifier_b)
186
+ end
187
+ end
188
+ end
189
+
190
+ describe '#hash' do
191
+ context 'equal identifiers' do
192
+ let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) }
193
+ let(:identifier_b) { described_class.new('/foo/bar//', type: :legacy) }
194
+
195
+ it 'is the same' do
196
+ expect(identifier_a.hash == identifier_b.hash).to eql(true)
197
+ end
198
+ end
199
+
200
+ context 'different identifiers' do
201
+ let(:identifier_a) { described_class.new('//foo/bar/', type: :legacy) }
202
+ let(:identifier_b) { described_class.new('/monkey/', type: :legacy) }
203
+
204
+ it 'is different' do
205
+ expect(identifier_a.hash == identifier_b.hash).to eql(false)
206
+ end
207
+ end
208
+ end
209
+
210
+ describe '#=~' do
211
+ let(:identifier) { described_class.new('/foo/bar') }
212
+
213
+ subject { identifier =~ pat }
214
+
215
+ context 'given a regex' do
216
+ context 'matching regex' do
217
+ let(:pat) { %r{\A/foo/bar} }
218
+ it { is_expected.to eql(0) }
219
+ end
220
+
221
+ context 'non-matching regex' do
222
+ let(:pat) { %r{\A/qux/monkey} }
223
+ it { is_expected.to eql(nil) }
224
+ end
225
+ end
226
+
227
+ context 'given a string' do
228
+ context 'matching string' do
229
+ let(:pat) { '/foo/*' }
230
+ it { is_expected.to eql(0) }
231
+ end
232
+
233
+ context 'non-matching string' do
234
+ let(:pat) { '/qux/*' }
235
+ it { is_expected.to eql(nil) }
236
+ end
237
+ end
238
+ end
239
+
240
+ describe '#<=>' do
241
+ let(:identifier) { described_class.new('/foo/bar') }
242
+
243
+ it 'compares by string' do
244
+ expect(identifier <=> '/foo/aarghh').to eql(1)
245
+ expect(identifier <=> '/foo/bar').to eql(0)
246
+ expect(identifier <=> '/foo/qux').to eql(-1)
247
+ end
248
+ end
249
+
250
+ describe '#prefix' do
251
+ let(:identifier) { described_class.new('/foo') }
252
+
253
+ subject { identifier.prefix(prefix) }
254
+
255
+ context 'prefix not ending nor starting with a slash' do
256
+ let(:prefix) { 'asdf' }
257
+
258
+ it 'raises an error' do
259
+ expect { subject }.to raise_error(
260
+ Nanoc::Identifier::InvalidPrefixError,
261
+ 'Invalid prefix (does not start with a slash): "asdf"',
262
+ )
263
+ end
264
+ end
265
+
266
+ context 'prefix ending with a slash' do
267
+ let(:prefix) { 'asdf/' }
268
+
269
+ it 'raises an error' do
270
+ expect { subject }.to raise_error(
271
+ Nanoc::Identifier::InvalidPrefixError,
272
+ 'Invalid prefix (does not start with a slash): "asdf/"',
273
+ )
274
+ end
275
+ end
276
+
277
+ context 'prefix ending and starting with a slash' do
278
+ let(:prefix) { '/asdf/' }
279
+
280
+ it 'returns a proper new identifier' do
281
+ expect(subject).to be_a(Nanoc::Identifier)
282
+ expect(subject.to_s).to eql('/asdf/foo')
283
+ end
284
+ end
285
+
286
+ context 'prefix nstarting with a slash' do
287
+ let(:prefix) { '/asdf' }
288
+
289
+ it 'returns a proper new identifier' do
290
+ expect(subject).to be_a(Nanoc::Identifier)
291
+ expect(subject.to_s).to eql('/asdf/foo')
292
+ end
293
+ end
294
+ end
295
+
296
+ describe '#without_ext' do
297
+ subject { identifier.without_ext }
298
+
299
+ context 'legacy type' do
300
+ let(:identifier) { described_class.new('/foo/', type: :legacy) }
301
+
302
+ it 'raises an error' do
303
+ expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError)
304
+ end
305
+ end
306
+
307
+ context 'identifier with no extension' do
308
+ let(:identifier) { described_class.new('/foo') }
309
+
310
+ it 'does nothing' do
311
+ expect(subject).to eql('/foo')
312
+ end
313
+ end
314
+
315
+ context 'identifier with extension' do
316
+ let(:identifier) { described_class.new('/foo.md') }
317
+
318
+ it 'removes the extension' do
319
+ expect(subject).to eql('/foo')
320
+ end
321
+ end
322
+ end
323
+
324
+ describe '#ext' do
325
+ subject { identifier.ext }
326
+
327
+ context 'legacy type' do
328
+ let(:identifier) { described_class.new('/foo/', type: :legacy) }
329
+
330
+ it 'raises an error' do
331
+ expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError)
332
+ end
333
+ end
334
+
335
+ context 'identifier with no extension' do
336
+ let(:identifier) { described_class.new('/foo') }
337
+
338
+ it { is_expected.to be_nil }
339
+ end
340
+
341
+ context 'identifier with extension' do
342
+ let(:identifier) { described_class.new('/foo.md') }
343
+
344
+ it { is_expected.to eql('md') }
345
+ end
346
+ end
347
+
348
+ describe '#without_exts' do
349
+ subject { identifier.without_exts }
350
+
351
+ context 'legacy type' do
352
+ let(:identifier) { described_class.new('/foo/', type: :legacy) }
353
+
354
+ it 'raises an error' do
355
+ expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError)
356
+ end
357
+ end
358
+
359
+ context 'identifier with no extension' do
360
+ let(:identifier) { described_class.new('/foo') }
361
+
362
+ it 'does nothing' do
363
+ expect(subject).to eql('/foo')
364
+ end
365
+ end
366
+
367
+ context 'identifier with one extension' do
368
+ let(:identifier) { described_class.new('/foo.md') }
369
+
370
+ it 'removes the extension' do
371
+ expect(subject).to eql('/foo')
372
+ end
373
+ end
374
+
375
+ context 'identifier with multiple extensions' do
376
+ let(:identifier) { described_class.new('/foo.html.md') }
377
+
378
+ it 'removes the extension' do
379
+ expect(subject).to eql('/foo')
380
+ end
381
+ end
382
+ end
383
+
384
+ describe '#exts' do
385
+ subject { identifier.exts }
386
+
387
+ context 'legacy type' do
388
+ let(:identifier) { described_class.new('/foo/', type: :legacy) }
389
+
390
+ it 'raises an error' do
391
+ expect { subject }.to raise_error(Nanoc::Identifier::UnsupportedLegacyOperationError)
392
+ end
393
+ end
394
+
395
+ context 'identifier with no extension' do
396
+ let(:identifier) { described_class.new('/foo') }
397
+
398
+ it { is_expected.to be_empty }
399
+ end
400
+
401
+ context 'identifier with one extension' do
402
+ let(:identifier) { described_class.new('/foo.md') }
403
+
404
+ it { is_expected.to eql(['md']) }
405
+ end
406
+
407
+ context 'identifier with multiple extensions' do
408
+ let(:identifier) { described_class.new('/foo.html.md') }
409
+
410
+ it { is_expected.to eql(%w(html md)) }
411
+ end
412
+ end
413
+
414
+ describe '#legacy?' do
415
+ subject { identifier.legacy? }
416
+
417
+ context 'legacy type' do
418
+ let(:identifier) { described_class.new('/foo/', type: :legacy) }
419
+ it { is_expected.to eql(true) }
420
+ end
421
+
422
+ context 'full type' do
423
+ let(:identifier) { described_class.new('/foo/', type: :full) }
424
+ it { is_expected.to eql(false) }
425
+ end
426
+ end
427
+
428
+ describe '#full?' do
429
+ subject { identifier.full? }
430
+
431
+ context 'legacy type' do
432
+ let(:identifier) { described_class.new('/foo/', type: :legacy) }
433
+ it { is_expected.to eql(false) }
434
+ end
435
+
436
+ context 'full type' do
437
+ let(:identifier) { described_class.new('/foo/', type: :full) }
438
+ it { is_expected.to eql(true) }
439
+ end
440
+ end
441
+
442
+ describe '#components' do
443
+ subject { identifier.components }
444
+
445
+ context 'no components' do
446
+ let(:identifier) { described_class.new('/') }
447
+ it { is_expected.to eql([]) }
448
+ end
449
+
450
+ context 'one component' do
451
+ let(:identifier) { described_class.new('/foo.md') }
452
+ it { is_expected.to eql(['foo.md']) }
453
+ end
454
+
455
+ context 'two components' do
456
+ let(:identifier) { described_class.new('/foo/bar.md') }
457
+ it { is_expected.to eql(['foo', 'bar.md']) }
458
+ end
459
+ end
460
+ end
@@ -0,0 +1,226 @@
1
+ describe Nanoc::Int::ItemRep do
2
+ let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') }
3
+ let(:rep) { Nanoc::Int::ItemRep.new(item, :giraffe) }
4
+
5
+ describe '#compiled_content' do
6
+ let(:snapshot_name) { raise 'override me' }
7
+ subject { rep.compiled_content(snapshot: snapshot_name) }
8
+
9
+ shared_examples 'a non-moving snapshot with content' do
10
+ context 'no snapshot def' do
11
+ it 'raises' do
12
+ expect { subject }.to raise_error(Nanoc::Int::Errors::NoSuchSnapshot)
13
+ end
14
+ end
15
+
16
+ context 'snapshot def exists' do
17
+ before do
18
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
19
+ rep.snapshot_contents = { snapshot_name => content }
20
+ end
21
+
22
+ context 'content is textual' do
23
+ let(:content) { Nanoc::Int::TextualContent.new('hellos') }
24
+ it { is_expected.to eql('hellos') }
25
+ end
26
+
27
+ context 'content is binary' do
28
+ before { File.write('donkey.dat', 'binary data') }
29
+ let(:content) { Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat')) }
30
+
31
+ it 'raises' do
32
+ expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ shared_examples 'a non-moving snapshot' do
39
+ include_examples 'a non-moving snapshot with content'
40
+
41
+ context 'snapshot def exists, but not content' do
42
+ before do
43
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
44
+ rep.snapshot_contents = {}
45
+ end
46
+
47
+ it 'errors' do
48
+ expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
49
+ end
50
+ end
51
+ end
52
+
53
+ shared_examples 'snapshot :last' do
54
+ context 'no snapshot def' do
55
+ it 'errors' do
56
+ expect { subject }.to raise_error(Nanoc::Int::Errors::NoSuchSnapshot)
57
+ end
58
+ end
59
+
60
+ context 'snapshot exists' do
61
+ context 'snapshot is not final' do
62
+ before do
63
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
64
+ end
65
+
66
+ context 'snapshot content does not exist' do
67
+ before do
68
+ rep.snapshot_contents = {}
69
+ end
70
+
71
+ it 'errors' do
72
+ expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
73
+ end
74
+ end
75
+
76
+ context 'snapshot content exists' do
77
+ context 'content is textual' do
78
+ before do
79
+ rep.snapshot_contents[snapshot_name] = Nanoc::Int::TextualContent.new('hellos')
80
+ end
81
+
82
+ context 'not compiled' do
83
+ before { rep.compiled = false }
84
+
85
+ it 'raises' do
86
+ expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
87
+ end
88
+ end
89
+
90
+ context 'compiled' do
91
+ before { rep.compiled = true }
92
+
93
+ it { is_expected.to eql('hellos') }
94
+ end
95
+ end
96
+
97
+ context 'content is binary' do
98
+ before do
99
+ File.write('donkey.dat', 'binary data')
100
+ rep.snapshot_contents[snapshot_name] = Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat'))
101
+ end
102
+
103
+ context 'not compiled' do
104
+ before { rep.compiled = false }
105
+
106
+ it 'raises' do
107
+ expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
108
+ end
109
+ end
110
+
111
+ context 'compiled' do
112
+ before { rep.compiled = true }
113
+
114
+ it 'raises' do
115
+ expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem)
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ context 'snapshot is final' do
123
+ before do
124
+ rep.snapshot_defs = [Nanoc::Int::SnapshotDef.new(snapshot_name)]
125
+ end
126
+
127
+ context 'snapshot content does not exist' do
128
+ before do
129
+ rep.snapshot_contents = {}
130
+ end
131
+
132
+ it 'errors' do
133
+ expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
134
+ end
135
+ end
136
+
137
+ context 'snapshot content exists' do
138
+ context 'content is textual' do
139
+ before do
140
+ rep.snapshot_contents[snapshot_name] = Nanoc::Int::TextualContent.new('hellos')
141
+ end
142
+
143
+ context 'not compiled' do
144
+ before { rep.compiled = false }
145
+
146
+ it 'errors' do
147
+ expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
148
+ end
149
+ end
150
+
151
+ context 'compiled' do
152
+ before { rep.compiled = true }
153
+
154
+ it { is_expected.to eql('hellos') }
155
+ end
156
+ end
157
+
158
+ context 'content is binary' do
159
+ before do
160
+ File.write('donkey.dat', 'binary data')
161
+ rep.snapshot_contents[snapshot_name] = Nanoc::Int::BinaryContent.new(File.expand_path('donkey.dat'))
162
+ end
163
+
164
+ context 'not compiled' do
165
+ before { rep.compiled = false }
166
+
167
+ it 'raises' do
168
+ expect { subject }.to yield_from_fiber(an_instance_of(Nanoc::Int::Errors::UnmetDependency))
169
+ end
170
+ end
171
+
172
+ context 'compiled' do
173
+ before { rep.compiled = true }
174
+
175
+ it 'raises' do
176
+ expect { subject }.to raise_error(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem)
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ context 'snapshot nil' do
186
+ let(:snapshot_name) { :last }
187
+ subject { rep.compiled_content(snapshot: nil) }
188
+ include_examples 'snapshot :last'
189
+ end
190
+
191
+ context 'snapshot not specified' do
192
+ subject { rep.compiled_content }
193
+
194
+ context 'pre exists' do
195
+ before { rep.snapshot_contents[:pre] = Nanoc::Int::TextualContent.new('omg') }
196
+ let(:snapshot_name) { :pre }
197
+ include_examples 'a non-moving snapshot with content'
198
+ end
199
+
200
+ context 'pre does not exist' do
201
+ let(:snapshot_name) { :last }
202
+ include_examples 'snapshot :last'
203
+ end
204
+ end
205
+
206
+ context 'snapshot :pre specified' do
207
+ let(:snapshot_name) { :pre }
208
+ include_examples 'a non-moving snapshot'
209
+ end
210
+
211
+ context 'snapshot :post specified' do
212
+ let(:snapshot_name) { :post }
213
+ include_examples 'a non-moving snapshot'
214
+ end
215
+
216
+ context 'snapshot :last specified' do
217
+ let(:snapshot_name) { :last }
218
+ include_examples 'snapshot :last'
219
+ end
220
+
221
+ context 'snapshot :donkey specified' do
222
+ let(:snapshot_name) { :donkey }
223
+ include_examples 'a non-moving snapshot'
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,3 @@
1
+ describe Nanoc::Int::Item do
2
+ it_behaves_like 'a document'
3
+ end
@@ -0,0 +1,3 @@
1
+ describe Nanoc::Int::Layout do
2
+ it_behaves_like 'a document'
3
+ end