radiant 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of radiant might be problematic. Click here for more details.

Files changed (205) hide show
  1. data/CHANGELOG +1 -0
  2. data/CONTRIBUTORS +12 -0
  3. data/LICENSE +9 -0
  4. data/README +91 -0
  5. data/Rakefile +10 -0
  6. data/app/behaviors/archive_behavior.rb +42 -0
  7. data/app/behaviors/archive_day_index_behavior.rb +30 -0
  8. data/app/behaviors/archive_month_index_behavior.rb +30 -0
  9. data/app/behaviors/archive_year_index_behavior.rb +30 -0
  10. data/app/behaviors/env_behavior.rb +18 -0
  11. data/app/behaviors/page_missing_behavior.rb +31 -0
  12. data/app/controllers/admin/export_controller.rb +8 -0
  13. data/app/controllers/admin/layout_controller.rb +23 -0
  14. data/app/controllers/admin/model_controller.rb +119 -0
  15. data/app/controllers/admin/page_controller.rb +119 -0
  16. data/app/controllers/admin/snippet_controller.rb +6 -0
  17. data/app/controllers/admin/user_controller.rb +45 -0
  18. data/app/controllers/admin/welcome_controller.rb +39 -0
  19. data/app/controllers/application.rb +32 -0
  20. data/app/controllers/site_controller.rb +54 -0
  21. data/app/filters/markdown_filter.rb +9 -0
  22. data/app/filters/textile_filter.rb +9 -0
  23. data/app/helpers/admin/export_helper.rb +2 -0
  24. data/app/helpers/admin/layout_helper.rb +2 -0
  25. data/app/helpers/admin/page_helper.rb +10 -0
  26. data/app/helpers/admin/snippet_helper.rb +2 -0
  27. data/app/helpers/admin/user_helper.rb +2 -0
  28. data/app/helpers/admin/welcome_helper.rb +2 -0
  29. data/app/helpers/application_helper.rb +141 -0
  30. data/app/helpers/site_helper.rb +2 -0
  31. data/app/models/archive_finder.rb +66 -0
  32. data/app/models/behavior.rb +194 -0
  33. data/app/models/layout.rb +13 -0
  34. data/app/models/page.rb +91 -0
  35. data/app/models/page_context.rb +526 -0
  36. data/app/models/page_part.rb +13 -0
  37. data/app/models/radiant/config.rb +53 -0
  38. data/app/models/radiant/exporter.rb +11 -0
  39. data/app/models/response_cache.rb +112 -0
  40. data/app/models/snippet.rb +16 -0
  41. data/app/models/status.rb +31 -0
  42. data/app/models/text_filter.rb +11 -0
  43. data/app/models/user.rb +70 -0
  44. data/app/models/user_action_observer.rb +13 -0
  45. data/app/views/admin/layout/index.rhtml +38 -0
  46. data/app/views/admin/layout/new.rhtml +37 -0
  47. data/app/views/admin/layout/remove.rhtml +17 -0
  48. data/app/views/admin/page/_node.rhtml +51 -0
  49. data/app/views/admin/page/_part.rhtml +17 -0
  50. data/app/views/admin/page/children.rhtml +4 -0
  51. data/app/views/admin/page/index.rhtml +172 -0
  52. data/app/views/admin/page/new.rhtml +164 -0
  53. data/app/views/admin/page/remove.rhtml +14 -0
  54. data/app/views/admin/snippet/index.rhtml +36 -0
  55. data/app/views/admin/snippet/new.rhtml +28 -0
  56. data/app/views/admin/snippet/remove.rhtml +16 -0
  57. data/app/views/admin/user/index.rhtml +43 -0
  58. data/app/views/admin/user/new.rhtml +48 -0
  59. data/app/views/admin/user/preferences.rhtml +29 -0
  60. data/app/views/admin/user/remove.rhtml +16 -0
  61. data/app/views/admin/welcome/login.rhtml +51 -0
  62. data/app/views/layouts/application.rhtml +75 -0
  63. data/app/views/site/not_found.rhtml +3 -0
  64. data/bin/radiant +305 -0
  65. data/config/boot.rb +80 -0
  66. data/config/database.mysql.yml +20 -0
  67. data/config/database.postgresql.yml +20 -0
  68. data/config/database.sqlite.yml +20 -0
  69. data/config/environment.rb +76 -0
  70. data/config/environments/development.rb +20 -0
  71. data/config/environments/production.rb +22 -0
  72. data/config/environments/test.rb +20 -0
  73. data/config/locomotive.yml +6 -0
  74. data/config/routes.rb +64 -0
  75. data/db/development_structure.sql +80 -0
  76. data/db/migrate/001_create_radiant_tables.rb +73 -0
  77. data/db/migrate/002_insert_initial_data.rb +45 -0
  78. data/db/migrate/003_rename_behavior_column.rb +9 -0
  79. data/db/migrate/004_rename_filter_column.rb +11 -0
  80. data/db/migrate/005_add_virtual_column_to_page.rb +9 -0
  81. data/db/migrate/006_integer_columns_to_boolean.rb +11 -0
  82. data/db/migrate/007_remove_virtual_column_from_page.rb +9 -0
  83. data/db/migrate/008_add_virtual_column_to_page_again.rb +9 -0
  84. data/db/migrate/009_add_content_type_field_to_layout.rb +9 -0
  85. data/db/schema.rb +74 -0
  86. data/db/templates/empty.yml +2 -0
  87. data/db/templates/simple-blog.yml +197 -0
  88. data/db/templates/styled-blog.yml +472 -0
  89. data/lib/advanced_delegation.rb +21 -0
  90. data/lib/archive_index_behavior_tags_and_methods.rb +48 -0
  91. data/lib/generators/behavior/USAGE +16 -0
  92. data/lib/generators/behavior/behavior_generator.rb +22 -0
  93. data/lib/generators/behavior/templates/model.rb.template +9 -0
  94. data/lib/generators/behavior/templates/unit_test.rb.template +16 -0
  95. data/lib/generators/filter/USAGE +16 -0
  96. data/lib/generators/filter/filter_generator.rb +22 -0
  97. data/lib/generators/filter/templates/model.rb.template +8 -0
  98. data/lib/generators/filter/templates/unit_test.rb.template +7 -0
  99. data/lib/inheritable_class_attributes.rb +65 -0
  100. data/lib/login_system.rb +80 -0
  101. data/lib/plugins/index_quoting_fix/init.rb +32 -0
  102. data/lib/plugins/string_io/init.rb +2 -0
  103. data/lib/radiant.rb +5 -0
  104. data/lib/registerable.rb +70 -0
  105. data/lib/tasks/release.rake +84 -0
  106. data/public/404.html +8 -0
  107. data/public/500.html +8 -0
  108. data/public/dispatch.cgi +10 -0
  109. data/public/dispatch.fcgi +24 -0
  110. data/public/dispatch.rb +10 -0
  111. data/public/favicon.ico +0 -0
  112. data/public/images/add-child.png +0 -0
  113. data/public/images/brown-bottom-line.gif +0 -0
  114. data/public/images/clear-page-cache.png +0 -0
  115. data/public/images/collapse.png +0 -0
  116. data/public/images/expand.png +0 -0
  117. data/public/images/minus.png +0 -0
  118. data/public/images/new-homepage.png +0 -0
  119. data/public/images/new-layout.png +0 -0
  120. data/public/images/new-snippet.png +0 -0
  121. data/public/images/new-user.png +0 -0
  122. data/public/images/page.png +0 -0
  123. data/public/images/plus.png +0 -0
  124. data/public/images/remove-disabled.png +0 -0
  125. data/public/images/remove.png +0 -0
  126. data/public/images/snippet.png +0 -0
  127. data/public/images/spinner.gif +0 -0
  128. data/public/images/view-site.gif +0 -0
  129. data/public/images/virtual-page.png +0 -0
  130. data/public/javascripts/application.js +2 -0
  131. data/public/javascripts/controls.js +815 -0
  132. data/public/javascripts/dragdrop.js +913 -0
  133. data/public/javascripts/effects.js +958 -0
  134. data/public/javascripts/pngfix.js +78 -0
  135. data/public/javascripts/prototype.js +2006 -0
  136. data/public/javascripts/ruledtable.js +28 -0
  137. data/public/javascripts/string.js +23 -0
  138. data/public/javascripts/tabcontrol.js +140 -0
  139. data/public/robots.txt +1 -0
  140. data/public/stylesheets/admin.css +464 -0
  141. data/script/about +3 -0
  142. data/script/breakpointer +3 -0
  143. data/script/console +3 -0
  144. data/script/destroy +3 -0
  145. data/script/generate +3 -0
  146. data/script/performance/benchmarker +3 -0
  147. data/script/performance/profiler +3 -0
  148. data/script/plugin +3 -0
  149. data/script/process/reaper +3 -0
  150. data/script/process/spawner +3 -0
  151. data/script/process/spinner +3 -0
  152. data/script/runner +3 -0
  153. data/script/server +3 -0
  154. data/script/setup_database +297 -0
  155. data/test/fixtures/layouts.yml +26 -0
  156. data/test/fixtures/page_parts.yml +99 -0
  157. data/test/fixtures/pages.yml +359 -0
  158. data/test/fixtures/pages.yml.rej +28 -0
  159. data/test/fixtures/snippets.yml +18 -0
  160. data/test/fixtures/users.yml +30 -0
  161. data/test/functional/admin/export_controller_test.rb +22 -0
  162. data/test/functional/admin/layout_controller_test.rb +40 -0
  163. data/test/functional/admin/model_controller_test.rb +152 -0
  164. data/test/functional/admin/page_controller_test.rb +179 -0
  165. data/test/functional/admin/snippet_controller_test.rb +11 -0
  166. data/test/functional/admin/user_controller_test.rb +71 -0
  167. data/test/functional/admin/welcome_controller_test.rb +48 -0
  168. data/test/functional/application_controller_test.rb +44 -0
  169. data/test/functional/login_system_test.rb +155 -0
  170. data/test/functional/site_controller_test.rb +172 -0
  171. data/test/helpers/archive_index_test_helper.rb +35 -0
  172. data/test/helpers/behavior_render_test_helper.rb +34 -0
  173. data/test/helpers/behavior_test_helper.rb +47 -0
  174. data/test/helpers/caching_test_helper.rb +41 -0
  175. data/test/helpers/layout_test_helper.rb +35 -0
  176. data/test/helpers/page_part_test_helper.rb +49 -0
  177. data/test/helpers/page_test_helper.rb +36 -0
  178. data/test/helpers/snippet_test_helper.rb +32 -0
  179. data/test/helpers/user_test_helper.rb +34 -0
  180. data/test/helpers/validation_test_helper.rb +42 -0
  181. data/test/test_helper.rb +54 -0
  182. data/test/unit/behavior_test.rb +196 -0
  183. data/test/unit/behaviors/archive_behavior_test.rb +33 -0
  184. data/test/unit/behaviors/archive_day_index_behavior_test.rb +21 -0
  185. data/test/unit/behaviors/archive_month_index_behavior_test.rb +21 -0
  186. data/test/unit/behaviors/archive_year_index_behavior_test.rb +21 -0
  187. data/test/unit/behaviors/page_missing_behavior_test.rb +27 -0
  188. data/test/unit/filters/markdown_filter_test.rb +14 -0
  189. data/test/unit/filters/textile_filter_test.rb +14 -0
  190. data/test/unit/inheritable_class_attributes_test.rb +47 -0
  191. data/test/unit/layout_test.rb +29 -0
  192. data/test/unit/page_context_test.rb +375 -0
  193. data/test/unit/page_context_test.rb.rej +26 -0
  194. data/test/unit/page_part_test.rb +44 -0
  195. data/test/unit/page_test.rb +224 -0
  196. data/test/unit/radiant/config_test.rb +46 -0
  197. data/test/unit/radiant/exporter_test.rb +26 -0
  198. data/test/unit/registerable_test.rb +68 -0
  199. data/test/unit/response_cache_test.rb +133 -0
  200. data/test/unit/snippet_test.rb +47 -0
  201. data/test/unit/status_test.rb +43 -0
  202. data/test/unit/text_filter_test.rb +14 -0
  203. data/test/unit/user_action_observer_test.rb +40 -0
  204. data/test/unit/user_test.rb +138 -0
  205. metadata +355 -0
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class ArchiveBehaviorTest < Test::Unit::TestCase
4
+ fixtures :pages
5
+
6
+ def test_child_url
7
+ child = pages(:article)
8
+ assert_equal '/archive/2000/05/01/article/', child.url
9
+ end
10
+
11
+ def test_child_url__nil_published_at_date
12
+ child = pages(:article_draft)
13
+ assert_nil child.published_at
14
+ assert_equal '/archive/' + Time.now.strftime('%Y/%m/%d') + '/draft/', child.url
15
+ end
16
+
17
+ def test_find__year_index
18
+ expected = pages(:year_index)
19
+ year_index = Page.find_by_url('/archive/2000/')
20
+ assert_equal expected, year_index
21
+ end
22
+ def test_find__month_index
23
+ expected = pages(:month_index)
24
+ month_index = Page.find_by_url('/archive/2000/06/')
25
+ assert_equal expected, month_index
26
+ end
27
+ def test_find__day_index
28
+ expected = pages(:day_index)
29
+ day_index = Page.find_by_url('/archive/2000/06/09/')
30
+ assert_equal expected, day_index
31
+ end
32
+
33
+ end
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class ArchiveDayIndexBehaviorTest < Test::Unit::TestCase
4
+ fixtures :pages
5
+ test_helper :archive_index, :behavior_render
6
+
7
+ def setup
8
+ @page = pages(:day_index)
9
+ end
10
+
11
+ def test_children_tag
12
+ assert_renders 'article-2 ', '<r:archive:children:each><r:slug /> </r:archive:children:each>', '/archive/2000/06/09/'
13
+ assert_renders 'article-2 ', '<r:archive:children:each><r:slug /> </r:archive:children:each>', '/archive/2000/06/09'
14
+ end
15
+
16
+ def test_title_tag
17
+ assert_renders 'June 09, 2000 Archive', '<r:title />', '/archive/2000/06/09/'
18
+ end
19
+
20
+ include ArchiveIndexTests
21
+ end
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class ArchiveMonthIndexBehaviorTest < Test::Unit::TestCase
4
+ fixtures :pages
5
+ test_helper :archive_index, :behavior_render
6
+
7
+ def setup
8
+ @page = pages(:month_index)
9
+ end
10
+
11
+ def test_children_tag
12
+ assert_renders 'article-2 article-3 ', '<r:archive:children:each><r:slug /> </r:archive:children:each>', '/archive/2000/06/'
13
+ assert_renders 'article-2 article-3 ', '<r:archive:children:each><r:slug /> </r:archive:children:each>', '/archive/2000/06'
14
+ end
15
+
16
+ def test_title_tag
17
+ assert_renders 'June 2000 Archive', '<r:title />', '/archive/2000/06/'
18
+ end
19
+
20
+ include ArchiveIndexTests
21
+ end
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class ArchiveYearIndexBehaviorTest < Test::Unit::TestCase
4
+ fixtures :pages
5
+ test_helper :archive_index, :behavior_render
6
+
7
+ def setup
8
+ @page = pages(:year_index)
9
+ end
10
+
11
+ def test_children_tag
12
+ assert_renders 'article article-2 article-3 article-4 ', '<r:archive:children:each><r:slug /> </r:archive:children:each>', '/archive/2000/'
13
+ assert_renders 'article article-2 article-3 article-4 ', '<r:archive:children:each><r:slug /> </r:archive:children:each>', '/archive/2000'
14
+ end
15
+
16
+ def test_title_tag
17
+ assert_renders '2000 Archive', '<r:title />', '/archive/2000/'
18
+ end
19
+
20
+ include ArchiveIndexTests
21
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class PageMissingBehaviorTest < Test::Unit::TestCase
4
+ fixtures :pages
5
+ test_helper :behavior_render
6
+
7
+ def setup
8
+ @page = pages(:missing)
9
+ end
10
+
11
+ def test_url
12
+ assert_renders 'http://testhost.tld/gallery/asdf?param=4', '<r:attempted_url />', '/gallery/asdf?param=4'
13
+ end
14
+
15
+ def test_virtual
16
+ assert_equal true, @page.virtual?
17
+ end
18
+
19
+ def test_cache
20
+ assert_equal false, @page.cache?
21
+ end
22
+
23
+ def test_headers
24
+ assert_headers({'Status' => '404 Not Found'}, '/gallery/asdf')
25
+ end
26
+
27
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class MarkdownFilterTest < Test::Unit::TestCase
4
+
5
+ def test_registered_id
6
+ assert_equal 'Markdown', MarkdownFilter.registered_id
7
+ end
8
+
9
+ def test_filter
10
+ markdown = MarkdownFilter.new
11
+ assert_equal '<p><strong>strong</strong></p>', markdown.filter('**strong**')
12
+ end
13
+
14
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../../test_helper'
2
+
3
+ class TextileFilterTest < Test::Unit::TestCase
4
+
5
+ def test_registered_id
6
+ assert_equal 'Textile', TextileFilter.registered_id
7
+ end
8
+
9
+ def test_filter
10
+ textile = TextileFilter.new
11
+ assert_equal '<h1>Test</h1>', textile.filter('h1. Test')
12
+ end
13
+
14
+ end
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'inheritable_class_attributes'
3
+
4
+ class InheritableClassAttributesTest < Test::Unit::TestCase
5
+ class A
6
+ include InheritableClassAttributes
7
+
8
+ cattr_inheritable_reader :reader
9
+ @reader = :test
10
+
11
+ cattr_inheritable_writer :writer
12
+ @writer = :test
13
+
14
+ cattr_inheritable_accessor :accessor
15
+ @accessor = :test
16
+ end
17
+
18
+ def test_inheritable_reader
19
+ assert_equal :test, A.reader
20
+ end
21
+
22
+ def test_inheritable_writer
23
+ A.writer = :changed
24
+ assert_equal :changed, A.module_eval(%{@writer})
25
+ end
26
+
27
+ def test_inheritable_accessor
28
+ A.accessor = :changed
29
+ assert_equal :changed, A.accessor
30
+ end
31
+
32
+ def test_inheritance
33
+ A.accessor = :unchanged
34
+ Kernel.module_eval %{ class B < A; end }
35
+ B.accessor = :changed
36
+ assert_equal :changed, B.accessor
37
+ assert_equal :unchanged, A.accessor
38
+ end
39
+
40
+ def test_array_inheritance
41
+ A.accessor = [1,2,3]
42
+ Kernel.module_eval %{ class C < A; end }
43
+ C.accessor << 4
44
+ assert_equal [1,2,3,4], C.accessor
45
+ assert_equal [1,2,3], A.accessor
46
+ end
47
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class LayoutTest < Test::Unit::TestCase
4
+ fixtures :layouts
5
+ test_helper :layouts, :validations
6
+
7
+ def setup
8
+ @layout = @model = Layout.new(VALID_LAYOUT_PARAMS)
9
+ end
10
+
11
+ def test_validates_presence_of
12
+ assert_valid :name, 'Just a Test'
13
+ assert_invalid :name, 'required', nil, '', ' '
14
+ end
15
+
16
+ def test_validates_uniqueness_of
17
+ assert_invalid :name, 'name already in use', 'Home Page'
18
+ assert_valid :name, 'Something Else'
19
+ end
20
+
21
+ def test_validates_length_of
22
+ {
23
+ :name => 100
24
+ }.each do |field, max|
25
+ assert_invalid field, ('%d-character limit' % max), 'x' * (max + 1)
26
+ assert_valid field, 'x' * max
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,375 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class PageContextTest < Test::Unit::TestCase
4
+ fixtures :pages, :page_parts, :layouts, :snippets, :users
5
+
6
+ def setup
7
+ setup_for_page(:radius)
8
+ end
9
+
10
+ def test_initialize
11
+ assert_equal(@page, @context.page)
12
+ end
13
+
14
+ def test_tag_page
15
+ assert_parse_output 'Radius Test Page', "<r:title />"
16
+ assert_parse_output 'Ruby Home Page | Radius Test Page', %{<r:find url="/"><r:title /> | <r:page:title /></r:find>}
17
+ end
18
+
19
+ def test_tags_page_attributes
20
+ @page.attributes.keys.each do |attr|
21
+ value = @page.send(attr)
22
+ unless [:created_by, :updated_by].include? attr.to_s.intern
23
+ assert_parse_output value.to_s, "<r:#{attr} />"
24
+ end
25
+ end
26
+ end
27
+
28
+ def test_tag_children
29
+ expected = 'Radius Test Child 1 Radius Test Child 2 Radius Test Child 3 '
30
+ input = '<r:children:each><r:title /> </r:children:each>'
31
+ assert_parse_output expected, input
32
+ end
33
+ def test_tag_children_each
34
+ assert_parse_output 'radius/child-1 radius/child-2 radius/child-3 ' , '<r:children:each><r:page><r:slug />/<r:child:slug /> </r:page></r:children:each>'
35
+ end
36
+ def test_tag_children_each_attributes
37
+ setup_for_page(:assorted)
38
+ assert_parse_output 'a b c d e f g h i j ', page_children_each_tags
39
+ assert_parse_output 'a b c d e ', page_children_each_tags(%{limit="5"})
40
+ assert_parse_output 'd e f g h ', page_children_each_tags(%{offset="3" limit="5"})
41
+ assert_parse_output 'j i h g f e d c b a ', page_children_each_tags(%{order="desc"})
42
+ assert_parse_output 'f e d c b a j i h g ', page_children_each_tags(%{by="breadcrumb"})
43
+ assert_parse_output 'g h i j a b c d e f ', page_children_each_tags(%{by="breadcrumb" order="desc"})
44
+ end
45
+ def test_tag_children_each_with_status_attribute
46
+ setup_for_page(:assorted)
47
+ assert_parse_output_match /^(draft |)a b c d e f g h i j( draft|) $/, page_children_each_tags(%{status="all"})
48
+ assert_parse_output 'draft ', page_children_each_tags(%{status="draft"})
49
+ assert_parse_output 'a b c d e f g h i j ', page_children_each_tags(%{status="published"})
50
+ assert_parse_output_match "`status' attribute of `each' tag must be set to a valid status", page_children_each_tags(%{status="askdf"})
51
+ end
52
+ def test_tag_children_each_attributes_with_invalid_limit
53
+ message = "`limit' attribute of `each' tag must be a positive number between 1 and 4 digits"
54
+ assert_parse_output_match message, page_children_each_tags(%{limit="a"})
55
+ assert_parse_output_match message, page_children_each_tags(%{limit="-10"})
56
+ assert_parse_output_match message, page_children_each_tags(%{limit="50000"})
57
+ end
58
+ def test_tag_children_each_attributes_with_invalid_offset
59
+ message = "`offset' attribute of `each' tag must be a positive number between 1 and 4 digits"
60
+ assert_parse_output_match message, page_children_each_tags(%{offset="a"})
61
+ assert_parse_output_match message, page_children_each_tags(%{offset="-10"})
62
+ assert_parse_output_match message, page_children_each_tags(%{offset="50000"})
63
+ end
64
+ def test_tag_children_each_attributes_with_invalid_by_field_name
65
+ message = "`by' attribute of `each' tag must be set to a valid field name"
66
+ assert_parse_output_match message, page_children_each_tags(%{by="non-existant-field"})
67
+ end
68
+ def test_tag_children_each_attributes_with_invalid_limit
69
+ message = %{`order' attribute of `each' tag must be set to either "asc" or "desc"}
70
+ assert_parse_output_match message, page_children_each_tags(%{order="asdf"})
71
+ end
72
+ def test_tag_children_each_does_not_list_virtual_pages
73
+ setup_for_page(:archive)
74
+ assert_parse_output 'article article-2 article-3 article-4 article-5 ', '<r:children:each><r:slug /> </r:children:each>'
75
+ assert_parse_output_match /^(draft |)article article-2 article-3 article-4 article-5( draft|) $/, '<r:children:each status="all"><r:slug /> </r:children:each>'
76
+ end
77
+
78
+ def test_tag_children_each_header
79
+ setup_for_page(:archive)
80
+ assert_parse_output '[May/00] article [Jun/00] article-2 article-3 [Aug/00] article-4 [Aug/01] article-5 ', '<r:children:each><r:header>[<r:date format="%b/%y" />] </r:header><r:slug /> </r:children:each>'
81
+ end
82
+ def test_tag_children_each_header_with_name_attribute
83
+ setup_for_page(:archive)
84
+ assert_parse_output '[2000] (May) article (Jun) article-2 article-3 (Aug) article-4 [2001] article-5 ', %{<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>}
85
+ end
86
+ def test_tag_children_each_header_with_restart_attribute
87
+ setup_for_page(:archive)
88
+ assert_parse_output(
89
+ '[2000] (May) article (Jun) article-2 article-3 (Aug) article-4 [2001] (Aug) article-5 ',
90
+ %{<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>}
91
+ )
92
+ assert_parse_output(
93
+ '[2000] (May) <01> article (Jun) <09> article-2 <10> article-3 (Aug) <06> article-4 [2001] (Aug) <06> article-5 ',
94
+ %{<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>}
95
+ )
96
+ end
97
+
98
+ def test_tag_children_count
99
+ assert_parse_output '3', '<r:children:count />'
100
+ end
101
+
102
+ def test_tag_children_first
103
+ assert_parse_output 'Radius Test Child 1', '<r:children:first:title />'
104
+ end
105
+ def test_tag_children_first_is_nil
106
+ setup_for_page(:textile)
107
+ assert_parse_output '', '<r:children:first:title />'
108
+ end
109
+
110
+ def test_tag_children_last
111
+ assert_parse_output 'Radius Test Child 3', '<r:children:last:title />'
112
+ end
113
+ def test_tag_children_last_nil
114
+ setup_for_page(:textile)
115
+ assert_parse_output '', '<r:children:last:title />'
116
+ end
117
+
118
+ def test_tag_content
119
+ expected = "<h1>Radius Test Page</h1>\n\n\n\t<ul>\n\t<li>Radius Test Child 1</li>\n\t\t<li>Radius Test Child 2</li>\n\t\t<li>Radius Test Child 3</li>\n\t</ul>"
120
+ assert_parse_output expected, '<r:content />'
121
+ end
122
+ def test_tag_content_with_part_attribute
123
+ assert_parse_output "Just a test.\n", '<r:content part="extended" />'
124
+ end
125
+ def test_tag_content_with_inherit_attribute
126
+ assert_parse_output '', '<r:content part="sidebar" />'
127
+ assert_parse_output '', '<r:content part="sidebar" inherit="false" />'
128
+ assert_parse_output 'Radius Test Page sidebar.', '<r:content part="sidebar" inherit="true" />'
129
+ assert_parse_output_match %{`inherit' attribute of `content' tag must be set to either "true" or "false"}, '<r:content part="sidebar" inherit="weird value" />'
130
+ end
131
+ def test_tag_content_with_inherit_and_contextual_attributes
132
+ assert_parse_output 'Radius Test Page sidebar.', '<r:content part="sidebar" inherit="true" contextual="true" />'
133
+ assert_parse_output 'Ruby Home Page sidebar.', '<r:content part="sidebar" inherit="true" contextual="false" />'
134
+
135
+ setup_for_page(:inheritance_test_page_grandchild)
136
+ assert_parse_output 'Inheritance Test Page Grandchild inherited body.', '<r:content part="body" inherit="true" contextual="true" />'
137
+ end
138
+
139
+ def test_tag_child_content
140
+ expected = "Radius test child 1 body.\nRadius test child 2 body.\nRadius test child 3 body.\n"
141
+ assert_parse_output expected, '<r:children:each><r:content /></r:children:each>'
142
+ end
143
+
144
+ def test_tag_if_content_without_body_attribute
145
+ assert_parse_output 'true', '<r:if_content>true</r:if_content>'
146
+ end
147
+ def test_tag_if_content_with_body_attribute
148
+ assert_parse_output 'true', '<r:if_content part="body">true</r:if_content>'
149
+ end
150
+ def test_tag_if_content_with_nonexistant_body_attribute
151
+ assert_parse_output '', '<r:if_content part="asdf">true</r:if_content>'
152
+ end
153
+
154
+ def test_tag_unless_content_without_body_attribute
155
+ assert_parse_output '', '<r:unless_content>false</r:unless_content>'
156
+ end
157
+ def test_tag_unless_content_with_body_attribute
158
+ assert_parse_output '', '<r:unless_content part="body">false</r:unless_content>'
159
+ end
160
+ def test_tag_unless_content_with_nonexistant_body_attribute
161
+ assert_parse_output 'false', '<r:unless_content part="asdf">false</r:unless_content>'
162
+ end
163
+
164
+ def test_tag_author
165
+ assert_parse_output 'Admin User', '<r:author />'
166
+ end
167
+ def test_tag_author_nil
168
+ setup_for_page(:textile)
169
+ assert_parse_output '', '<r:author />'
170
+ end
171
+
172
+ def test_tag_date
173
+ assert_parse_output 'Monday, January 30, 2006', '<r:date />'
174
+ end
175
+ def test_tag_date_with_format_attribute
176
+ assert_parse_output '30 Jan 2006', '<r:date format="%d %b %Y" />'
177
+ end
178
+
179
+ def test_tag_link
180
+ assert_parse_output '<a href="/radius/">Radius Test Page</a>', '<r:link />'
181
+ end
182
+ def test_tag_link__attributes
183
+ expected = '<a href="/radius/" class="test" id="radius">Radius Test Page</a>'
184
+ assert_parse_output expected, '<r:link class="test" id="radius" />'
185
+ end
186
+ def test_tag_link__block_form
187
+ assert_parse_output '<a href="/radius/">Test</a>', '<r:link>Test</r:link>'
188
+ end
189
+ def test_tag_link__anchor
190
+ assert_parse_output '<a href="/radius/#test">Test</a>', '<r:link anchor="test">Test</r:link>'
191
+ end
192
+ def test_tag_child_link
193
+ expected = "<a href=\"/radius/child-1/\">Radius Test Child 1</a> <a href=\"/radius/child-2/\">Radius Test Child 2</a> <a href=\"/radius/child-3/\">Radius Test Child 3</a> "
194
+ assert_parse_output expected, '<r:children:each><r:link /> </r:children:each>'
195
+ end
196
+
197
+ def test_tag_snippet
198
+ assert_parse_output 'test', '<r:snippet name="first" />'
199
+ end
200
+ def test_tag_snippet_not_found
201
+ assert_parse_output_match 'snippet not found', '<r:snippet name="non-existant" />'
202
+ end
203
+ def test_tag_snippet_without_name
204
+ assert_parse_output_match "`snippet' tag must contain `name' attribute", '<r:snippet />'
205
+ end
206
+ def test_tag_snippet_with_markdown
207
+ assert_parse_output '<p><strong>markdown</strong></p>', '<r:page><r:snippet name="markdown" /></r:page>'
208
+ end
209
+
210
+ def test_tag_random
211
+ assert_parse_output_match /^(1|2|3)$/, "<r:random> <r:option>1</r:option> <r:option>2</r:option> <r:option>3</r:option> </r:random>"
212
+ end
213
+
214
+ def test_tag_comment
215
+ assert_parse_output 'just a test', 'just a <r:comment>small </r:comment>test'
216
+ end
217
+
218
+ def test_tag_navigation_1
219
+ tags = %{<r:navigation urls="Home: Boy: /; Archives: /archive/; Radius: /radius/; Docs: /documentation/">
220
+ <r:normal><a href="<r:url />"><r:title /></a></r:normal>
221
+ <r:here><strong><r:title /></strong></r:here>
222
+ <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected>
223
+ <r:between> | </r:between>
224
+ </r:navigation>}
225
+ expected = %{<strong><a href="/">Home: Boy</a></strong> | <a href="/archive/">Archives</a> | <strong>Radius</strong> | <a href="/documentation/">Docs</a>}
226
+ assert_parse_output expected, tags
227
+ end
228
+ def test_tag_navigation_2
229
+ tags = %{<r:navigation urls="Home: /; Archives: /archive/; Radius: /radius/; Docs: /documentation/">
230
+ <r:normal><r:title /></r:normal>
231
+ </r:navigation>}
232
+ expected = %{Home Archives Radius Docs}
233
+ assert_parse_output expected, tags
234
+ end
235
+ def test_tag_navigation_3
236
+ tags = %{<r:navigation urls="Home: /; Archives: /archive/; Radius: /radius/; Docs: /documentation/">
237
+ <r:normal><r:title /></r:normal>
238
+ <r:selected><strong><r:title/></strong></r:selected>
239
+ </r:navigation>}
240
+ expected = %{<strong>Home</strong> Archives <strong>Radius</strong> Docs}
241
+ assert_parse_output expected, tags
242
+ end
243
+ def test_tag_navigation_without_urls
244
+ assert_parse_output '', %{<r:navigation></r:navigation>}
245
+ end
246
+ def test_tag_navigation_without_urls
247
+ assert_parse_output_match "`navigation' tag must include a `normal' tag", %{<r:navigation urls="something:here"></r:navigation>}
248
+ end
249
+ def test_tag_navigation_with_urls_without_slashes
250
+ tags = %{<r:navigation urls="Home: ; Archives: /archive; Radius: /radius; Docs: /documentation">
251
+ <r:normal><r:title /></r:normal>
252
+ <r:here><strong><r:title /></strong></r:here>
253
+ </r:navigation>}
254
+ expected = %{Home Archives <strong>Radius</strong> Docs}
255
+ assert_parse_output expected, tags
256
+ end
257
+
258
+ def test_tag_find
259
+ assert_parse_output 'Ruby Home Page', %{<r:find url="/"><r:title /></r:find>}
260
+ end
261
+ def test_tag_find_without_url
262
+ assert_parse_output_match "`find' tag must contain `url' attribute", %{<r:find />}
263
+ end
264
+ def test_tag_find_with_nonexistant_url
265
+ assert_parse_output '', %{<r:find url="/asdfsdf/"><r:title /></r:find>}
266
+ end
267
+
268
+ def test_tag_find_and_children
269
+ assert_parse_output 'a-great-day-for-ruby another-great-day-for-ruby ', %{<r:find url="/news/"><r:children:each><r:slug /> </r:children:each></r:find>}
270
+ end
271
+
272
+ def test_tag_escape_html
273
+ assert_parse_output '&lt;strong&gt;a bold move&lt;/strong&gt;', '<r:escape_html><strong>a bold move</strong></r:escape_html>'
274
+ end
275
+
276
+ def test_tag_rfc1123_date
277
+ @page.published_at = Time.utc(2004, 5, 2)
278
+ assert_parse_output 'Sun, 02 May 2004 00:00:00 GMT', '<r:rfc1123_date />'
279
+ end
280
+
281
+ def test_tag_breadcrumbs
282
+ setup_for_page(:deep_nested_child_for_breadcrumbs)
283
+ assert_parse_output '<a href="/">Home</a> &gt; <a href="/radius/">Radius Test Page</a> &gt; <a href="/radius/child-1/">Radius Test Child 1</a> &gt; Deeply nested child',
284
+ '<r:breadcrumbs />'
285
+ end
286
+
287
+ def test_tag_breadcrumbs_with_separator_attribute
288
+ setup_for_page(:deep_nested_child_for_breadcrumbs)
289
+ assert_parse_output '<a href="/">Home</a> :: <a href="/radius/">Radius Test Page</a> :: <a href="/radius/child-1/">Radius Test Child 1</a> :: Deeply nested child',
290
+ '<r:breadcrumbs separator=" :: " />'
291
+ end
292
+
293
+ def test_tag_if_url_does_not_match
294
+ assert_parse_output '', '<r:if_url matches="fancypants">true</r:if_url>'
295
+ end
296
+
297
+ def test_tag_if_url_matches
298
+ assert_parse_output 'true', '<r:if_url matches="r.dius/$">true</r:if_url>'
299
+ end
300
+
301
+ def test_tag_if_url_without_ignore_case
302
+ assert_parse_output 'true', '<r:if_url matches="rAdius/$">true</r:if_url>'
303
+ end
304
+
305
+ def test_tag_if_url_with_ignore_case_true
306
+ assert_parse_output 'true', '<r:if_url matches="rAdius/$" ignore_case="true">true</r:if_url>'
307
+ end
308
+
309
+ def test_tag_if_url_with_ignore_case_false
310
+ assert_parse_output '', '<r:if_url matches="rAdius/$" ignore_case="false">true</r:if_url>'
311
+ end
312
+
313
+ def test_tag_if_url_with_malformatted_regexp
314
+ assert_parse_output_match "Malformed regular expression in `matches' argument of `if_url' tag:", '<r:if_url matches="r(dius/$">true</r:if_url>'
315
+ end
316
+
317
+ def test_tag_if_url_empty
318
+ assert_parse_output_match "`if_url' tag must contain a `matches' attribute", '<r:if_url>test</r:if_url>'
319
+ end
320
+
321
+ def test_tag_unless_url_does_not_match
322
+ assert_parse_output 'true', '<r:unless_url matches="fancypants">true</r:unless_url>'
323
+ end
324
+
325
+ def test_tag_unless_url_matches
326
+ assert_parse_output '', '<r:unless_url matches="r.dius/$">true</r:unless_url>'
327
+ end
328
+
329
+ def test_tag_unless_url_without_ignore_case
330
+ assert_parse_output '', '<r:unless_url matches="rAdius/$">true</r:unless_url>'
331
+ end
332
+
333
+ def test_tag_unless_url_with_ignore_case_true
334
+ assert_parse_output '', '<r:unless_url matches="rAdius/$" ignore_case="true">true</r:unless_url>'
335
+ end
336
+
337
+ def test_tag_unless_url_with_ignore_case_false
338
+ assert_parse_output 'true', '<r:unless_url matches="rAdius/$" ignore_case="false">true</r:unless_url>'
339
+ end
340
+
341
+ def test_tag_unless_url_with_malformatted_regexp
342
+ assert_parse_output_match "Malformed regular expression in `matches' argument of `unless_url' tag:", '<r:unless_url matches="r(dius/$">true</r:unless_url>'
343
+ end
344
+
345
+ def test_tag_unless_url_empty
346
+ assert_parse_output_match "`unless_url' tag must contain a `matches' attribute", '<r:unless_url>test</r:unless_url>'
347
+ end
348
+
349
+ def test_tag_missing
350
+ assert_parse_output_match "undefined tag `missing'", '<r:missing />'
351
+ end
352
+
353
+ protected
354
+
355
+ def setup_for_page(page)
356
+ @page = pages(page)
357
+ @context = PageContext.new(@page)
358
+ @parser = Radius::Parser.new(@context, :tag_prefix => 'r')
359
+ end
360
+
361
+ def page_children_each_tags(attr = nil)
362
+ attr = ' ' + attr unless attr.nil?
363
+ "<r:children:each#{attr}><r:slug /> </r:children:each>"
364
+ end
365
+
366
+ def assert_parse_output(expected, input)
367
+ output = @parser.parse(input)
368
+ assert_equal expected, output
369
+ end
370
+
371
+ def assert_parse_output_match(regexp, input)
372
+ output = @parser.parse(input)
373
+ assert_match regexp, output
374
+ end
375
+ end