require File.dirname(__FILE__) + '/../spec_helper' describe "Standard Tags" do dataset :users_and_pages, :file_not_found, :snippets it ' should allow access to the current page' do page(:home) page.should render('').as('Home') page.should render(%{ | }).as('Radius | Home') end [:breadcrumb, :slug, :title, :url].each do |attr| it " should render the '#{attr}' attribute" do value = page.send(attr) page.should render("").as(value.to_s) end end it " with a nil relative URL root should scope to the relative root of /" do ActionController::Base.relative_url_root = nil page(:home).should render("").as("/") end it ' with a relative URL root should scope to the relative root' do page(:home).should render("").with_relative_root("/foo").as("/foo/") end it ' should change the local context to the parent page' do page(:parent) page.should render('').as(pages(:home).title) page.should render('').as(page_eachable_children(pages(:home)).collect(&:title).join("")) page.should render('').as(@page.title * page.children.count) end it ' should render the contained block if the current page has a parent page' do page.should render('true').as('true') page(:home).should render('true').as('') end it ' should render the contained block unless the current page has a parent page' do page.should render('true').as('') page(:home).should render('true').as('true') end it ' should render the contained block if the current page has child pages' do page(:home).should render('true').as('true') page(:childless).should render('true').as('') end it ' should render the contained block if the current page has no child pages' do page(:home).should render('true').as('') page(:childless).should render('true').as('true') end describe "" do it "should iterate through the children of the current page" do page(:parent) page.should render(' ').as('Child Child 2 Child 3 ') page.should render('/ ').as('parent/child parent/child-2 parent/child-3 ') page(:assorted).should render(page_children_each_tags).as('a b c d e f g h i j ') end it 'should not list draft pages' do page.should render(' ').as('a b c d e f g h i j ') end it 'should include draft pages with status="all"' do page.should render(' ').as('a b c d draft e f g h i j ') end it "should include draft pages by default on the dev host" do page.should render(' ').as('a b c d draft e f g h i j ').on('dev.site.com') end it 'should error with invalid "limit" attribute' do message = "`limit' attribute of `each' tag must be a positive number between 1 and 4 digits" page.should render(page_children_each_tags(%{limit="a"})).with_error(message) page.should render(page_children_each_tags(%{limit="-10"})).with_error(message) page.should render(page_children_each_tags(%{limit="50000"})).with_error(message) end it 'should error with invalid "offset" attribute' do message = "`offset' attribute of `each' tag must be a positive number between 1 and 4 digits" page.should render(page_children_each_tags(%{offset="a"})).with_error(message) page.should render(page_children_each_tags(%{offset="-10"})).with_error(message) page.should render(page_children_each_tags(%{offset="50000"})).with_error(message) end it 'should error with invalid "by" attribute' do message = "`by' attribute of `each' tag must be set to a valid field name" page.should render(page_children_each_tags(%{by="non-existant-field"})).with_error(message) end it 'should error with invalid "order" attribute' do message = %{`order' attribute of `each' tag must be set to either "asc" or "desc"} page.should render(page_children_each_tags(%{order="asdf"})).with_error(message) end it "should limit the number of children when given a 'limit' attribute" do page.should render(page_children_each_tags(%{limit="5"})).as('a b c d e ') end it "should limit and offset the children when given 'limit' and 'offset' attributes" do page.should render(page_children_each_tags(%{offset="3" limit="5"})).as('d e f g h ') end it "should change the sort order when given an 'order' attribute" do page.should render(page_children_each_tags(%{order="desc"})).as('j i h g f e d c b a ') end it "should sort by the 'by' attribute" do page.should render(page_children_each_tags(%{by="breadcrumb"})).as('f e d c b a j i h g ') end it "should sort by the 'by' attribute according to the 'order' attribute" do page.should render(page_children_each_tags(%{by="breadcrumb" order="desc"})).as('g h i j a b c d e f ') end describe 'with "status" attribute' do it "set to 'all' should list all children" do page.should render(page_children_each_tags(%{status="all"})).as("a b c d e f g h i j draft ") end it "set to 'draft' should list only children with 'draft' status" do page.should render(page_children_each_tags(%{status="draft"})).as('draft ') end it "set to 'published' should list only children with 'draft' status" do page.should render(page_children_each_tags(%{status="published"})).as('a b c d e f g h i j ') end it "set to an invalid status should render an error" do page.should render(page_children_each_tags(%{status="askdf"})).with_error("`status' attribute of `each' tag must be set to a valid status") end end end describe "" do it "should render for the first child" do tags = 'FIRST: ' expected = "FIRST:article article-2 article-3 article-4 " page(:news).should render(tags).as(expected) end end describe "" do it "should render for all but the first child" do tags = 'NOT-FIRST: ' expected = "article NOT-FIRST:article-2 NOT-FIRST:article-3 NOT-FIRST:article-4 " page(:news).should render(tags).as(expected) end end describe "" do it "should render for the last child" do tags = 'LAST: ' expected = "article article-2 article-3 LAST:article-4 " page(:news).should render(tags).as(expected) end end describe "" do it "should render for all but the last child" do tags = 'NOT-LAST: ' expected = "NOT-LAST:article NOT-LAST:article-2 NOT-LAST:article-3 article-4 " page(:news).should render(tags).as(expected) end end describe "" do it "should render the header when it changes" do tags = '[] ' expected = "[Dec/00] article [Feb/01] article-2 article-3 [Mar/01] article-4 " page(:news).should render(tags).as(expected) end it 'with "name" attribute should maintain a separate header' do tags = %{[] () } expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " page(:news).should render(tags).as(expected) end it 'with "restart" attribute set to one name should restart that header' do tags = %{[] () } expected = "[2000] (Dec) article [2001] (Feb) article-2 article-3 (Mar) article-4 " page(:news).should render(tags).as(expected) end it 'with "restart" attribute set to two names should restart both headers' do tags = %{[] () <> } expected = "[2000] (Dec) <01> article [2001] (Feb) <09> article-2 <24> article-3 (Mar) <06> article-4 " page(:news).should render(tags).as(expected) end end describe "" do it 'should render the number of children of the current page' do page(:parent).should render('').as('3') end it "should accept the same scoping conditions as " do page.should render('').as('10') page.should render('').as('11') page.should render('').as('1') page.should render('').as('0') end end describe "" do it 'should render its contents in the context of the first child page' do page(:parent).should render('').as('Child') end it 'should accept the same scoping attributes as ' do page.should render(page_children_first_tags).as('a') page.should render(page_children_first_tags(%{limit="5"})).as('a') page.should render(page_children_first_tags(%{offset="3" limit="5"})).as('d') page.should render(page_children_first_tags(%{order="desc"})).as('j') page.should render(page_children_first_tags(%{by="breadcrumb"})).as('f') page.should render(page_children_first_tags(%{by="breadcrumb" order="desc"})).as('g') end it "should render nothing when no children exist" do page(:first).should render('').as('') end end describe "" do it 'should render its contents in the context of the last child page' do page(:parent).should render('').as('Child 3') end it 'should accept the same scoping attributes as ' do page.should render(page_children_last_tags).as('j') page.should render(page_children_last_tags(%{limit="5"})).as('e') page.should render(page_children_last_tags(%{offset="3" limit="5"})).as('h') page.should render(page_children_last_tags(%{order="desc"})).as('a') page.should render(page_children_last_tags(%{by="breadcrumb"})).as('g') page.should render(page_children_last_tags(%{by="breadcrumb" order="desc"})).as('f') end it "should render nothing when no children exist" do page(:first).should render('').as('') end end describe "" do it "should render the 'body' part by default" do page.should render('').as('Assorted body.') end it "with 'part' attribute should render the specified part" do page(:home).should render('').as("Just a test.") end it "should prevent simple recursion" do page(:recursive_parts).should render('').with_error("Recursion error: already rendering the `body' part.") end it "should prevent deep recursion" do page(:recursive_parts).should render('').with_error("Recursion error: already rendering the `one' part.") page(:recursive_parts).should render('').with_error("Recursion error: already rendering the `two' part.") end describe "with inherit attribute" do it "missing or set to 'false' should render the current page's part" do page.should render('').as('') page.should render('').as('') end describe "set to 'true'" do it "should render an ancestor's part" do page.should render('').as('Assorted sidebar.') end it "should render nothing when no ancestor has the part" do page.should render('').as('') end describe "and contextual attribute" do it "set to 'true' should render the part in the context of the current page" do page(:parent).should render('').as('Parent sidebar.') page(:child).should render('').as('Child sidebar.') page(:grandchild).should render('').as('Grandchild sidebar.') end it "set to 'false' should render the part in the context of its containing page" do page(:parent).should render('').as('Home sidebar.') end it "should maintain the global page" do page(:first) page.should render('').as('First First') page.should render('').as('Home First') end end end it "set to an erroneous value should render an error" do page.should render('').with_error(%{`inherit' attribute of `content' tag must be set to either "true" or "false"}) end it "should render parts with respect to the current contextual page" do expected = "Child body. Child 2 body. Child 3 body. " page(:parent).should render(' ').as(expected) end end end describe "" do it "without 'part' attribute should render the contained block if the 'body' part exists" do page.should render('true').as('true') end it "should render the contained block if the specified part exists" do page.should render('true').as('true') end it "should not render the contained block if the specified part does not exist" do page.should render('true').as('') end describe "with more than one part given (separated by comma)" do it "should render the contained block only if all specified parts exist" do page(:home).should render('true').as('true') end it "should not render the contained block if at least one of the specified parts does not exist" do page(:home).should render('true').as('') end describe "with inherit attribute set to 'true'" do it 'should render the contained block if the current or ancestor pages have the specified parts' do page(:guests).should render('true').as('true') end it 'should not render the contained block if the current or ancestor pages do not have all of the specified parts' do page(:guests).should render('true').as('') end end describe "with inherit attribute set to 'false'" do it 'should render the contained block if the current page has the specified parts' do page(:guests).should render('true').as('') end it 'should not render the contained block if the current or ancestor pages do not have all of the specified parts' do page(:guests).should render('true').as('') end end describe "with the 'find' attribute set to 'any'" do it "should render the contained block if any of the specified parts exist" do page.should render('true').as('true') end end describe "with the 'find' attribute set to 'all'" do it "should render the contained block if all of the specified parts exist" do page(:home).should render('true').as('true') end it "should not render the contained block if all of the specified parts do not exist" do page.should render('true').as('') end end end end describe "" do describe "with inherit attribute set to 'true'" do it 'should not render the contained block if the current or ancestor pages have the specified parts' do page(:guests).should render('true').as('') end it 'should render the contained block if the current or ancestor pages do not have the specified parts' do page(:guests).should render('true').as('true') end it "should not render the contained block if the specified part does not exist but does exist on an ancestor" do page.should render('false').as('') end end it "without 'part' attribute should not render the contained block if the 'body' part exists" do page.should render('false').as('') end it "should not render the contained block if the specified part exists" do page.should render('false').as('') end it "should render the contained block if the specified part does not exist" do page.should render('false').as('false') end it "should render the contained block if the specified part does not exist but does exist on an ancestor" do page.should render('false').as('false') end describe "with more than one part given (separated by comma)" do it "should not render the contained block if all of the specified parts exist" do page(:home).should render('true').as('') end it "should render the contained block if at least one of the specified parts exists" do page(:home).should render('true').as('true') end describe "with the 'inherit' attribute set to 'true'" do it "should render the contained block if the current or ancestor pages have none of the specified parts" do page.should render('true').as('true') end it "should not render the contained block if all of the specified parts are present on the current or ancestor pages" do page(:party).should render('true').as('') end end describe "with the 'find' attribute set to 'all'" do it "should not render the contained block if all of the specified parts exist" do page(:home).should render('true').as('') end it "should render the contained block unless all of the specified parts exist" do page.should render('true').as('true') end end describe "with the 'find' attribute set to 'any'" do it "should not render the contained block if any of the specified parts exist" do page.should render('true').as('') end end end end describe "" do it "should render the author of the current page" do page.should render('').as('Admin') end it "should render nothing when the page has no author" do page(:no_user).should render('').as('') end end describe "" do before :each do page(:dated) end it "should render the published date of the page" do page.should render('').as('Wednesday, January 11, 2006') end it "should format the published date according to the 'format' attribute" do page.should render('').as('11 Jan 2006') end describe "with 'for' attribute" do it "set to 'now' should render the current date in the current Time.zone" do page.should render('').as(Time.zone.now.strftime("%A, %B %d, %Y")) end it "set to 'created_at' should render the creation date" do page.should render('').as('Tuesday, January 10, 2006') end it "set to 'updated_at' should render the update date" do page.should render('').as('Thursday, January 12, 2006') end it "set to 'published_at' should render the publish date" do page.should render('').as('Wednesday, January 11, 2006') end it "set to an invalid attribute should render an error" do page.should render('').with_error("Invalid value for 'for' attribute.") end end it "should use the currently set timezone" do Time.zone = "Tokyo" format = "%H:%m" expected = page.published_at.in_time_zone(ActiveSupport::TimeZone['Tokyo']).strftime(format) page.should render(%Q() ).as(expected) end end describe "" do it "should render a link to the current page" do page.should render('').as('Assorted') end it "should render its contents as the text of the link" do page.should render('Test').as('Test') end it "should pass HTML attributes to the tag" do expected = 'Assorted' page.should render('').as(expected) end it "should add the anchor attribute to the link as a URL anchor" do page.should render('Test').as('Test') end it "should render a link for the current contextual page" do expected = %{Child Child 2 Child 3 } page(:parent).should render(' ' ).as(expected) end it "should scope the link within the relative URL root" do page(:assorted).should render('').with_relative_root('/foo').as('Assorted') end end describe "" do it "should render the contents of the specified snippet" do page.should render('').as('test') end it "should render an error when the snippet does not exist" do page.should render('').with_error('snippet not found') end it "should render an error when not given a 'name' attribute" do page.should render('').with_error("`snippet' tag must contain `name' attribute") end it "should filter the snippet with its assigned filter" do page.should render('').matching(%r{

markdown

}) end it "should maintain the global page inside the snippet" do page(:parent).should render('').as("#{@page.title} " * @page.children.count) end it "should maintain the global page when the snippet renders recursively" do page(:child).should render('').as("Great GrandchildGrandchildChild") end it "should render the specified snippet when called as an empty double-tag" do page.should render('').as('test') end it "should capture contents of a double tag, substituting for in snippet" do page.should render('inner'). as('Before...inner...and after') end it "should do nothing with contents of double tag when snippet doesn't yield" do page.should render('content disappears!'). as('test') end it "should render nested yielding snippets" do page.should render('Hello, World!'). as('
Before...Hello, World!...and after
') end it "should render double-tag snippets called from within a snippet" do page.should render('the content'). as('above the content below') end it "should render contents each time yield is called" do page.should render('French'). as('French is Frencher than French') end end it "should do nothing when called from page body" do page.should render('').as("") end it ' should render a randomly selected contained ' do page.should render(" 1 2 3 ").matching(/^(1|2|3)$/) end it ' should render a randomly selected, dynamically set ' do page(:parent).should render("").matching(/^(Child|Child\ 2|Child\ 3)$/) end it ' should render nothing it contains' do page.should render('just a small test').as('just a test') end describe "" do it "should render the nested tag by default" do tags = %{ } expected = %{Home Assorted Parent} page.should render(tags).as(expected) end it "should render the nested tag for URLs that match the current page" do tags = %{ } expected = %{Home Assorted Parent Radius} page(:parent).should render(tags).as(expected) end it "should render the nested tag for URLs that exactly match the current page" do tags = %{ | } expected = %{Home: Boy | Assorted | Parent} page.should render(tags).as(expected) end it "should render the nested tag between each link" do tags = %{ :: } expected = %{Home :: Assorted :: Parent} page.should render(tags).as(expected) end it 'without urls should render nothing' do page.should render(%{}).as('') end it 'without a nested tag should render an error' do page.should render(%{}).with_error( "`navigation' tag must include a `normal' tag") end it 'with urls without trailing slashes should match corresponding pages' do tags = %{ } expected = %{Home Assorted Parent Radius} page.should render(tags).as(expected) end it 'should prune empty blocks' do tags = %{ | } expected = %{Home: Boy | Archives | Docs} page(:radius).should render(tags).as(expected) end end describe "" do it "should change the local page to the page specified in the 'url' attribute" do page.should render(%{}).as('Child') end it "should render an error without the 'url' attribute" do page.should render(%{}).with_error("`find' tag must contain `url' attribute") end it "should render nothing when the 'url' attribute does not point to a page" do page.should render(%{}).as('') end it "should render nothing when the 'url' attribute does not point to a page and a custom 404 page exists" do page.should render(%{}).as('') end it "should scope contained tags to the found page" do page.should render(%{ }).as('child child-2 child-3 ') end it "should accept a path relative to the current page" do page(:great_grandchild).should render(%{}).as("Child 2") end end it ' should escape HTML-related characters into entities' do page.should render('a bold move').as('<strong>a bold move</strong>') end it ' should render an RFC1123-compatible date' do page(:dated).should render('').as('Wed, 11 Jan 2006 00:00:00 GMT') end describe "" do it "should render a series of breadcrumb links separated by >" do expected = %{Home > Parent > Child > Grandchild > Great Grandchild} page(:great_grandchild).should render('').as(expected) end it "with a 'separator' attribute should use the separator instead of >" do expected = %{Home :: Parent} page(:parent).should render('').as(expected) end it "with a 'nolinks' attribute set to 'true' should not render links" do expected = %{Home > Parent} page(:parent).should render('').as(expected) end it "with a relative URL root should scope links to the relative root" do expected = 'Home > Assorted' page(:assorted).should render('').with_relative_root('/foo').as(expected) end end describe "" do describe "with 'matches' attribute" do it "should render the contained block if the page URL matches" do page.should render('true').as('true') end it "should not render the contained block if the page URL does not match" do page.should render('true').as('') end it "set to a malformatted regexp should render an error" do page.should render('true').with_error("Malformed regular expression in `matches' argument of `if_url' tag: unmatched (: /as(sorted\\/$/") end it "without 'ignore_case' attribute should ignore case by default" do page.should render('true').as('true') end describe "with 'ignore_case' attribute" do it "set to 'true' should use a case-insensitive match" do page.should render('true').as('true') end it "set to 'false' should use a case-sensitive match" do page.should render('true').as('') end end end it "with no attributes should render an error" do page.should render('test').with_error("`if_url' tag must contain a `matches' attribute.") end end describe "" do describe "with 'matches' attribute" do it "should not render the contained block if the page URL matches" do page.should render('true').as('') end it "should render the contained block if the page URL does not match" do page.should render('true').as('true') end it "set to a malformatted regexp should render an error" do page.should render('true').with_error("Malformed regular expression in `matches' argument of `unless_url' tag: unmatched (: /as(sorted\\/$/") end it "without 'ignore_case' attribute should ignore case by default" do page.should render('true').as('') end describe "with 'ignore_case' attribute" do it "set to 'true' should use a case-insensitive match" do page.should render('true').as('') end it "set to 'false' should use a case-sensitive match" do page.should render('true').as('true') end end end it "with no attributes should render an error" do page.should render('test').with_error("`unless_url' tag must contain a `matches' attribute.") end end describe "" do it "should render passed values in succession" do page.should render(' ').as('first second') end it "should return to the beginning of the cycle when reaching the end" do page.should render(' ').as('first second first') end it "should use a default cycle name of 'cycle'" do page.should render(' ').as('first second') end it "should maintain separate cycle counters" do page.should render(' ').as('first one second two') end it "should reset the counter" do page.should render(' ').as('first first') end it "should require the values attribute" do page.should render('').with_error("`cycle' tag must contain a `values' attribute.") end end describe "" do it "should render the contained block when on the dev site" do page.should render('-dev-').as('-dev-').on('dev.site.com') end it "should not render the contained block when not on the dev site" do page.should render('-dev-').as('--') end describe "on an included page" do it "should render the contained block when on the dev site" do page.should render('--').as('-dev-').on('dev.site.com') end it "should not render the contained block when not on the dev site" do page.should render('--').as('--') end end end describe "" do it "should not render the contained block when not on the dev site" do page.should render('-not dev-').as('--').on('dev.site.com') end it "should render the contained block when not on the dev site" do page.should render('-not dev-').as('-not dev-') end describe "on an included page" do it "should not render the contained block when not on the dev site" do page.should render('--').as('--').on('dev.site.com') end it "should render the contained block when not on the dev site" do page.should render('--').as('-not dev-') end end end describe "" do it "should render the status of the current page" do status_tag = "" page(:a).should render(status_tag).as("Published") page(:hidden).should render(status_tag).as("Hidden") page(:draft).should render(status_tag).as("Draft") end describe "with the downcase attribute set to 'true'" do it "should render the lowercased status of the current page" do status_tag_lc = "" page(:a).should render(status_tag_lc).as("published") page(:hidden).should render(status_tag_lc).as("hidden") page(:draft).should render(status_tag_lc).as("draft") end end end describe "" do it "should render the tag's content when the current page is an ancestor of tag.locals.page" do page(:radius).should render(%{true}).as('true') end it "should not render the tag's content when current page is not an ancestor of tag.locals.page" do page(:parent).should render(%{true}).as('') end end describe "" do it "should render the tag's content when the current page is not an ancestor of tag.locals.page" do page(:parent).should render(%{true}).as('true') end it "should not render the tag's content when current page is an ancestor of tag.locals.page" do page(:radius).should render(%{true}).as('') end end describe "" do it "should render the tag's content when the current page is the same as the local contextual page" do page(:home).should render(%{true}).as('true') end it "should not render the tag's content when the current page is not the same as the local contextual page" do page(:radius).should render(%{true}).as('') end end describe "" do it "should render the tag's content when the current page is not the same as the local contextual page" do page(:radius).should render(%{true}).as('true') end it "should not render the tag's content when the current page is the same as the local contextual page" do page(:home).should render(%{true}).as('') end end describe "" do it "should render tags for the description and keywords" do page(:home).should render('').as(%{}) end it "should render tags with escaped values for the description and keywords" do page.should render('').as(%{}) end describe "with 'tag' attribute set to 'false'" do it "should render the contents of the description and keywords" do page(:home).should render('').as(%{The homepageHome, Page}) end it "should escape the contents of the description and keywords" do page.should render('').as("sweet & harmonious biscuitssweet & harmonious biscuits") end end end describe "" do it "should render a tag for the description" do page(:home).should render('').as(%{}) end it "should render a tag with escaped value for the description" do page.should render('').as(%{}) end describe "with 'tag' attribute set to 'false'" do it "should render the contents of the description" do page(:home).should render('').as(%{The homepage}) end it "should escape the contents of the description" do page.should render('').as("sweet & harmonious biscuits") end end end describe "" do it "should render a tag for the keywords" do page(:home).should render('').as(%{}) end it "should render a tag with escaped value for the keywords" do page.should render('').as(%{}) end describe "with 'tag' attribute set to 'false'" do it "should render the contents of the keywords" do page(:home).should render('').as(%{Home, Page}) end it "should escape the contents of the keywords" do page.should render('').as("sweet & harmonious biscuits") end end end private def page(symbol = nil) if symbol.nil? @page ||= pages(:assorted) else @page = pages(symbol) end end def page_children_each_tags(attr = nil) attr = ' ' + attr unless attr.nil? "
" end def page_children_first_tags(attr = nil) attr = ' ' + attr unless attr.nil? "
" end def page_children_last_tags(attr = nil) attr = ' ' + attr unless attr.nil? "" end def page_eachable_children(page) page.children.select(&:published?).reject(&:virtual) end end