Changeset 833

Show
Ignore:
Timestamp:
04/19/08 11:36:38 (5 months ago)
Author:
seancribbs
Message:

Convert StandardTags? specs to nested describe blocks.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/radiant/CHANGELOG

    r832 r833  
    22 
    33=== SVN 
    4 * Remove test/unit tests - all RSpec now! [Sean Cribbs] 
     4* Convert StandardTags specs to nested describe blocks. [Sean Cribbs] 
     5* Remove test/unit tests - all RSpec now. [Sean Cribbs] 
    56* Fix radiant:update:javascripts task. [Sean Cribbs] 
    67* Fix problem in test fixtures. [Adam Keyes] 
  • trunk/radiant/db/schema.rb

    r826 r833  
    6868  end 
    6969 
     70  add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" 
    7071  add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at" 
    71   add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" 
    7272 
    7373  create_table "snippets", :force => true do |t| 
  • trunk/radiant/spec/models/standard_tags_spec.rb

    r827 r833  
    44  scenario :users_and_pages, :file_not_found, :snippets 
    55 
    6   specify '<r:page> should allow access to the current page' do 
     6  it '<r:page> should allow access to the current page' do 
    77    page(:home) 
    88    page.should render('<r:page:title />').as('Home') 
     
    1010  end 
    1111 
    12   specify '<r:breadcrumb>, <r:slug>, <r:title>, and <r:url>' do 
    13     page(:home) 
    14     [:breadcrumb, :slug, :title, :url].each do |attr| 
     12  [:breadcrumb, :slug, :title, :url].each do |attr| 
     13    it "<r:#{attr}> should render the '#{attr}' attribute" do 
    1514      value = page.send(attr) 
    1615      page.should render("<r:#{attr} />").as(value.to_s) 
     
    1817  end 
    1918 
    20   specify '<r:url> with a relative URL root should scope to the relative root' do 
     19  it '<r:url> with a relative URL root should scope to the relative root' do 
    2120    page(:home).should render("<r:url />").with_relative_root("/foo").as("/foo/") 
    2221  end 
    2322 
    24   specify '<r:parent>' do 
     23  it '<r:parent> should change the local context to the parent page' do 
    2524    page(:parent) 
    2625    page.should render('<r:parent><r:title /></r:parent>').as(pages(:home).title) 
     
    2928  end 
    3029 
    31   specify '<r:if_parent>' do 
     30  it '<r:if_parent> should render the contained block if the current page has a parent page' do 
    3231    page.should render('<r:if_parent>true</r:if_parent>').as('true') 
    3332    page(:home).should render('<r:if_parent>true</r:if_parent>').as('') 
    3433  end 
    3534 
    36   specify '<r:unless_parent>' do 
     35  it '<r:unless_parent> should render the contained block unless the current page has a parent page' do 
    3736    page.should render('<r:unless_parent>true</r:unless_parent>').as('') 
    3837    page(:home).should render('<r:unless_parent>true</r:unless_parent>').as('true') 
    3938  end 
    4039 
    41   specify '<r:if_children>' do 
     40  it '<r:if_children> should render the contained block if the current page has child pages' do 
    4241    page(:home).should render('<r:if_children>true</r:if_children>').as('true') 
    4342    page(:childless).should render('<r:if_children>true</r:if_children>').as('') 
    4443  end 
    4544 
    46   specify '<r:unless_children>' do 
     45  it '<r:unless_children> should render the contained block if the current page has no child pages' do 
    4746    page(:home).should render('<r:unless_children>true</r:unless_children>').as('') 
    4847    page(:childless).should render('<r:unless_children>true</r:unless_children>').as('true') 
    4948  end 
    5049 
    51   specify '<r:children:each>' do 
    52     page(:parent) 
    53     page.should render('<r:children:each><r:title /> </r:children:each>').as('Child Child 2 Child 3 ') 
    54     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 ') 
    55   end 
    56   specify '<r:children:each> order attributes' do 
    57     page.should render(page_children_each_tags).as('a b c d e f g h i j ') 
    58     page.should render(page_children_each_tags(%{limit="5"})).as('a b c d e ') 
    59     page.should render(page_children_each_tags(%{offset="3" limit="5"})).as('d e f g h ') 
    60     page.should render(page_children_each_tags(%{order="desc"})).as('j i h g f e d c b a ') 
    61     page.should render(page_children_each_tags(%{by="breadcrumb"})).as('f e d c b a j i h g ') 
    62     page.should render(page_children_each_tags(%{by="breadcrumb" order="desc"})).as('g h i j a b c d e f ') 
    63   end 
    64   specify '<r:children:each> with "status" attribute' do 
    65     page.should render(page_children_each_tags(%{status="all"})).as("a b c d e f g h i j draft ") 
    66     page.should render(page_children_each_tags(%{status="draft"})).as('draft ') 
    67     page.should render(page_children_each_tags(%{status="published"})).as('a b c d e f g h i j ') 
    68     page.should render(page_children_each_tags(%{status="askdf"})).with_error("`status' attribute of `each' tag must be set to a valid status") 
    69   end 
    70   specify '<r:children:each> should not list virtual pages' do 
    71     page.should render('<r:children:each><r:slug /> </r:children:each>').as('a b c d e f g h i j ') 
    72     page.should render('<r:children:each status="all"><r:slug /> </r:children:each>').as('a b c d e f g h i j draft ') 
    73   end 
    74   specify '<r:children:each> should error with invalid "limit" attribute' do 
    75     message = "`limit' attribute of `each' tag must be a positive number between 1 and 4 digits" 
    76     page.should render(page_children_each_tags(%{limit="a"})).with_error(message) 
    77     page.should render(page_children_each_tags(%{limit="-10"})).with_error(message) 
    78     page.should render(page_children_each_tags(%{limit="50000"})).with_error(message) 
    79   end 
    80   specify '<r:children:each> should error with invalid "offset" attribute' do 
    81     message = "`offset' attribute of `each' tag must be a positive number between 1 and 4 digits" 
    82     page.should render(%{offset="a"}).with_error(message) 
    83     page.should render(%{offset="-10"}).with_error(message) 
    84     page.should render(%{offset="50000"}).with_error(message) 
    85   end 
    86   specify '<r:children:each> should error with invalid "by" attribute' do 
    87     message = "`by' attribute of `each' tag must be set to a valid field name" 
    88     page.should render(page_children_each_tags(%{by="non-existant-field"})).with_error(message) 
    89   end 
    90   specify '<r:children:each> should error with invalid "order" attribute' do 
    91     message = %{`order' attribute of `each' tag must be set to either "asc" or "desc"} 
    92     page.should render(page_children_each_tags(%{order="asdf"})).with_error(message) 
    93   end 
    94  
    95   specify '<r:children:each:header>' do 
    96     tags = '<r:children:each><r:header>[<r:date format="%b/%y" />] </r:header><r:slug /> </r:children:each>' 
    97     expected = "[Dec/00] article [Feb/01] article-2 article-3 [Mar/01] article-4 " 
    98     page(:news).should render(tags).as(expected) 
    99   end 
    100   specify '<r:children:each:header> with "name" attribute' do 
    101     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>} 
    102     expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " 
    103     page(:news).should render(tags).as(expected) 
    104   end 
    105   specify '<r:children:each:header> with "restart" attribute set to one name' do 
    106     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>} 
    107     expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " 
    108     page(:news).should render(tags).as(expected) 
    109   end 
    110   specify '<r:children:each:header> with "restart" attribute set to two names' do 
    111     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>} 
    112     expected = "[2000] (Dec) <01> article [2001] (Feb) <09> article-2 <24> article-3 (Mar) <06> article-4 " 
    113     page(:news).should render(tags).as(expected) 
    114   end 
    115  
    116   specify '<r:children:count>' do 
     50  describe "<r:children:each>" do 
     51    it "should iterate through the children of the current page" do 
     52      page(:parent) 
     53      page.should render('<r:children:each><r:title /> </r:children:each>').as('Child Child 2 Child 3 ') 
     54      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 ') 
     55      page(:assorted).should render(page_children_each_tags).as('a b c d e f g h i j ') 
     56    end 
     57 
     58    it 'should not list virtual pages' do 
     59      page.should render('<r:children:each><r:slug /> </r:children:each>').as('a b c d e f g h i j ') 
     60      page.should render('<r:children:each status="all"><r:slug /> </r:children:each>').as('a b c d e f g h i j draft ') 
     61    end 
     62 
     63    it 'should error with invalid "limit" attribute' do 
     64      message = "`limit' attribute of `each' tag must be a positive number between 1 and 4 digits" 
     65      page.should render(page_children_each_tags(%{limit="a"})).with_error(message) 
     66      page.should render(page_children_each_tags(%{limit="-10"})).with_error(message) 
     67      page.should render(page_children_each_tags(%{limit="50000"})).with_error(message) 
     68    end 
     69 
     70    it 'should error with invalid "offset" attribute' do 
     71      message = "`offset' attribute of `each' tag must be a positive number between 1 and 4 digits" 
     72      page.should render(%{offset="a"}).with_error(message) 
     73      page.should render(%{offset="-10"}).with_error(message) 
     74      page.should render(%{offset="50000"}).with_error(message) 
     75    end 
     76 
     77    it 'should error with invalid "by" attribute' do 
     78      message = "`by' attribute of `each' tag must be set to a valid field name" 
     79      page.should render(page_children_each_tags(%{by="non-existant-field"})).with_error(message) 
     80    end 
     81 
     82    it 'should error with invalid "order" attribute' do 
     83      message = %{`order' attribute of `each' tag must be set to either "asc" or "desc"} 
     84      page.should render(page_children_each_tags(%{order="asdf"})).with_error(message) 
     85    end 
     86 
     87    it "should limit the number of children when given a 'limit' attribute" do 
     88      page.should render(page_children_each_tags(%{limit="5"})).as('a b c d e ') 
     89    end 
     90 
     91    it "should limit and offset the children when given 'limit' and 'offset' attributes" do 
     92      page.should render(page_children_each_tags(%{offset="3" limit="5"})).as('d e f g h ') 
     93    end 
     94 
     95    it "should change the sort order when given an 'order' attribute" do 
     96      page.should render(page_children_each_tags(%{order="desc"})).as('j i h g f e d c b a ') 
     97    end 
     98 
     99    it "should sort by the 'by' attribute" do 
     100      page.should render(page_children_each_tags(%{by="breadcrumb"})).as('f e d c b a j i h g ') 
     101    end 
     102 
     103    it "should sort by the 'by' attribute according to the 'order' attribute" do 
     104      page.should render(page_children_each_tags(%{by="breadcrumb" order="desc"})).as('g h i j a b c d e f ') 
     105    end 
     106 
     107    describe 'with "status" attribute' do 
     108      it "set to 'all' should list all children" do 
     109        page.should render(page_children_each_tags(%{status="all"})).as("a b c d e f g h i j draft ") 
     110      end 
     111 
     112      it "set to 'draft' should list only children with 'draft' status" do 
     113        page.should render(page_children_each_tags(%{status="draft"})).as('draft ') 
     114      end 
     115 
     116      it "set to 'published' should list only children with 'draft' status" do 
     117        page.should render(page_children_each_tags(%{status="published"})).as('a b c d e f g h i j ') 
     118      end 
     119 
     120      it "set to an invalid status should render an error" do 
     121        page.should render(page_children_each_tags(%{status="askdf"})).with_error("`status' attribute of `each' tag must be set to a valid status") 
     122      end 
     123    end 
     124  end 
     125 
     126 
     127  describe "<r:children:each:header>" do 
     128    it "should render the header when it changes" do 
     129      tags = '<r:children:each><r:header>[<r:date format="%b/%y" />] </r:header><r:slug /> </r:children:each>' 
     130      expected = "[Dec/00] article [Feb/01] article-2 article-3 [Mar/01] article-4 " 
     131      page(:news).should render(tags).as(expected) 
     132    end 
     133 
     134    it 'with "name" attribute should maintain a separate header' do 
     135      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>} 
     136      expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " 
     137      page(:news).should render(tags).as(expected) 
     138    end 
     139 
     140    it 'with "restart" attribute set to one name should restart that header' do 
     141      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>} 
     142      expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " 
     143      page(:news).should render(tags).as(expected) 
     144    end 
     145 
     146    it 'with "restart" attribute set to two names should restart both headers' do 
     147      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>} 
     148      expected = "[2000] (Dec) <01> article [2001] (Feb) <09> article-2 <24> article-3 (Mar) <06> article-4 " 
     149      page(:news).should render(tags).as(expected) 
     150    end 
     151  end 
     152 
     153  it '<r:children:count> should render the number of children of the current page' do 
    117154    page(:parent).should render('<r:children:count />').as('3') 
    118155  end 
    119156 
    120   specify '<r:children:first>' do 
    121     page(:parent).should render('<r:children:first:title />').as('Child') 
    122   end 
    123   specify '<r:children:first> with attributes' do 
    124     page.should render(page_children_first_tags).as('a') 
    125     page.should render(page_children_first_tags(%{limit="5"})).as('a') 
    126     page.should render(page_children_first_tags(%{offset="3" limit="5"})).as('d') 
    127     page.should render(page_children_first_tags(%{order="desc"})).as('j') 
    128     page.should render(page_children_first_tags(%{by="breadcrumb"})).as('f') 
    129     page.should render(page_children_first_tags(%{by="breadcrumb" order="desc"})).as('g') 
    130   end 
    131   specify '<r:children:first> when no children exist' do 
    132     page(:first).should render('<r:children:first:title />').as('') 
    133   end 
    134  
    135   specify '<r:children:last>' do 
    136     page(:parent).should render('<r:children:last:title />').as('Child 3') 
    137   end 
    138   specify '<r:children:last> with attributes' do 
    139     page.should render(page_children_last_tags).as('j') 
    140     page.should render(page_children_last_tags(%{limit="5"})).as('e') 
    141     page.should render(page_children_last_tags(%{offset="3" limit="5"})).as('h') 
    142     page.should render(page_children_last_tags(%{order="desc"})).as('a') 
    143     page.should render(page_children_last_tags(%{by="breadcrumb"})).as('g') 
    144     page.should render(page_children_last_tags(%{by="breadcrumb" order="desc"})).as('f') 
    145   end 
    146   specify '<r:children:last> when no children exist' do 
    147     page(:first).should render('<r:children:last:title />').as('') 
    148   end 
    149  
    150   specify '<r:content>' do 
    151     page.should render('<r:content />').as('Assorted body.') 
    152   end 
    153   specify '<r:content> with "part" attribute' do 
    154     page(:home).should render('<r:content part="extended" />').as("Just a test.") 
    155   end 
    156   specify '<r:content> with inherit attribute' do 
    157     page.should render('<r:content part="sidebar" />').as('') 
    158     page.should render('<r:content part="sidebar" inherit="false" />').as('') 
    159     page.should render('<r:content part="sidebar" inherit="true" />').as('Assorted sidebar.') 
    160     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"}) 
    161     page.should render('<r:content part="part_that_doesnt_exist" inherit="true" />').as('') 
    162   end 
    163   specify '<r:content> with inherit and contextual attributes' do 
    164     page(:parent) 
    165     page.should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Parent sidebar.') 
    166     page.should render('<r:content part="sidebar" inherit="true" contextual="false" />').as('Home sidebar.') 
    167     page(:child).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Child sidebar.') 
    168     page(:grandchild).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Grandchild sidebar.') 
    169   end 
    170   specify '<r:content> with global page propagation' do 
    171     page(:first) 
    172     page.should render('<r:content part="titles" inherit="true" contextual="true"/>').as('First First') 
    173     page.should render('<r:content part="titles" inherit="true" contextual="false"/>').as('Home First') 
    174   end 
    175   specify '<r:content /> for children' do 
    176     expected = "Child body. Child 2 body. Child 3 body. " 
    177     page(:parent).should render('<r:children:each><r:content /> </r:children:each>').as(expected) 
    178   end 
    179  
    180   specify '<r:if_content> without "part" attribute' do 
    181     page.should render('<r:if_content>true</r:if_content>').as('true') 
    182   end 
    183   specify '<r:if_content> with "part" attribute' do 
    184     page.should render('<r:if_content part="body">true</r:if_content>').as('true') 
    185   end 
    186   specify '<r:if_content> with nonexistant "part" attribute' do 
    187     page.should render('<r:if_content part="asdf">true</r:if_content>').as('') 
    188   end 
    189  
    190   specify '<r:unless_content> without "part" attribute' do 
    191     page.should render('<r:unless_content>false</r:unless_content>').as('') 
    192   end 
    193   specify '<r:unless_content> with "part" attribute' do 
    194     page.should render('<r:unless_content part="body">false</r:unless_content>').as('') 
    195   end 
    196   specify '<r:unless_content> with nonexistant "part" attribute' do 
    197     page.should render('<r:unless_content part="asdf">false</r:unless_content>').as('false') 
    198   end 
    199  
    200   specify '<r:author>' do 
    201     page.should render('<r:author />').as('Admin') 
    202   end 
    203   specify '<r:author> nil' do 
    204     page(:no_user).should render('<r:author />').as('') 
    205   end 
    206  
    207   specify '<r:date>' do 
    208     page(:dated) 
    209     page.should render('<r:date />').as('Wednesday, January 11, 2006') 
    210   end 
    211   specify '<r:date> with "format" attribute' do 
    212     page(:dated) 
    213     page.should render('<r:date format="%d %b %Y" />').as('11 Jan 2006') 
    214   end 
    215   specify '<r:date> with "for" attribute' do 
    216     page(:dated) 
    217     page.should render('<r:date for="now" />').as(Time.now.strftime("%A, %B %d, %Y")) 
    218     page.should render('<r:date for="created_at" />').as('Tuesday, January 10, 2006') 
    219     page.should render('<r:date for="updated_at" />').as('Thursday, January 12, 2006') 
    220     page.should render('<r:date for="published_at" />').as('Wednesday, January 11, 2006') 
    221     page.should render('<r:date for="blah" />').with_error("Invalid value for 'for' attribute.") 
    222   end 
    223   specify '<r:date> should use local timezone' do 
    224     page(:dated) 
    225     Radiant::Config["local.timezone"] = "Tokyo" 
    226     format = "%H:%m" 
    227     expected = TimeZone["Tokyo"].adjust(page.published_at).strftime(format) 
    228     page.should render(%Q(<r:date format="#{format}" />) ).as(expected) 
    229   end 
    230  
    231   specify '<r:link>' do 
    232     page.should render('<r:link />').as('<a href="/assorted/">Assorted</a>') 
    233   end 
    234   specify '<r:link> in block form' do 
    235     page.should render('<r:link>Test</r:link>').as('<a href="/assorted/">Test</a>') 
    236   end 
    237   specify '<r:link> with HTML attributes' do 
    238     expected = '<a href="/assorted/" class="test" id="assorted">Assorted</a>' 
    239     page.should render('<r:link class="test" id="assorted" />').as(expected) 
    240   end 
    241   specify '<r:link> with "anchor" attribute' do 
    242     page.should render('<r:link anchor="test">Test</r:link>').as('<a href="/assorted/#test">Test</a>') 
    243   end 
    244   specify '<r:link> should work for children' do 
    245     expected = %{<a href="/parent/child/">Child</a> <a href="/parent/child-2/">Child 2</a> <a href="/parent/child-3/">Child 3</a> } 
    246     page(:parent).should render('<r:children:each><r:link /> </r:children:each>' ).as(expected) 
    247   end 
    248   specify '<r:link> with a relative URL root should scope to the relative root' do 
    249     page(:assorted).should render('<r:link />').with_relative_root('/foo').as('<a href="/foo/assorted/">Assorted</a>') 
    250   end 
    251  
    252   specify '<r:snippet>' do 
    253     page.should render('<r:snippet name="first" />').as('test') 
    254   end 
    255   specify '<r:snippet> not found' do 
    256     page.should render('<r:snippet name="non-existant" />').with_error('snippet not found') 
    257   end 
    258   specify '<r:snippet> without name' do 
    259     page.should render('<r:snippet />').with_error("`snippet' tag must contain `name' attribute") 
    260   end 
    261   specify '<r:snippet> with markdown' do 
    262     page.should render('<r:page><r:snippet name="markdown" /></r:page>').as('<p><strong>markdown</strong></p>') 
    263   end 
    264   specify '<r:snippet> with global page propagation' do 
    265     page(:parent).should render('<r:snippet name="global_page_cascade" />').as("#{@page.title} " * @page.children.count) 
    266   end 
    267   specify '<r:snippet> with recursion global page propagation' do 
    268     page(:child).should render('<r:snippet name="recursive" />').as("Great GrandchildGrandchildChild") 
     157  describe "<r:children:first>" do 
     158    it 'should render its contents in the context of the first child page' do 
     159      page(:parent).should render('<r:children:first:title />').as('Child') 
     160    end 
     161 
     162    it 'should accept the same scoping attributes as <r:children:each>' do 
     163      page.should render(page_children_first_tags).as('a') 
     164      page.should render(page_children_first_tags(%{limit="5"})).as('a') 
     165      page.should render(page_children_first_tags(%{offset="3" limit="5"})).as('d') 
     166      page.should render(page_children_first_tags(%{order="desc"})).as('j') 
     167      page.should render(page_children_first_tags(%{by="breadcrumb"})).as('f') 
     168      page.should render(page_children_first_tags(%{by="breadcrumb" order="desc"})).as('g') 
     169    end 
     170 
     171    it "should render nothing when no children exist" do 
     172      page(:first).should render('<r:children:first:title />').as('') 
     173    end 
     174  end 
     175 
     176  describe "<r:children:last>" do 
     177    it 'should render its contents in the context of the last child page' do 
     178      page(:parent).should render('<r:children:last:title />').as('Child 3') 
     179    end 
     180 
     181    it 'should accept the same scoping attributes as <r:children:each>' do 
     182      page.should render(page_children_last_tags).as('j') 
     183      page.should render(page_children_last_tags(%{limit="5"})).as('e') 
     184      page.should render(page_children_last_tags(%{offset="3" limit="5"})).as('h') 
     185      page.should render(page_children_last_tags(%{order="desc"})).as('a') 
     186      page.should render(page_children_last_tags(%{by="breadcrumb"})).as('g') 
     187      page.should render(page_children_last_tags(%{by="breadcrumb" order="desc"})).as('f') 
     188    end 
     189 
     190    it "should render nothing when no children exist" do 
     191      page(:first).should render('<r:children:last:title />').as('') 
     192    end 
     193  end 
     194 
     195  describe "<r:content>" do 
     196    it "should render the 'body' part by default" do 
     197      page.should render('<r:content />').as('Assorted body.') 
     198    end 
     199 
     200    it "with 'part' attribute should render the specified part" do 
     201      page(:home).should render('<r:content part="extended" />').as("Just a test.") 
     202    end 
     203 
     204    describe "with inherit attribute" do 
     205      it "missing or set to 'false' should render the current page's part" do 
     206        page.should render('<r:content part="sidebar" />').as('') 
     207        page.should render('<r:content part="sidebar" inherit="false" />').as('') 
     208      end 
     209 
     210      describe "set to 'true'" do 
     211        it "should render an ancestor's part" do 
     212          page.should render('<r:content part="sidebar" inherit="true" />').as('Assorted sidebar.') 
     213        end 
     214        it "should render nothing when no ancestor has the part" do 
     215          page.should render('<r:content part="part_that_doesnt_exist" inherit="true" />').as('') 
     216        end 
     217 
     218        describe "and contextual attribute" do 
     219          it "set to 'true' should render the part in the context of the current page" do 
     220            page(:parent).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Parent sidebar.') 
     221            page(:child).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Child sidebar.') 
     222            page(:grandchild).should render('<r:content part="sidebar" inherit="true" contextual="true" />').as('Grandchild sidebar.') 
     223          end 
     224 
     225          it "set to 'false' should render the part in the context of its containing page" do 
     226            page(:parent).should render('<r:content part="sidebar" inherit="true" contextual="false" />').as('Home sidebar.') 
     227          end 
     228 
     229          it "should maintain the global page" do 
     230            page(:first) 
     231            page.should render('<r:content part="titles" inherit="true" contextual="true"/>').as('First First') 
     232            page.should render('<r:content part="titles" inherit="true" contextual="false"/>').as('Home First') 
     233          end 
     234        end 
     235      end 
     236 
     237      it "set to an erroneous value should render an error" do 
     238        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"}) 
     239      end 
     240 
     241      it "should render parts with respect to the current contextual page" do 
     242        expected = "Child body. Child 2 body. Child 3 body. " 
     243        page(:parent).should render('<r:children:each><r:content /> </r:children:each>').as(expected) 
     244      end 
     245    end 
     246  end 
     247 
     248  describe "<r:if_content>" do 
     249    it "without 'part' attribute should render the contained block if the 'body' part exists" do 
     250      page.should render('<r:if_content>true</r:if_content>').as('true') 
     251    end 
     252 
     253    it "should render the contained block if the specified part exists" do 
     254      page.should render('<r:if_content part="body">true</r:if_content>').as('true') 
     255    end 
     256 
     257    it "should not render the contained block if the specified part does not exist" do 
     258      page.should render('<r:if_content part="asdf">true</r:if_content>').as('') 
     259    end 
     260  end 
     261 
     262  describe "<r:unless_content>" do 
     263    it "without 'part' attribute should not render the contained block if the 'body' part exists" do 
     264      page.should render('<r:unless_content>false</r:unless_content>').as('') 
     265    end 
     266 
     267    it "should not render the contained block if the specified part exists" do 
     268      page.should render('<r:unless_content part="body">false</r:unless_content>').as('') 
     269    end 
     270 
     271    it "should render the contained block if the specified part does not exist" do 
     272      page.should render('<r:unless_content part="asdf">false</r:unless_content>').as('false') 
     273    end 
     274  end 
     275 
     276  describe "<r:author>" do 
     277    it "should render the author of the current page" do 
     278      page.should render('<r:author />').as('Admin') 
     279    end 
     280 
     281    it "should render nothing when the page has no author" do 
     282      page(:no_user).should render('<r:author />').as('') 
     283    end 
     284  end 
     285 
     286  describe "<r:date>" do 
     287    before :each do 
     288      page(:dated) 
     289    end 
     290 
     291    it "should render the published date of the page" do 
     292      page.should render('<r:date />').as('Wednesday, January 11, 2006') 
     293    end 
     294 
     295    it "should format the published date according to the 'format' attribute" do 
     296      page.should render('<r:date format="%d %b %Y" />').as('11 Jan 2006') 
     297    end 
     298 
     299    describe "with 'for' attribute" do 
     300      it "set to 'now' should render the current date" do 
     301        page.should render('<r:date for="now" />').as(Time.now.strftime("%A, %B %d, %Y")) 
     302      end 
     303 
     304      it "set to 'created_at' should render the creation date" do 
     305        page.should render('<r:date for="created_at" />').as('Tuesday, January 10, 2006') 
     306      end 
     307 
     308      it "set to 'updated_at' should render the update date" do 
     309        page.should render('<r:date for="updated_at" />').as('Thursday, January 12, 2006') 
     310      end 
     311 
     312      it "set to 'published_at' should render the publish date" do 
     313        page.should render('<r:date for="published_at" />').as('Wednesday, January 11, 2006') 
     314      end 
     315 
     316      it "set to an invalid attribute should render an error" do 
     317        page.should render('<r:date for="blah" />').with_error("Invalid value for 'for' attribute.") 
     318      end 
     319    end 
     320 
     321    it "should use the configured local timezone" do 
     322      Radiant::Config["local.timezone"] = "Tokyo" 
     323      format = "%H:%m" 
     324      expected = TimeZone["Tokyo"].adjust(page.published_at).strftime(format) 
     325      page.should render(%Q(<r:date format="#{format}" />) ).as(expected) 
     326    end 
     327  end 
     328 
     329  describe "<r:link>" do 
     330    it "should render a link to the current page" do 
     331      page.should render('<r:link />').as('<a href="/assorted/">Assorted</a>') 
     332    end 
     333 
     334    it "should render its contents as the text of the link" do 
     335      page.should render('<r:link>Test</r:link>').as('<a href="/assorted/">Test</a>') 
     336    end 
     337 
     338    it "should pass HTML attributes to the <a> tag" do 
     339      expected = '<a href="/assorted/" class="test" id="assorted">Assorted</a>' 
     340      page.should render('<r:link class="test" id="assorted" />').as(expected) 
     341    end 
     342 
     343    it "should add the anchor attribute to the link as a URL anchor" do 
     344      page.should render('<r:link anchor="test">Test</r:link>').as('<a href="/assorted/#test">Test</a>') 
     345    end 
     346 
     347    it "should render a link for the current contextual page" do 
     348      expected = %{<a href="/parent/child/">Child</a> <a href="/parent/child-2/">Child 2</a> <a href="/parent/child-3/">Child 3</a> } 
     349      page(:parent).should render('<r:children:each><r:link /> </r:children:each>' ).as(expected) 
     350    end 
     351 
     352    it "should scope the link within the relative URL root" do 
     353      page(:assorted).should render('<r:link />').with_relative_root('/foo').as('<a href="/foo/assorted/">Assorted</a>') 
     354    end 
     355  end 
     356 
     357  describe "<r:snippet>" do 
     358    it "should the contents of the specified snippet" do 
     359      page.should render('<r:snippet name="first" />').as('test') 
     360    end 
     361 
     362    it "should render an error when the snippet does not exist" do 
     363      page.should render('<r:snippet name="non-existant" />').with_error('snippet not found') 
     364    end 
     365 
     366    it "should render an error when not given a 'name' attribute" do 
     367      page.should render('<r:snippet />').with_error("`snippet' tag must contain `name' attribute") 
     368    end 
     369 
     370    it "should filter the snippet with its assigned filter" do 
     371      page.should render('<r:page><r:snippet name="markdown" /></r:page>').as('<p><strong>markdown</strong></p>') 
     372    end 
     373 
     374    it "should maintain the global page inside the snippet" do 
     375      page(:parent).should render('<r:snippet name="global_page_cascade" />').as("#{@page.title} " * @page.children.count) 
     376    end 
     377 
     378    it "should maintain the global page when the snippet renders recursively" do 
     379      page(:child).should render('<r:snippet name="recursive" />').as("Great GrandchildGrandchildChild") 
     380    end 
    269381  end 
    270382 
     
    277389  end 
    278390 
    279   specify '<r:navigation> simple case' do 
    280     tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/"> 
    281                <r:normal><r:title /></r:normal> 
    282              </r:navigation>} 
    283     expected = %{Home Assorted Parent} 
    284     page.should render(tags).as(expected) 
    285   end 
    286   specify '<r:navigation> more complex' do 
    287     tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/ | Radius: /radius/"> 
    288                <r:normal><r:title /></r:normal> 
    289                <r:selected><strong><r:title/></strong></r:selected> 
    290              </r:navigation>} 
    291     expected = %{<strong>Home</strong> Assorted <strong>Parent</strong> Radius} 
    292     page(:parent).should render(tags).as(expected) 
    293   end 
    294   specify '<r:navigation> very complex' do 
    295     tags = %{<r:navigation urls="Home: Boy: / | Assorted: /assorted/ | Parent: /parent/"> 
    296                <r:normal><a href="<r:url />"><r:title /></a></r:normal> 
    297                <r:here><strong><r:title /></strong></r:here> 
    298                <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected> 
    299                <r:between> | </r:between> 
    300              </r:navigation>} 
    301     expected = %{<strong><a href="/">Home: Boy</a></strong> | <strong>Assorted</strong> | <a href="/parent/">Parent</a>} 
    302     page.should render(tags).as(expected) 
    303   end 
    304   specify '<r:navigation> without urls' do 
    305     page.should render(%{<r:navigation><r:normal /></r:navigation>}).as('') 
    306   end 
    307   specify '<r:navigation> without normal tag' do 
    308     page.should render(%{<r:navigation urls="something:here"></r:navigation>}).with_error( "`navigation' tag must include a `normal' tag") 
    309   end 
    310   specify '<r:navigation> with urls without slashes' do 
    311     tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/ | Radius: /radius/"> 
    312                <r:normal><r:title /></r:normal> 
    313                <r:here><strong><r:title /></strong></r:here> 
    314              </r:navigation>} 
    315     expected = %{Home <strong>Assorted</strong> Parent Radius} 
    316     page.should render(tags).as(expected) 
    317   end 
    318   specify '<r:navigation> with empty nodes' do 
    319     tags = %{<r:navigation urls="Home: Boy: / | Archives: /archive/ | Radius: /radius/ | Docs: /documentation/"> 
    320                <r:normal><a href="<r:url />"><r:title /></a></r:normal> 
    321                <r:here></r:here> 
    322                <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected> 
    323                <r:between> | </r:between> 
    324              </r:navigation>} 
    325     expected = %{<strong><a href="/">Home: Boy</a></strong> | <a href="/archive/">Archives</a> | <a href="/documentation/">Docs</a>} 
    326     page(:radius).should render(tags).as(expected) 
     391  describe "<r:navigation>" do 
     392    it "should render the nested <r:normal> tag by default" do 
     393      tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/"> 
     394                 <r:normal><r:title /></r:normal> 
     395               </r:navigation>} 
     396      expected = %{Home Assorted Parent} 
     397      page.should render(tags).as(expected) 
     398    end 
     399 
     400    it "should render the nested <r:selected> tag for URLs that match the current page" do 
     401      tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/ | Radius: /radius/"> 
     402                 <r:normal><r:title /></r:normal> 
     403                 <r:selected><strong><r:title/></strong></r:selected> 
     404               </r:navigation>} 
     405      expected = %{<strong>Home</strong> Assorted <strong>Parent</strong> Radius} 
     406      page(:parent).should render(tags).as(expected) 
     407    end 
     408 
     409    it "should render the nested <r:here> tag for URLs that exactly match the current page" do 
     410      tags = %{<r:navigation urls="Home: Boy: / | Assorted: /assorted/ | Parent: /parent/"> 
     411                 <r:normal><a href="<r:url />"><r:title /></a></r:normal> 
     412                 <r:here><strong><r:title /></strong></r:here> 
     413                 <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected> 
     414                 <r:between> | </r:between> 
     415               </r:navigation>} 
     416      expected = %{<strong><a href="/">Home: Boy</a></strong> | <strong>Assorted</strong> | <a href="/parent/">Parent</a>} 
     417      page.should render(tags).as(expected) 
     418    end 
     419 
     420    it "should render the nested <r:between> tag between each link" do 
     421      tags = %{<r:navigation urls="Home: / | Assorted: /assorted/ | Parent: /parent/"> 
     422                 <r:normal><r:title /></r:normal> 
     423                 <r:between> :: </r:between> 
     424               </r:navigation>} 
     425      expected = %{Home :: Assorted :: Parent} 
     426      page.should render(tags).as(expected) 
     427    end 
     428 
     429    it 'without urls should render nothing' do 
     430      page.should render(%{<r:navigation><r:normal /></r:navigation>}).as('') 
     431    end 
     432 
     433    it 'without a nested <r:normal> tag should render an error' do 
     434      page.should render(%{<r:navigation urls="something:here"></r:navigation>}).with_error( "`navigation' tag must include a `normal' tag") 
     435    end 
     436 
     437    it 'with urls without trailing slashes should match corresponding pages' do 
     438      tags = %{<r:navigation urls="Home: / | Assorted: /assorted | Parent: /parent | Radius: /radius"> 
     439                 <r:normal><r:title /></r:normal> 
     440                 <r:here><strong><r:title /></strong></r:here> 
     441               </r:navigation>} 
     442      expected = %{Home <strong>Assorted</strong> Parent Radius} 
     443      page.should render(tags).as(expected) 
     444    end 
     445 
     446    it 'should prune empty blocks' do 
     447      tags = %{<r:navigation urls="Home: Boy: / | Archives: /archive/ | Radius: /radius/ | Docs: /documentation/"> 
     448                 <r:normal><a href="<r:url />"><r:title /></a></r:normal> 
     449                 <r:here></r:here> 
     450                 <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected> 
     451                 <r:between> | </r:between> 
     452               </r:navigation>} 
     453      expected = %{<strong><a href="/">Home: Boy</a></strong> | <a href="/archive/">Archives</a> | <a href="/documentation/">Docs</a>} 
     454      page(:radius).should render(tags).as(expected) 
     455    end 
    327456  end 
    328457 
     
    559688      page(:home).should render('<r:meta/>').as(%{<meta name="description" content="The homepage" /><meta name="keywords" content="Home, Page" />}) 
    560689    end 
    561      
     690 
    562691    it "should render <meta> tags with escaped values for the description and keywords" do 
    563692      page.should render('<r:meta/>').as(%{<meta name="description" content="sweet &amp; harmonious biscuits" /><meta name="keywords" content="sweet &amp; harmonious biscuits" />}) 
     
    568697        page(:home).should render('<r:meta tag="false" />').as(%{The homepageHome, Page}) 
    569698      end 
    570        
     699 
    571700      it "should escape the contents of the description and keywords" do 
    572701        page.should render('<r:meta tag="false" />').as("sweet &amp; harmonious biscuitssweet &amp; harmonious biscuits") 
     
    574703    end 
    575704  end 
    576    
     705 
    577706  describe "<r:meta:description>" do 
    578707    it "should render a <meta> tag for the description" do 
    579708      page(:home).should render('<r:meta:description/>').as(%{<meta name="description" content="The homepage" />}) 
    580709    end 
    581      
     710 
    582711    it "should render a <meta> tag with escaped value for the description" do 
    583712      page.should render('<r:meta:description />').as(%{<meta name="description" content="sweet &amp; harmonious biscuits" />}) 
     
    588717        page(:home).should render('<r:meta:description tag="false" />').as(%{The homepage}) 
    589718      end 
    590        
     719 
    591720      it "should escape the contents of the description" do 
    592721        page.should render('<r:meta:description tag="false" />').as("sweet &amp; harmonious biscuits") 
     
    594723    end 
    595724  end 
    596    
     725 
    597726  describe "<r:meta:keywords>" do 
    598727    it "should render a <meta> tag for the keywords" do 
    599728      page(:home).should render('<r:meta:keywords/>').as(%{<meta name="keywords" content="Home, Page" />}) 
    600729    end 
    601      
     730 
    602731    it "should render a <meta> tag with escaped value for the keywords" do 
    603732      page.should render('<r:meta:keywords />').as(%{<meta name="keywords" content="sweet &amp; harmonious biscuits" />}) 
     
    608737        page(:home).should render('<r:meta:keywords tag="false" />').as(%{Home, Page}) 
    609738      end 
    610        
     739 
    611740      it "should escape the contents of the keywords" do 
    612741        page.should render('<r:meta:keywords tag="false" />').as("sweet &amp; harmonious biscuits") 
     
    614743    end 
    615744  end 
    616    
     745 
    617746  private 
    618747