Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 373
- Log:
Initial import of Radiant 0.9.1, which is now packaged as a gem. This is an
import of the tagged 0.9.1 source checked out from GitHub, which isn't quite
the same as the gem distribution - but it doesn't seem to be available in an
archived form and the installed gem already has modifications, so this is
the closest I can get.
- Author:
- rool
- Date:
- Mon Mar 21 13:40:05 +0000 2011
- Size:
- 55581 Bytes
1 | require File.dirname(__FILE__) + '/../spec_helper' |
2 | |
3 | describe "Standard Tags" do |
4 | dataset :users_and_pages, :file_not_found, :snippets |
5 | |
6 | it '<r:page> should allow access to the current page' do |
7 | page(:home) |
8 | page.should render('<r:page:title />').as('Home') |
9 | page.should render(%{<r:find url="/radius"><r:title /> | <r:page:title /></r:find>}).as('Radius | Home') |
10 | end |
11 | |
12 | [:breadcrumb, :slug, :title, :url].each do |attr| |
13 | it "<r:#{attr}> should render the '#{attr}' attribute" do |
14 | value = page.send(attr) |
15 | page.should render("<r:#{attr} />").as(value.to_s) |
16 | end |
17 | end |
18 | |
19 | it "<r:url> with a nil relative URL root should scope to the relative root of /" do |
20 | ActionController::Base.relative_url_root = nil |
21 | page(:home).should render("<r:url />").as("/") |
22 | end |
23 | |
24 | it '<r:url> with a relative URL root should scope to the relative root' do |
25 | page(:home).should render("<r:url />").with_relative_root("/foo").as("/foo/") |
26 | end |
27 | |
28 | it '<r:parent> should change the local context to the parent page' do |
29 | page(:parent) |
30 | page.should render('<r:parent><r:title /></r:parent>').as(pages(:home).title) |
31 | page.should render('<r:parent><r:children:each by="title"><r:title /></r:children:each></r:parent>').as(page_eachable_children(pages(:home)).collect(&:title).join("")) |
32 | page.should render('<r:children:each><r:parent:title /></r:children:each>').as(@page.title * page.children.count) |
33 | end |
34 | |
35 | it '<r:if_parent> should render the contained block if the current page has a parent page' do |
36 | page.should render('<r:if_parent>true</r:if_parent>').as('true') |
37 | page(:home).should render('<r:if_parent>true</r:if_parent>').as('') |
38 | end |
39 | |
40 | it '<r:unless_parent> should render the contained block unless the current page has a parent page' do |
41 | page.should render('<r:unless_parent>true</r:unless_parent>').as('') |
42 | page(:home).should render('<r:unless_parent>true</r:unless_parent>').as('true') |
43 | end |
44 | |
45 | it '<r:if_children> should render the contained block if the current page has child pages' do |
46 | page(:home).should render('<r:if_children>true</r:if_children>').as('true') |
47 | page(:childless).should render('<r:if_children>true</r:if_children>').as('') |
48 | end |
49 | |
50 | it '<r:unless_children> should render the contained block if the current page has no child pages' do |
51 | page(:home).should render('<r:unless_children>true</r:unless_children>').as('') |
52 | page(:childless).should render('<r:unless_children>true</r:unless_children>').as('true') |
53 | end |
54 | |
55 | describe "<r:children:each>" do |
56 | it "should iterate through the children of the current page" do |
57 | page(:parent) |
58 | page.should render('<r:children:each><r:title /> </r:children:each>').as('Child Child 2 Child 3 ') |
59 | page.should render('<r:children:each><r:page><r:slug />/<r:child:slug /> </r:page></r:children:each>').as('parent/child parent/child-2 parent/child-3 ') |
60 | page(:assorted).should render(page_children_each_tags).as('a b c d e f g h i j ') |
61 | end |
62 | |
63 | it 'should not list draft pages' do |
64 | page.should render('<r:children:each by="title"><r:slug /> </r:children:each>').as('a b c d e f g h i j ') |
65 | end |
66 | |
67 | it 'should include draft pages with status="all"' do |
68 | page.should render('<r:children:each status="all" by="slug"><r:slug /> </r:children:each>').as('a b c d draft e f g h i j ') |
69 | end |
70 | |
71 | it "should include draft pages by default on the dev host" do |
72 | page.should render('<r:children:each by="slug"><r:slug /> </r:children:each>').as('a b c d draft e f g h i j ').on('dev.site.com') |
73 | end |
74 | |
75 | it 'should not list draft pages on dev.site.com when Radiant::Config["dev.host"] is set to something else' do |
76 | Radiant::Config['dev.host'] = 'preview.site.com' |
77 | page.should render('<r:children:each by="title"><r:slug /> </r:children:each>').as('a b c d e f g h i j ').on('dev.site.com') |
78 | end |
79 | |
80 | describe 'with paginated="true"' do |
81 | it 'should limit correctly the result set' do |
82 | page.pagination_parameters = {:page => 1, :per_page => 10} |
83 | page.should render('<r:children:each paginated="true" per_page="10"><r:slug /> </r:children:each>').as('a b c d e f g h i j ') |
84 | page.should render('<r:children:each paginated="true" per_page="2"><r:slug /> </r:children:each>').not_matching(/a b c/) |
85 | end |
86 | it 'should display a pagination control block' do |
87 | page.pagination_parameters = {:page => 1, :per_page => 1} |
88 | page.should render('<r:children:each paginated="true"><r:slug /> </r:children:each>').matching(/div class="pagination"/) |
89 | end |
90 | it 'should link to the correct paginated page' do |
91 | page(:another) |
92 | page.pagination_parameters = {:page => 1, :per_page => 1} |
93 | page.should render('<r:find url="/assorted"><r:children:each paginated="true"><r:slug /> </r:children:each></r:find>').matching(%r{href="/another}) |
94 | end |
95 | it 'should pass through selected will_paginate parameters' do |
96 | page(:assorted) |
97 | page.pagination_parameters = {:page => 5, :per_page => 1} |
98 | page.should render('<r:children:each paginated="true" separator="not that likely a choice"><r:slug /> </r:children:each>').matching(/not that likely a choice/) |
99 | page.should render('<r:children:each paginated="true" previous_label="before"><r:slug /> </r:children:each>').matching(/before/) |
100 | page.should render('<r:children:each paginated="true" next_label="after"><r:slug /> </r:children:each>').matching(/after/) |
101 | page.should render('<r:children:each paginated="true" inner_window="1" outer_window="0"><r:slug /> </r:children:each>').not_matching(/\?p=2/) |
102 | end |
103 | end |
104 | |
105 | it 'should error with invalid "limit" attribute' do |
106 | message = "`limit' attribute of `each' tag must be a positive number between 1 and 4 digits" |
107 | page.should render(page_children_each_tags(%{limit="a"})).with_error(message) |
108 | page.should render(page_children_each_tags(%{limit="-10"})).with_error(message) |
109 | page.should render(page_children_each_tags(%{limit="50000"})).with_error(message) |
110 | end |
111 | |
112 | it 'should error with invalid "offset" attribute' do |
113 | message = "`offset' attribute of `each' tag must be a positive number between 1 and 4 digits" |
114 | page.should render(page_children_each_tags(%{offset="a"})).with_error(message) |
115 | page.should render(page_children_each_tags(%{offset="-10"})).with_error(message) |
116 | page.should render(page_children_each_tags(%{offset="50000"})).with_error(message) |
117 | end |
118 | |
119 | it 'should error with invalid "by" attribute' do |
120 | message = "`by' attribute of `each' tag must be set to a valid field name" |
121 | page.should render(page_children_each_tags(%{by="non-existant-field"})).with_error(message) |
122 | end |
123 | |
124 | it 'should error with invalid "order" attribute' do |
125 | message = %{`order' attribute of `each' tag must be set to either "asc" or "desc"} |
126 | page.should render(page_children_each_tags(%{order="asdf"})).with_error(message) |
127 | end |
128 | |
129 | it "should limit the number of children when given a 'limit' attribute" do |
130 | page.should render(page_children_each_tags(%{limit="5"})).as('a b c d e ') |
131 | end |
132 | |
133 | it "should limit and offset the children when given 'limit' and 'offset' attributes" do |
134 | page.should render(page_children_each_tags(%{offset="3" limit="5"})).as('d e f g h ') |
135 | end |
136 | |
137 | it "should change the sort order when given an 'order' attribute" do |
138 | page.should render(page_children_each_tags(%{order="desc"})).as('j i h g f e d c b a ') |
139 | end |
140 | |
141 | it "should sort by the 'by' attribute" do |
142 | page.should render(page_children_each_tags(%{by="breadcrumb"})).as('f e d c b a j i h g ') |
143 | end |
144 | |
145 | it "should sort by the 'by' attribute according to the 'order' attribute" do |
146 | page.should render(page_children_each_tags(%{by="breadcrumb" order="desc"})).as('g h i j a b c d e f ') |
147 | end |
148 | |
149 | describe 'with "status" attribute' do |
150 | it "set to 'all' should list all children" do |
151 | page.should render(page_children_each_tags(%{status="all"})).as("a b c d e f g h i j draft ") |
152 | end |
153 | |
154 | it "set to 'draft' should list only children with 'draft' status" do |
155 | page.should render(page_children_each_tags(%{status="draft"})).as('draft ') |
156 | end |
157 | |
158 | it "set to 'published' should list only children with 'draft' status" do |
159 | page.should render(page_children_each_tags(%{status="published"})).as('a b c d e f g h i j ') |
160 | end |
161 | |
162 | it "set to an invalid status should render an error" do |
163 | page.should render(page_children_each_tags(%{status="askdf"})).with_error("`status' attribute of `each' tag must be set to a valid status") |
164 | end |
165 | end |
166 | end |
167 | |
168 | describe "<r:children:each:if_first>" do |
169 | it "should render for the first child" do |
170 | tags = '<r:children:each><r:if_first>FIRST:</r:if_first><r:slug /> </r:children:each>' |
171 | expected = "FIRST:article article-2 article-3 article-4 " |
172 | page(:news).should render(tags).as(expected) |
173 | end |
174 | end |
175 | |
176 | describe "<r:children:each:unless_first>" do |
177 | it "should render for all but the first child" do |
178 | tags = '<r:children:each><r:unless_first>NOT-FIRST:</r:unless_first><r:slug /> </r:children:each>' |
179 | expected = "article NOT-FIRST:article-2 NOT-FIRST:article-3 NOT-FIRST:article-4 " |
180 | page(:news).should render(tags).as(expected) |
181 | end |
182 | end |
183 | |
184 | describe "<r:children:each:if_last>" do |
185 | it "should render for the last child" do |
186 | tags = '<r:children:each><r:if_last>LAST:</r:if_last><r:slug /> </r:children:each>' |
187 | expected = "article article-2 article-3 LAST:article-4 " |
188 | page(:news).should render(tags).as(expected) |
189 | end |
190 | end |
191 | |
192 | describe "<r:children:each:unless_last>" do |
193 | it "should render for all but the last child" do |
194 | tags = '<r:children:each><r:unless_last>NOT-LAST:</r:unless_last><r:slug /> </r:children:each>' |
195 | expected = "NOT-LAST:article NOT-LAST:article-2 NOT-LAST:article-3 article-4 " |
196 | page(:news).should render(tags).as(expected) |
197 | end |
198 | end |
199 | |
200 | describe "<r:children:each:header>" do |
201 | it "should render the header when it changes" do |
202 | tags = '<r:children:each><r:header>[<r:date format="%b/%y" />] </r:header><r:slug /> </r:children:each>' |
203 | expected = "[Dec/00] article [Feb/01] article-2 article-3 [Mar/01] article-4 " |
204 | page(:news).should render(tags).as(expected) |
205 | end |
206 | |
207 | it 'with "name" attribute should maintain a separate header' do |
208 | tags = %{<r:children:each><r:header name="year">[<r:date format='%Y' />] </r:header><r:header name="month">(<r:date format="%b" />) </r:header><r:slug /> </r:children:each>} |
209 | expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " |
210 | page(:news).should render(tags).as(expected) |
211 | end |
212 | |
213 | it 'with "restart" attribute set to one name should restart that header' do |
214 | tags = %{<r:children:each><r:header name="year" restart="month">[<r:date format='%Y' />] </r:header><r:header name="month">(<r:date format="%b" />) </r:header><r:slug /> </r:children:each>} |
215 | expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " |
216 | page(:news).should render(tags).as(expected) |
217 | end |
218 | |
219 | it 'with "restart" attribute set to two names should restart both headers' do |
220 | tags = %{<r:children:each><r:header name="year" restart="month;day">[<r:date format='%Y' />] </r:header><r:header name="month" restart="day">(<r:date format="%b" />) </r:header><r:header name="day"><<r:date format='%d' />> </r:header><r:slug /> </r:children:each>} |
221 | expected = "[2000] (Dec) <01> article [2001] (Feb) <09> article-2 <24> article-3 (Mar) <06> article-4 " |
222 | page(:news).should render(tags).as(expected) |
223 | end |
224 | end |
225 | |
226 | describe "<r:children:count>" do |
227 | it 'should render the number of children of the current page' do |
228 | page(:parent).should render('<r:children:count />').as('3') |
229 | end |
230 | |
231 | it "should accept the same scoping conditions as <r:children:each>" do |
232 | page.should render('<r:children:count />').as('10') |
233 | page.should render('<r:children:count status="all" />').as('11') |
234 | page.should render('<r:children:count status="draft" />').as('1') |
235 | page.should render('<r:children:count status="hidden" />').as('0') |
236 | end |
237 | end |
238 | |
239 | describe "<r:children:first>" do |
240 | it 'should render its contents in the context of the first child page' do |
241 | page(:parent).should render('<r:children:first:title />').as('Child') |
242 | end |
243 | |
244 | it 'should accept the same scoping attributes as <r:children:each>' do |
245 | page.should render(page_children_first_tags).as('a') |
246 | page.should render(page_children_first_tags(%{limit="5"})).as('a') |
247 | page.should render(page_children_first_tags(%{offset="3" limit="5"})).as('d') |
248 | page.should render(page_children_first_tags(%{order="desc"})).as('j') |
249 | page.should render(page_children_first_tags(%{by="breadcrumb"})).as('f') |
250 | page.should render(page_children_first_tags(%{by="breadcrumb" order="desc"})).as('g') |
251 | end |
252 | |
253 | it "should render nothing when no children exist" do |
254 | page(:first).should render('<r:children:first:title />').as('') |
255 | end |
256 | end |
257 | |
258 | describe "<r:children:last>" do |
259 | it 'should render its contents in the context of the last child page' do |
260 | page(:parent).should render('<r:children:last:title />').as('Child 3') |
261 | end |
262 | |
263 | it 'should accept the same scoping attributes as <r:children:each>' do |
264 | page.should render(page_children_last_tags).as('j') |
265 | page.should render(page_children_last_tags(%{limit="5"})).as('e') |
266 | page.should render(page_children_last_tags(%{offset="3" limit="5"})).as('h') |
267 | page.should render(page_children_last_tags(%{order="desc"})).as('a') |
268 | page.should render(page_children_last_tags(%{by="breadcrumb"})).as('g') |
269 | page.should render(page_children_last_tags(%{by="breadcrumb" order="desc"})).as('f') |
270 | end |
271 | |
272 | it "should render nothing when no children exist" do |
273 | page(:first).should render('<r:children:last:title />').as('') |
274 | end |
275 | end |
276 | |
277 | describe "<r:content>" do |
278 | it "should render the 'body' part by default" do |
279 | page.should render('<r:content />').as('Assorted body.') |
280 | end |
281 | |
282 | it "with 'part' attribute should render the specified part" do |
283 | page(:home).should render('<r:content part="extended" />').as("Just a test.") |
284 | end |
285 | |
286 | it "should prevent simple recursion" do |
287 | page(:recursive_parts).should render('<r:content />').with_error("Recursion error: already rendering the `body' part.") |
288 | end |
289 | |
290 | it "should prevent deep recursion" do |
291 | page(:recursive_parts).should render('<r:content part="one"/>').with_error("Recursion error: already rendering the `one' part.") |
292 | page(:recursive_parts).should render('<r:content part="two"/>').with_error("Recursion error: already rendering the `two' part.") |
293 | end |
294 | |
295 | it "should allow repetition" do |
296 | page(:recursive_parts).should render('<r:content part="repeat"/>').as('xx') |
297 | end |
298 | |
299 | it "should not prevent rendering a part more than once in sequence" do |
300 | page(:home).should render('<r:content /><r:content />').as('Hello world!Hello world!') |
301 | end |
302 | |
303 | describe "with inherit attribute" do |
304 | it "missing or set to 'false' should render the current page's part" do |
305 | page.should render('<r:content part="sidebar" />').as('') |
306 | page.should render('<r:content part="sidebar" inherit="false" />').as('') |
307 | end |
308 | |
309 | describe "set to 'true'" do |
310 | it "should render an ancestor's part" do |
311 | page.should render('<r:content part="sidebar" inherit="true" />').as('Assorted sidebar.') |
312 | end |
313 | it "should render nothing when no ancestor has the part" do |
314 | page.should render('<r:content part="part_that_doesnt_exist" inherit="true" />').as('') |
315 | end |
316 | |
317 | describe "and contextual attribute" do |
318 | it "set to 'true' should render the part in the context of the current page" do |
319 | page(:parent).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Parent sidebar.') |
320 | page(:child).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Child sidebar.') |
321 | page(:grandchild).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Grandchild sidebar.') |
322 | end |
323 | |
324 | it "set to 'false' should render the part in the context of its containing page" do |
325 | page(:parent).should render('<r:content part="sidebar" inherit="true" contextual="false" />').as('Home sidebar.') |
326 | end |
327 | |
328 | it "should maintain the global page" do |
329 | page(:first) |
330 | page.should render('<r:content part="titles" inherit="true" contextual="true"/>').as('First First') |
331 | page.should render('<r:content part="titles" inherit="true" contextual="false"/>').as('Home First') |
332 | end |
333 | end |
334 | end |
335 | |
336 | it "set to an erroneous value should render an error" do |
337 | page.should render('<r:content part="sidebar" inherit="weird value" />').with_error(%{`inherit' attribute of `content' tag must be set to either "true" or "false"}) |
338 | end |
339 | |
340 | it "should render parts with respect to the current contextual page" do |
341 | expected = "Child body. Child 2 body. Child 3 body. " |
342 | page(:parent).should render('<r:children:each><r:content /> </r:children:each>').as(expected) |
343 | end |
344 | end |
345 | end |
346 | |
347 | describe "<r:if_content>" do |
348 | |
349 | it "without 'part' attribute should render the contained block if the 'body' part exists" do |
350 | page.should render('<r:if_content>true</r:if_content>').as('true') |
351 | end |
352 | |
353 | it "should render the contained block if the specified part exists" do |
354 | page.should render('<r:if_content part="body">true</r:if_content>').as('true') |
355 | end |
356 | |
357 | it "should not render the contained block if the specified part does not exist" do |
358 | page.should render('<r:if_content part="asdf">true</r:if_content>').as('') |
359 | end |
360 | |
361 | describe "with more than one part given (separated by comma)" do |
362 | |
363 | it "should render the contained block only if all specified parts exist" do |
364 | page(:home).should render('<r:if_content part="body, extended">true</r:if_content>').as('true') |
365 | end |
366 | |
367 | it "should not render the contained block if at least one of the specified parts does not exist" do |
368 | page(:home).should render('<r:if_content part="body, madeup">true</r:if_content>').as('') |
369 | end |
370 | |
371 | describe "with inherit attribute set to 'true'" do |
372 | it 'should render the contained block if the current or ancestor pages have the specified parts' do |
373 | page(:guests).should render('<r:if_content part="favors, extended" inherit="true">true</r:if_content>').as('true') |
374 | end |
375 | |
376 | it 'should not render the contained block if the current or ancestor pages do not have all of the specified parts' do |
377 | page(:guests).should render('<r:if_content part="favors, madeup" inherit="true">true</r:if_content>').as('') |
378 | end |
379 | |
380 | describe "with find attribute set to 'any'" do |
381 | it 'should render the contained block if the current or ancestor pages have any of the specified parts' do |
382 | page(:guests).should render('<r:if_content part="favors, madeup" inherit="true" find="any">true</r:if_content>').as('true') |
383 | end |
384 | |
385 | it 'should still render the contained block if first of the specified parts has not been found' do |
386 | page(:guests).should render('<r:if_content part="madeup, favors" inherit="true" find="any">true</r:if_content>').as('true') |
387 | end |
388 | end |
389 | end |
390 | |
391 | describe "with inherit attribute set to 'false'" do |
392 | it 'should render the contained block if the current page has the specified parts' do |
393 | page(:guests).should render('<r:if_content part="favors, games" inherit="false">true</r:if_content>').as('') |
394 | end |
395 | |
396 | it 'should not render the contained block if the current or ancestor pages do not have all of the specified parts' do |
397 | page(:guests).should render('<r:if_content part="favors, madeup" inherit="false">true</r:if_content>').as('') |
398 | end |
399 | end |
400 | describe "with the 'find' attribute set to 'any'" do |
401 | it "should render the contained block if any of the specified parts exist" do |
402 | page.should render('<r:if_content part="body, asdf" find="any">true</r:if_content>').as('true') |
403 | end |
404 | end |
405 | describe "with the 'find' attribute set to 'all'" do |
406 | it "should render the contained block if all of the specified parts exist" do |
407 | page(:home).should render('<r:if_content part="body, sidebar" find="all">true</r:if_content>').as('true') |
408 | end |
409 | |
410 | it "should not render the contained block if all of the specified parts do not exist" do |
411 | page.should render('<r:if_content part="asdf, madeup" find="all">true</r:if_content>').as('') |
412 | end |
413 | end |
414 | end |
415 | end |
416 | |
417 | describe "<r:unless_content>" do |
418 | describe "with inherit attribute set to 'true'" do |
419 | it 'should not render the contained block if the current or ancestor pages have the specified parts' do |
420 | page(:guests).should render('<r:unless_content part="favors, extended" inherit="true">true</r:unless_content>').as('') |
421 | end |
422 | |
423 | it 'should render the contained block if the current or ancestor pages do not have the specified parts' do |
424 | page(:guests).should render('<r:unless_content part="madeup, imaginary" inherit="true">true</r:unless_content>').as('true') |
425 | end |
426 | |
427 | it "should not render the contained block if the specified part does not exist but does exist on an ancestor" do |
428 | page.should render('<r:unless_content part="sidebar" inherit="true">false</r:unless_content>').as('') |
429 | end |
430 | |
431 | describe "with find attribute set to 'any'" do |
432 | it 'should not render the contained block if the current or ancestor pages have any of the specified parts' do |
433 | page(:guests).should render('<r:unless_content part="favors, madeup" inherit="true" find="any">true</r:unless_content>').as('') |
434 | end |
435 | |
436 | it 'should still not render the contained block if first of the specified parts has not been found' do |
437 | page(:guests).should render('<r:unless_content part="madeup, favors" inherit="true" find="any">true</r:unless_content>').as('') |
438 | end |
439 | end |
440 | end |
441 | |
442 | it "without 'part' attribute should not render the contained block if the 'body' part exists" do |
443 | page.should render('<r:unless_content>false</r:unless_content>').as('') |
444 | end |
445 | |
446 | it "should not render the contained block if the specified part exists" do |
447 | page.should render('<r:unless_content part="body">false</r:unless_content>').as('') |
448 | end |
449 | |
450 | it "should render the contained block if the specified part does not exist" do |
451 | page.should render('<r:unless_content part="asdf">false</r:unless_content>').as('false') |
452 | end |
453 | |
454 | it "should render the contained block if the specified part does not exist but does exist on an ancestor" do |
455 | page.should render('<r:unless_content part="sidebar">false</r:unless_content>').as('false') |
456 | end |
457 | |
458 | describe "with more than one part given (separated by comma)" do |
459 | |
460 | it "should not render the contained block if all of the specified parts exist" do |
461 | page(:home).should render('<r:unless_content part="body, extended">true</r:unless_content>').as('') |
462 | end |
463 | |
464 | it "should render the contained block if at least one of the specified parts exists" do |
465 | page(:home).should render('<r:unless_content part="body, madeup">true</r:unless_content>').as('true') |
466 | end |
467 | |
468 | describe "with the 'inherit' attribute set to 'true'" do |
469 | it "should render the contained block if the current or ancestor pages have none of the specified parts" do |
470 | page.should render('<r:unless_content part="imaginary, madeup" inherit="true">true</r:unless_content>').as('true') |
471 | end |
472 | |
473 | it "should not render the contained block if all of the specified parts are present on the current or ancestor pages" do |
474 | page(:party).should render('<r:unless_content part="favors, extended" inherit="true">true</r:unless_content>').as('') |
475 | end |
476 | end |
477 | |
478 | describe "with the 'find' attribute set to 'all'" do |
479 | it "should not render the contained block if all of the specified parts exist" do |
480 | page(:home).should render('<r:unless_content part="body, sidebar" find="all">true</r:unless_content>').as('') |
481 | end |
482 | |
483 | it "should render the contained block unless all of the specified parts exist" do |
484 | page.should render('<r:unless_content part="body, madeup" find="all">true</r:unless_content>').as('true') |
485 | end |
486 | end |
487 | |
488 | describe "with the 'find' attribute set to 'any'" do |
489 | it "should not render the contained block if any of the specified parts exist" do |
490 | page.should render('<r:unless_content part="body, madeup" find="any">true</r:unless_content>').as('') |
491 | end |
492 | end |
493 | end |
494 | end |
495 | |
496 | describe "<r:aggregate>" do |
497 | it "should raise an error when given no 'urls' attribute" do |
498 | pages(:home).should render('<r:aggregate></r:aggregate>').with_error("`urls' attribute required") |
499 | end |
500 | it "should expand its contents with a given 'urls' attribute formatted as '/url1; /url2;'" do |
501 | pages(:home).should render('<r:aggregate urls="/parent/child; /first;">true</r:aggregate>').as('true') |
502 | end |
503 | end |
504 | |
505 | describe "<r:aggregate:children>" do |
506 | it "should expand its contents" do |
507 | pages(:home).should render('<r:aggregate urls="/parent/child; /first;"><r:children>true</r:children></r:aggregate>').as('true') |
508 | end |
509 | end |
510 | |
511 | describe "<r:aggregate:children:count>" do |
512 | it "should display the number of aggregated children" do |
513 | pages(:home).should render('<r:aggregate urls="/news; /assorted"><r:children:count /></r:aggregate>').as('14') |
514 | end |
515 | end |
516 | |
517 | describe "<r:aggregate:children:each>" do |
518 | it "should loop through each child from the given urls" do |
519 | pages(:home).should render('<r:aggregate urls="/parent; /news"><r:children:each><r:title/> </r:children:each></r:aggregate>').as('Article Article 2 Article 3 Article 4 Child Child 2 Child 3 ') |
520 | end |
521 | it "should sort the children by the given 'by' attribute" do |
522 | pages(:home).should render('<r:aggregate urls="/assorted; /news"><r:children:each by="slug"><r:slug /> </r:children:each></r:aggregate>').as('a article article-2 article-3 article-4 b c d e f g h i j ') |
523 | end |
524 | it "should order the children by the given 'order' attribute when used with 'by'" do |
525 | pages(:home).should render('<r:aggregate urls="/assorted; /news"><r:children:each by="slug" order="desc"><r:slug /> </r:children:each></r:aggregate>').as('j i h g f e d c b article-4 article-3 article-2 article a ') |
526 | end |
527 | it "should limit the number of results with the given 'limit' attribute" do |
528 | pages(:home).should render('<r:aggregate urls="/assorted; /news"><r:children:each by="slug" order="desc" limit="3"><r:slug /> </r:children:each></r:aggregate>').as('j i h ') |
529 | end |
530 | end |
531 | |
532 | describe "<r:aggregate:each>" do |
533 | it "should loop through each of the given aggregate urls" do |
534 | pages(:home).should render('<r:aggregate urls="/parent/child; /first; /assorted;"><r:each><r:title /> </r:each></r:aggregate>').as('Child First Assorted ') |
535 | end |
536 | it "should display it's contents in the scope of the individually aggregated page" do |
537 | pages(:home).should render('<r:aggregate urls="/parent; /news; /assorted;"><r:each><r:children:each><r:title /> </r:children:each></r:each></r:aggregate>').as('Child Child 2 Child 3 Article Article 2 Article 3 Article 4 a b c d e f g h i j ') |
538 | end |
539 | end |
540 | |
541 | describe "<r:author>" do |
542 | it "should render the author of the current page" do |
543 | page.should render('<r:author />').as('Admin') |
544 | end |
545 | |
546 | it "should render nothing when the page has no author" do |
547 | page(:no_user).should render('<r:author />').as('') |
548 | end |
549 | end |
550 | |
551 | describe "<r:gravatar>" do |
552 | it "should render the Gravatar URL of author of the current page" do |
553 | page.should render('<r:gravatar />').as('http://www.gravatar.com/avatar.php?gravatar_id=e64c7d89f26bd1972efa854d13d7dd61&rating=G&size=32') |
554 | end |
555 | |
556 | it "should render the Gravatar URL of the name user" do |
557 | page.should render('<r:gravatar name="Admin" />').as('http://www.gravatar.com/avatar.php?gravatar_id=e64c7d89f26bd1972efa854d13d7dd61&rating=G&size=32') |
558 | end |
559 | |
560 | it "should render the default avatar when the user has not set an email address" do |
561 | page.should render('<r:gravatar name="Designer" />').as('http://testhost.tld/images/admin/avatar_32x32.png') |
562 | end |
563 | |
564 | it "should render the specified size" do |
565 | page.should render('<r:gravatar name="Designer" size="96px" />').as('http://testhost.tld/images/admin/avatar_96x96.png') |
566 | end |
567 | |
568 | it "should render the specified rating" do |
569 | page.should render('<r:gravatar rating="X" />').as('http://www.gravatar.com/avatar.php?gravatar_id=e64c7d89f26bd1972efa854d13d7dd61&rating=X&size=32') |
570 | end |
571 | end |
572 | |
573 | describe "<r:date>" do |
574 | before :each do |
575 | page(:dated) |
576 | end |
577 | |
578 | it "should render the published date of the page" do |
579 | page.should render('<r:date />').as('Wednesday, January 11, 2006') |
580 | end |
581 | |
582 | it "should format the published date according to the 'format' attribute" do |
583 | page.should render('<r:date format="%d %b %Y" />').as('11 Jan 2006') |
584 | end |
585 | |
586 | describe "with 'for' attribute" do |
587 | it "set to 'now' should render the current date in the current Time.zone" do |
588 | page.should render('<r:date for="now" />').as(Time.zone.now.strftime("%A, %B %d, %Y")) |
589 | end |
590 | |
591 | it "set to 'created_at' should render the creation date" do |
592 | page.should render('<r:date for="created_at" />').as('Tuesday, January 10, 2006') |
593 | end |
594 | |
595 | it "set to 'updated_at' should render the update date" do |
596 | page.should render('<r:date for="updated_at" />').as('Thursday, January 12, 2006') |
597 | end |
598 | |
599 | it "set to 'published_at' should render the publish date" do |
600 | page.should render('<r:date for="published_at" />').as('Wednesday, January 11, 2006') |
601 | end |
602 | |
603 | it "set to an invalid attribute should render an error" do |
604 | page.should render('<r:date for="blah" />').with_error("Invalid value for 'for' attribute.") |
605 | end |
606 | end |
607 | |
608 | it "should use the currently set timezone" do |
609 | Time.zone = "Tokyo" |
610 | format = "%H:%m" |
611 | expected = page.published_at.in_time_zone(ActiveSupport::TimeZone['Tokyo']).strftime(format) |
612 | page.should render(%Q(<r:date format="#{format}" />) ).as(expected) |
613 | end |
614 | end |
615 | |
616 | describe "<r:link>" do |
617 | it "should render a link to the current page" do |
618 | page.should render('<r:link />').as('<a href="/assorted/">Assorted</a>') |
619 | end |
620 | |
621 | it "should render its contents as the text of the link" do |
622 | page.should render('<r:link>Test</r:link>').as('<a href="/assorted/">Test</a>') |
623 | end |
624 | |
625 | it "should pass HTML attributes to the <a> tag" do |
626 | expected = '<a href="/assorted/" class="test" id="assorted">Assorted</a>' |
627 | page.should render('<r:link class="test" id="assorted" />').as(expected) |
628 | end |
629 | |
630 | it "should add the anchor attribute to the link as a URL anchor" do |
631 | page.should render('<r:link anchor="test">Test</r:link>').as('<a href="/assorted/#test">Test</a>') |
632 | end |
633 | |
634 | it "should render a link for the current contextual page" do |
635 | expected = %{<a href="/parent/child/">Child</a> <a href="/parent/child-2/">Child 2</a> <a href="/parent/child-3/">Child 3</a> } |
636 | page(:parent).should render('<r:children:each><r:link /> </r:children:each>' ).as(expected) |
637 | end |
638 | |
639 | it "should scope the link within the relative URL root" do |
640 | page(:assorted).should render('<r:link />').with_relative_root('/foo').as('<a href="/foo/assorted/">Assorted</a>') |
641 | end |
642 | end |
643 | |
644 | describe "<r:snippet>" do |
645 | it "should render the contents of the specified snippet" do |
646 | page.should render('<r:snippet name="first" />').as('test') |
647 | end |
648 | |
649 | it "should render an error when the snippet does not exist" do |
650 | page.should render('<r:snippet name="non-existant" />').with_error('snippet not found') |
651 | end |
652 | |
653 | it "should render an error when not given a 'name' attribute" do |
654 | page.should render('<r:snippet />').with_error("`snippet' tag must contain `name' attribute") |
655 | end |
656 | |
657 | it "should filter the snippet with its assigned filter" do |
658 | page.should render('<r:page><r:snippet name="markdown" /></r:page>').matching(%r{<p><strong>markdown</strong></p>}) |
659 | end |
660 | |
661 | it "should maintain the global page inside the snippet" do |
662 | page(:parent).should render('<r:snippet name="global_page_cascade" />').as("#{@page.title} " * @page.children.count) |
663 | end |
664 | |
665 | it "should maintain the global page when the snippet renders recursively" do |
666 | page(:child).should render('<r:snippet name="recursive" />').as("Great GrandchildGrandchildChild") |
667 | end |
668 | |
669 | it "should render the specified snippet when called as an empty double-tag" do |
670 | page.should render('<r:snippet name="first"></r:snippet>').as('test') |
671 | end |
672 | |
673 | it "should capture contents of a double tag, substituting for <r:yield/> in snippet" do |
674 | page.should render('<r:snippet name="yielding">inner</r:snippet>'). |
675 | as('Before...inner...and after') |
676 | end |
677 | |
678 | it "should do nothing with contents of double tag when snippet doesn't yield" do |
679 | page.should render('<r:snippet name="first">content disappears!</r:snippet>'). |
680 | as('test') |
681 | end |
682 | |
683 | it "should render nested yielding snippets" do |
684 | page.should render('<r:snippet name="div_wrap"><r:snippet name="yielding">Hello, World!</r:snippet></r:snippet>'). |
685 | as('<div>Before...Hello, World!...and after</div>') |
686 | end |
687 | |
688 | it "should render double-tag snippets called from within a snippet" do |
689 | page.should render('<r:snippet name="nested_yields">the content</r:snippet>'). |
690 | as('<snippet name="div_wrap">above the content below</snippet>') |
691 | end |
692 | |
693 | it "should render contents each time yield is called" do |
694 | page.should render('<r:snippet name="yielding_often">French</r:snippet>'). |
695 | as('French is Frencher than French') |
696 | end |
697 | end |
698 | |
699 | it "should do nothing when called from page body" do |
700 | page.should render('<r:yield/>').as("") |
701 | end |
702 | |
703 | it '<r:random> should render a randomly selected contained <r:option>' do |
704 | page.should render("<r:random> <r:option>1</r:option> <r:option>2</r:option> <r:option>3</r:option> </r:random>").matching(/^(1|2|3)$/) |
705 | end |
706 | |
707 | it '<r:random> should render a randomly selected, dynamically set <r:option>' do |
708 | page(:parent).should render("<r:random:children:each:option:title />").matching(/^(Child|Child\ 2|Child\ 3)$/) |
709 | end |
710 | |
711 | it '<r:comment> should render nothing it contains' do |
712 | page.should render('just a <r:comment>small </r:comment>test').as('just a test') |
713 | end |
714 | |
715 | describe "<r:navigation>" do |
716 | it "should render the nested <r:normal> tag by default" do |
717 | tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/"> |
718 | <r:normal><r:title /></r:normal> |
719 | </r:navigation>} |
720 | expected = %{Home Assorted Parent} |
721 | page.should render(tags).as(expected) |
722 | end |
723 | |
724 | it "should render the nested <r:selected> tag for URLs that match the current page" do |
725 | tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/ | Radius: /radius/"> |
726 | <r:normal><r:title /></r:normal> |
727 | <r:selected><strong><r:title/></strong></r:selected> |
728 | </r:navigation>} |
729 | expected = %{<strong>Home</strong> Assorted <strong>Parent</strong> Radius} |
730 | page(:parent).should render(tags).as(expected) |
731 | end |
732 | |
733 | it "should render the nested <r:here> tag for URLs that exactly match the current page" do |
734 | tags = %{<r:navigation urls="Home: Boy: / | Assorted: /assorted/ | Parent: /parent/"> |
735 | <r:normal><a href="<r:url />"><r:title /></a></r:normal> |
736 | <r:here><strong><r:title /></strong></r:here> |
737 | <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected> |
738 | <r:between> | </r:between> |
739 | </r:navigation>} |
740 | expected = %{<strong><a href="/">Home: Boy</a></strong> | <strong>Assorted</strong> | <a href="/parent/">Parent</a>} |
741 | page.should render(tags).as(expected) |
742 | end |
743 | |
744 | it "should render the nested <r:between> tag between each link" do |
745 | tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/"> |
746 | <r:normal><r:title /></r:normal> |
747 | <r:between> :: </r:between> |
748 | </r:navigation>} |
749 | expected = %{Home :: Assorted :: Parent} |
750 | page.should render(tags).as(expected) |
751 | end |
752 | |
753 | it 'without urls should render nothing' do |
754 | page.should render(%{<r:navigation><r:normal /></r:navigation>}).as('') |
755 | end |
756 | |
757 | it 'without a nested <r:normal> tag should render an error' do |
758 | page.should render(%{<r:navigation urls="something:here"></r:navigation>}).with_error( "`navigation' tag must include a `normal' tag") |
759 | end |
760 | |
761 | it 'with urls without trailing slashes should match corresponding pages' do |
762 | tags = %{<r:navigation urls="Home: / | Assorted: /assorted | Parent: /parent | Radius: /radius"> |
763 | <r:normal><r:title /></r:normal> |
764 | <r:here><strong><r:title /></strong></r:here> |
765 | </r:navigation>} |
766 | expected = %{Home <strong>Assorted</strong> Parent Radius} |
767 | page.should render(tags).as(expected) |
768 | end |
769 | |
770 | it 'should prune empty blocks' do |
771 | tags = %{<r:navigation urls="Home: Boy: / | Archives: /archive/ | Radius: /radius/ | Docs: /documentation/"> |
772 | <r:normal><a href="<r:url />"><r:title /></a></r:normal> |
773 | <r:here></r:here> |
774 | <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected> |
775 | <r:between> | </r:between> |
776 | </r:navigation>} |
777 | expected = %{<strong><a href="/">Home: Boy</a></strong> | <a href="/archive/">Archives</a> | <a href="/documentation/">Docs</a>} |
778 | page(:radius).should render(tags).as(expected) |
779 | end |
780 | |
781 | it 'should render text under <r:if_first> and <r:if_last> only on the first and last item, respectively' do |
782 | tags = %{<r:navigation urls="Home: / | Assorted: /assorted | Parent: /parent | Radius: /radius"> |
783 | <r:normal><r:if_first>(</r:if_first><a href="<r:url />"><r:title /></a><r:if_last>)</r:if_last></r:normal> |
784 | <r:here><r:if_first>(</r:if_first><r:title /><r:if_last>)</r:if_last></r:here> |
785 | <r:selected><r:if_first>(</r:if_first><strong><a href="<r:url />"><r:title /></a></strong><r:if_last>)</r:if_last></r:selected> |
786 | </r:navigation>} |
787 | expected = %{(<strong><a href=\"/\">Home</a></strong> <a href=\"/assorted\">Assorted</a> <a href=\"/parent\">Parent</a> Radius)} |
788 | page(:radius).should render(tags).as(expected) |
789 | end |
790 | |
791 | it 'should render text under <r:unless_first> on every item but the first' do |
792 | tags = %{<r:navigation urls="Home: / | Assorted: /assorted | Parent: /parent | Radius: /radius"> |
793 | <r:normal><r:unless_first>> </r:unless_first><a href="<r:url />"><r:title /></a></r:normal> |
794 | <r:here><r:unless_first>> </r:unless_first><r:title /></r:here> |
795 | <r:selected><r:unless_first>> </r:unless_first><strong><a href="<r:url />"><r:title /></a></strong></r:selected> |
796 | </r:navigation>} |
797 | expected = %{<strong><a href=\"/\">Home</a></strong> > <a href=\"/assorted\">Assorted</a> > <a href=\"/parent\">Parent</a> > Radius} |
798 | page(:radius).should render(tags).as(expected) |
799 | end |
800 | |
801 | it 'should render text under <r:unless_last> on every item but the last' do |
802 | tags = %{<r:navigation urls="Home: / | Assorted: /assorted | Parent: /parent | Radius: /radius"> |
803 | <r:normal><a href="<r:url />"><r:title /></a><r:unless_last> ></r:unless_last></r:normal> |
804 | <r:here><r:title /><r:unless_last> ></r:unless_last></r:here> |
805 | <r:selected><strong><a href="<r:url />"><r:title /></a></strong><r:unless_last> ></r:unless_last></r:selected> |
806 | </r:navigation>} |
807 | expected = %{<strong><a href=\"/\">Home</a></strong> > <a href=\"/assorted\">Assorted</a> > <a href=\"/parent\">Parent</a> > Radius} |
808 | page(:radius).should render(tags).as(expected) |
809 | end |
810 | end |
811 | |
812 | describe "<r:find>" do |
813 | it "should change the local page to the page specified in the 'url' attribute" do |
814 | page.should render(%{<r:find url="/parent/child/"><r:title /></r:find>}).as('Child') |
815 | end |
816 | |
817 | it "should render an error without the 'url' attribute" do |
818 | page.should render(%{<r:find />}).with_error("`find' tag must contain `url' attribute") |
819 | end |
820 | |
821 | it "should render nothing when the 'url' attribute does not point to a page" do |
822 | page.should render(%{<r:find url="/asdfsdf/"><r:title /></r:find>}).as('') |
823 | end |
824 | |
825 | it "should render nothing when the 'url' attribute does not point to a page and a custom 404 page exists" do |
826 | page.should render(%{<r:find url="/gallery/asdfsdf/"><r:title /></r:find>}).as('') |
827 | end |
828 | |
829 | it "should scope contained tags to the found page" do |
830 | page.should render(%{<r:find url="/parent/"><r:children:each><r:slug /> </r:children:each></r:find>}).as('child child-2 child-3 ') |
831 | end |
832 | |
833 | it "should accept a path relative to the current page" do |
834 | page(:great_grandchild).should render(%{<r:find url="../../../child-2"><r:title/></r:find>}).as("Child 2") |
835 | end |
836 | end |
837 | |
838 | it '<r:escape_html> should escape HTML-related characters into entities' do |
839 | page.should render('<r:escape_html><strong>a bold move</strong></r:escape_html>').as('<strong>a bold move</strong>') |
840 | end |
841 | |
842 | it '<r:rfc1123_date> should render an RFC1123-compatible date' do |
843 | page(:dated).should render('<r:rfc1123_date />').as('Wed, 11 Jan 2006 00:00:00 GMT') |
844 | end |
845 | |
846 | describe "<r:breadcrumbs>" do |
847 | it "should render a series of breadcrumb links separated by >" do |
848 | expected = %{<a href="/">Home</a> > <a href="/parent/">Parent</a> > <a href="/parent/child/">Child</a> > <a href="/parent/child/grandchild/">Grandchild</a> > Great Grandchild} |
849 | page(:great_grandchild).should render('<r:breadcrumbs />').as(expected) |
850 | end |
851 | |
852 | it "with a 'separator' attribute should use the separator instead of >" do |
853 | expected = %{<a href="/">Home</a> :: Parent} |
854 | page(:parent).should render('<r:breadcrumbs separator=" :: " />').as(expected) |
855 | end |
856 | |
857 | it "with a 'nolinks' attribute set to 'true' should not render links" do |
858 | expected = %{Home > Parent} |
859 | page(:parent).should render('<r:breadcrumbs nolinks="true" />').as(expected) |
860 | end |
861 | |
862 | it "with a relative URL root should scope links to the relative root" do |
863 | expected = '<a href="/foo/">Home</a> > Assorted' |
864 | page(:assorted).should render('<r:breadcrumbs />').with_relative_root('/foo').as(expected) |
865 | end |
866 | end |
867 | |
868 | describe "<r:if_url>" do |
869 | describe "with 'matches' attribute" do |
870 | it "should render the contained block if the page URL matches" do |
871 | page.should render('<r:if_url matches="a.sorted/$">true</r:if_url>').as('true') |
872 | end |
873 | |
874 | it "should not render the contained block if the page URL does not match" do |
875 | page.should render('<r:if_url matches="fancypants">true</r:if_url>').as('') |
876 | end |
877 | |
878 | it "set to a malformatted regexp should render an error" do |
879 | page.should render('<r:if_url matches="as(sorted/$">true</r:if_url>').with_error("Malformed regular expression in `matches' argument of `if_url' tag: unmatched (: /as(sorted\\/$/") |
880 | end |
881 | |
882 | it "without 'ignore_case' attribute should ignore case by default" do |
883 | page.should render('<r:if_url matches="asSorted/$">true</r:if_url>').as('true') |
884 | end |
885 | |
886 | describe "with 'ignore_case' attribute" do |
887 | it "set to 'true' should use a case-insensitive match" do |
888 | page.should render('<r:if_url matches="asSorted/$" ignore_case="true">true</r:if_url>').as('true') |
889 | end |
890 | |
891 | it "set to 'false' should use a case-sensitive match" do |
892 | page.should render('<r:if_url matches="asSorted/$" ignore_case="false">true</r:if_url>').as('') |
893 | end |
894 | end |
895 | end |
896 | |
897 | it "with no attributes should render an error" do |
898 | page.should render('<r:if_url>test</r:if_url>').with_error("`if_url' tag must contain a `matches' attribute.") |
899 | end |
900 | end |
901 | |
902 | describe "<r:unless_url>" do |
903 | describe "with 'matches' attribute" do |
904 | it "should not render the contained block if the page URL matches" do |
905 | page.should render('<r:unless_url matches="a.sorted/$">true</r:unless_url>').as('') |
906 | end |
907 | |
908 | it "should render the contained block if the page URL does not match" do |
909 | page.should render('<r:unless_url matches="fancypants">true</r:unless_url>').as('true') |
910 | end |
911 | |
912 | it "set to a malformatted regexp should render an error" do |
913 | page.should render('<r:unless_url matches="as(sorted/$">true</r:unless_url>').with_error("Malformed regular expression in `matches' argument of `unless_url' tag: unmatched (: /as(sorted\\/$/") |
914 | end |
915 | |
916 | it "without 'ignore_case' attribute should ignore case by default" do |
917 | page.should render('<r:unless_url matches="asSorted/$">true</r:unless_url>').as('') |
918 | end |
919 | |
920 | describe "with 'ignore_case' attribute" do |
921 | it "set to 'true' should use a case-insensitive match" do |
922 | page.should render('<r:unless_url matches="asSorted/$">true</r:unless_url>').as('') |
923 | end |
924 | |
925 | it "set to 'false' should use a case-sensitive match" do |
926 | page.should render('<r:unless_url matches="asSorted/$" ignore_case="false">true</r:unless_url>').as('true') |
927 | end |
928 | end |
929 | end |
930 | |
931 | it "with no attributes should render an error" do |
932 | page.should render('<r:unless_url>test</r:unless_url>').with_error("`unless_url' tag must contain a `matches' attribute.") |
933 | end |
934 | end |
935 | |
936 | describe "<r:cycle>" do |
937 | it "should render passed values in succession" do |
938 | page.should render('<r:cycle values="first, second" /> <r:cycle values="first, second" />').as('first second') |
939 | end |
940 | |
941 | it "should return to the beginning of the cycle when reaching the end" do |
942 | page.should render('<r:cycle values="first, second" /> <r:cycle values="first, second" /> <r:cycle values="first, second" />').as('first second first') |
943 | end |
944 | |
945 | it "should use a default cycle name of 'cycle'" do |
946 | page.should render('<r:cycle values="first, second" /> <r:cycle values="first, second" name="cycle" />').as('first second') |
947 | end |
948 | |
949 | it "should maintain separate cycle counters" do |
950 | page.should render('<r:cycle values="first, second" /> <r:cycle values="one, two" name="numbers" /> <r:cycle values="first, second" /> <r:cycle values="one, two" name="numbers" />').as('first one second two') |
951 | end |
952 | |
953 | it "should reset the counter" do |
954 | page.should render('<r:cycle values="first, second" /> <r:cycle values="first, second" reset="true"/>').as('first first') |
955 | end |
956 | |
957 | it "should require the values attribute" do |
958 | page.should render('<r:cycle />').with_error("`cycle' tag must contain a `values' attribute.") |
959 | end |
960 | end |
961 | |
962 | describe "<r:if_dev>" do |
963 | it "should render the contained block when on the dev site" do |
964 | page.should render('-<r:if_dev>dev</r:if_dev>-').as('-dev-').on('dev.site.com') |
965 | end |
966 | |
967 | it "should not render the contained block when not on the dev site" do |
968 | page.should render('-<r:if_dev>dev</r:if_dev>-').as('--') |
969 | end |
970 | |
971 | it "should not render the contained block when no request is present" do |
972 | page(:devtags).render_part('if_dev').should_not have_text('dev') |
973 | end |
974 | |
975 | describe "on an included page" do |
976 | it "should render the contained block when on the dev site" do |
977 | page.should render('-<r:find url="/devtags/"><r:content part="if_dev" /></r:find>-').as('-dev-').on('dev.site.com') |
978 | end |
979 | |
980 | it "should not render the contained block when not on the dev site" do |
981 | page.should render('-<r:find url="/devtags/"><r:content part="if_dev" /></r:find>-').as('--') |
982 | end |
983 | end |
984 | end |
985 | |
986 | describe "<r:unless_dev>" do |
987 | it "should not render the contained block when not on the dev site" do |
988 | page.should render('-<r:unless_dev>not dev</r:unless_dev>-').as('--').on('dev.site.com') |
989 | end |
990 | |
991 | it "should render the contained block when not on the dev site" do |
992 | page.should render('-<r:unless_dev>not dev</r:unless_dev>-').as('-not dev-') |
993 | end |
994 | |
995 | it "should render the contained block when no request is present" do |
996 | page(:devtags).render_part('unless_dev').should have_text('not dev') |
997 | end |
998 | |
999 | describe "on an included page" do |
1000 | it "should not render the contained block when not on the dev site" do |
1001 | page.should render('-<r:find url="/devtags/"><r:content part="unless_dev" /></r:find>-').as('--').on('dev.site.com') |
1002 | end |
1003 | |
1004 | it "should render the contained block when not on the dev site" do |
1005 | page.should render('-<r:find url="/devtags/"><r:content part="unless_dev" /></r:find>-').as('-not dev-') |
1006 | end |
1007 | end |
1008 | end |
1009 | |
1010 | describe "<r:status>" do |
1011 | it "should render the status of the current page" do |
1012 | status_tag = "<r:status/>" |
1013 | page(:a).should render(status_tag).as("Published") |
1014 | page(:hidden).should render(status_tag).as("Hidden") |
1015 | page(:draft).should render(status_tag).as("Draft") |
1016 | end |
1017 | |
1018 | describe "with the downcase attribute set to 'true'" do |
1019 | it "should render the lowercased status of the current page" do |
1020 | status_tag_lc = "<r:status downcase='true'/>" |
1021 | page(:a).should render(status_tag_lc).as("published") |
1022 | page(:hidden).should render(status_tag_lc).as("hidden") |
1023 | page(:draft).should render(status_tag_lc).as("draft") |
1024 | end |
1025 | end |
1026 | end |
1027 | |
1028 | describe "<r:if_ancestor_or_self>" do |
1029 | it "should render the tag's content when the current page is an ancestor of tag.locals.page" do |
1030 | page(:radius).should render(%{<r:find url="/"><r:if_ancestor_or_self>true</r:if_ancestor_or_self></r:find>}).as('true') |
1031 | end |
1032 | |
1033 | it "should not render the tag's content when current page is not an ancestor of tag.locals.page" do |
1034 | page(:parent).should render(%{<r:find url="/radius"><r:if_ancestor_or_self>true</r:if_ancestor_or_self></r:find>}).as('') |
1035 | end |
1036 | end |
1037 | |
1038 | describe "<r:unless_ancestor_or_self>" do |
1039 | it "should render the tag's content when the current page is not an ancestor of tag.locals.page" do |
1040 | page(:parent).should render(%{<r:find url="/radius"><r:unless_ancestor_or_self>true</r:unless_ancestor_or_self></r:find>}).as('true') |
1041 | end |
1042 | |
1043 | it "should not render the tag's content when current page is an ancestor of tag.locals.page" do |
1044 | page(:radius).should render(%{<r:find url="/"><r:unless_ancestor_or_self>true</r:unless_ancestor_or_self></r:find>}).as('') |
1045 | end |
1046 | end |
1047 | |
1048 | describe "<r:if_self>" do |
1049 | it "should render the tag's content when the current page is the same as the local contextual page" do |
1050 | page(:home).should render(%{<r:find url="/"><r:if_self>true</r:if_self></r:find>}).as('true') |
1051 | end |
1052 | |
1053 | it "should not render the tag's content when the current page is not the same as the local contextual page" do |
1054 | page(:radius).should render(%{<r:find url="/"><r:if_self>true</r:if_self></r:find>}).as('') |
1055 | end |
1056 | end |
1057 | |
1058 | describe "<r:unless_self>" do |
1059 | it "should render the tag's content when the current page is not the same as the local contextual page" do |
1060 | page(:radius).should render(%{<r:find url="/"><r:unless_self>true</r:unless_self></r:find>}).as('true') |
1061 | end |
1062 | |
1063 | it "should not render the tag's content when the current page is the same as the local contextual page" do |
1064 | page(:home).should render(%{<r:find url="/"><r:unless_self>true</r:unless_self></r:find>}).as('') |
1065 | end |
1066 | end |
1067 | |
1068 | describe "<r:meta>" do |
1069 | it "should render <meta> tags for the description and keywords" do |
1070 | page(:home).should render('<r:meta/>').as(%{<meta name="description" content="The homepage" /><meta name="keywords" content="Home, Page" />}) |
1071 | end |
1072 | |
1073 | it "should render <meta> tags with escaped values for the description and keywords" do |
1074 | page.should render('<r:meta/>').as(%{<meta name="description" content="sweet & harmonious biscuits" /><meta name="keywords" content="sweet & harmonious biscuits" />}) |
1075 | end |
1076 | |
1077 | describe "with 'tag' attribute set to 'false'" do |
1078 | it "should render the contents of the description and keywords" do |
1079 | page(:home).should render('<r:meta tag="false" />').as(%{The homepageHome, Page}) |
1080 | end |
1081 | |
1082 | it "should escape the contents of the description and keywords" do |
1083 | page.should render('<r:meta tag="false" />').as("sweet & harmonious biscuitssweet & harmonious biscuits") |
1084 | end |
1085 | end |
1086 | end |
1087 | |
1088 | describe "<r:meta:description>" do |
1089 | it "should render a <meta> tag for the description" do |
1090 | page(:home).should render('<r:meta:description/>').as(%{<meta name="description" content="The homepage" />}) |
1091 | end |
1092 | |
1093 | it "should render a <meta> tag with escaped value for the description" do |
1094 | page.should render('<r:meta:description />').as(%{<meta name="description" content="sweet & harmonious biscuits" />}) |
1095 | end |
1096 | |
1097 | describe "with 'tag' attribute set to 'false'" do |
1098 | it "should render the contents of the description" do |
1099 | page(:home).should render('<r:meta:description tag="false" />').as(%{The homepage}) |
1100 | end |
1101 | |
1102 | it "should escape the contents of the description" do |
1103 | page.should render('<r:meta:description tag="false" />').as("sweet & harmonious biscuits") |
1104 | end |
1105 | end |
1106 | end |
1107 | |
1108 | describe "<r:meta:keywords>" do |
1109 | it "should render a <meta> tag for the keywords" do |
1110 | page(:home).should render('<r:meta:keywords/>').as(%{<meta name="keywords" content="Home, Page" />}) |
1111 | end |
1112 | |
1113 | it "should render a <meta> tag with escaped value for the keywords" do |
1114 | page.should render('<r:meta:keywords />').as(%{<meta name="keywords" content="sweet & harmonious biscuits" />}) |
1115 | end |
1116 | |
1117 | describe "with 'tag' attribute set to 'false'" do |
1118 | it "should render the contents of the keywords" do |
1119 | page(:home).should render('<r:meta:keywords tag="false" />').as(%{Home, Page}) |
1120 | end |
1121 | |
1122 | it "should escape the contents of the keywords" do |
1123 | page.should render('<r:meta:keywords tag="false" />').as("sweet & harmonious biscuits") |
1124 | end |
1125 | end |
1126 | end |
1127 | |
1128 | private |
1129 | |
1130 | def page(symbol = nil) |
1131 | if symbol.nil? |
1132 | @page ||= pages(:assorted) |
1133 | else |
1134 | @page = pages(symbol) |
1135 | end |
1136 | end |
1137 | |
1138 | def page_children_each_tags(attr = nil) |
1139 | attr = ' ' + attr unless attr.nil? |
1140 | "<r:children:each#{attr}><r:slug /> </r:children:each>" |
1141 | end |
1142 | |
1143 | def page_children_first_tags(attr = nil) |
1144 | attr = ' ' + attr unless attr.nil? |
1145 | "<r:children:first#{attr}><r:slug /></r:children:first>" |
1146 | end |
1147 | |
1148 | def page_children_last_tags(attr = nil) |
1149 | attr = ' ' + attr unless attr.nil? |
1150 | "<r:children:last#{attr}><r:slug /></r:children:last>" |
1151 | end |
1152 | |
1153 | def page_eachable_children(page) |
1154 | page.children.select(&:published?).reject(&:virtual) |
1155 | end |
1156 | end |