comatose-rubyisbeautiful 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. data/CHANGELOG +198 -0
  2. data/Gemfile +29 -0
  3. data/Gemfile.lock +130 -0
  4. data/INSTALL +14 -0
  5. data/LICENSE +20 -0
  6. data/Manifest +188 -0
  7. data/README +0 -0
  8. data/README.markdown +113 -0
  9. data/Rakefile +5 -0
  10. data/SPECS +61 -0
  11. data/app/controllers/application_controller.rb +3 -0
  12. data/app/controllers/comatose/admin_controller.rb +425 -0
  13. data/app/controllers/comatose/application_controller.rb +30 -0
  14. data/app/controllers/comatose/base_controller.rb +167 -0
  15. data/app/helpers/application_helper.rb +2 -0
  16. data/app/helpers/comatose/admin_helper.rb +78 -0
  17. data/app/helpers/comatose/application_helper.rb +2 -0
  18. data/app/helpers/comatose/base_helper.rb +5 -0
  19. data/app/models/comatose/page.rb +166 -0
  20. data/app/views/comatose/admin/_form.html.erb +108 -0
  21. data/app/views/comatose/admin/_page_list_item.html.erb +62 -0
  22. data/app/views/comatose/admin/delete.html.erb +18 -0
  23. data/app/views/comatose/admin/edit.html.erb +5 -0
  24. data/app/views/comatose/admin/index.html.erb +34 -0
  25. data/app/views/comatose/admin/new.html.erb +5 -0
  26. data/app/views/comatose/admin/reorder.html.erb +30 -0
  27. data/app/views/comatose/admin/versions.html.erb +40 -0
  28. data/app/views/layouts/application.html.erb +14 -0
  29. data/app/views/layouts/comatose/admin.html.erb +44 -0
  30. data/app/views/layouts/comatose/base.html.erb +14 -0
  31. data/comatose-rubyisbeautiful.gemspec +65 -0
  32. data/config/environment.rb +5 -0
  33. data/config/environments/development.rb +26 -0
  34. data/config/environments/production.rb +49 -0
  35. data/config/environments/test.rb +35 -0
  36. data/config/locales/en.yml +5 -0
  37. data/config.ru +4 -0
  38. data/db/seeds.rb +11 -0
  39. data/lib/comatose/configuration.rb +87 -0
  40. data/lib/comatose/drop.rb +45 -0
  41. data/lib/comatose/engine.rb +28 -0
  42. data/lib/comatose/filters/inline_filter.rb +15 -0
  43. data/lib/comatose/filters/timeago_filter.rb +14 -0
  44. data/lib/comatose/filters/translation_filter.rb +11 -0
  45. data/lib/comatose/locale_constraint.rb +15 -0
  46. data/lib/comatose/logger.rb +10 -0
  47. data/lib/comatose/page_wrapper.rb +147 -0
  48. data/lib/comatose/processing_context.rb +103 -0
  49. data/lib/comatose/routes.rb +70 -0
  50. data/lib/comatose/tasks/admin.rb +57 -0
  51. data/lib/comatose/tasks/data.rb +79 -0
  52. data/lib/comatose/tasks/setup.rb +118 -0
  53. data/lib/comatose/text_filters.rb +148 -0
  54. data/lib/comatose/version.rb +9 -0
  55. data/lib/comatose.rb +88 -0
  56. data/lib/generators/comatose/USAGE +7 -0
  57. data/lib/generators/comatose/comatose_generator.rb +37 -0
  58. data/lib/generators/comatose/templates/comatose.rb +33 -0
  59. data/lib/generators/comatose/templates/migration.erb +32 -0
  60. data/lib/generators/comatose/templates/seeds.erb +2 -0
  61. data/lib/support/class_options.rb +36 -0
  62. data/lib/support/inline_rendering.rb +48 -0
  63. data/lib/support/route_mapper.rb +51 -0
  64. data/lib/tasks/comatose.rake +9 -0
  65. data/lib/text_filters/markdown.rb +14 -0
  66. data/lib/text_filters/markdown_smartypants.rb +15 -0
  67. data/lib/text_filters/none.rb +8 -0
  68. data/lib/text_filters/rdoc.rb +13 -0
  69. data/lib/text_filters/simple.rb +8 -0
  70. data/lib/text_filters/textile.rb +15 -0
  71. data/public/404.html +26 -0
  72. data/public/422.html +26 -0
  73. data/public/500.html +26 -0
  74. data/public/favicon.ico +0 -0
  75. data/public/images/comatose/collapsed.gif +0 -0
  76. data/public/images/comatose/expanded.gif +0 -0
  77. data/public/images/comatose/no-children.gif +0 -0
  78. data/public/images/comatose/page.gif +0 -0
  79. data/public/images/comatose/rails.png +0 -0
  80. data/public/images/comatose/spinner.gif +0 -0
  81. data/public/images/comatose/title-hover-bg.gif +0 -0
  82. data/public/javascripts/comatose/admin.js +406 -0
  83. data/public/javascripts/comatose/application.js +2 -0
  84. data/public/javascripts/comatose/dragdrop.js +974 -0
  85. data/public/javascripts/editor.js +452 -0
  86. data/public/javascripts/jquery/GPL-LICENSE.txt +278 -0
  87. data/public/javascripts/jquery/MIT-LICENSE.txt +20 -0
  88. data/public/javascripts/jquery/README +67 -0
  89. data/public/javascripts/jquery/jquery.js +11 -0
  90. data/public/javascripts/jquery/jquery.ui.draggable.js +1 -0
  91. data/public/javascripts/jquery/jquery.ui.js +1 -0
  92. data/public/javascripts/jquery/jquery.ui.resizable.js +1 -0
  93. data/public/javascripts/jquery/jquery.ui.sortable.js +1 -0
  94. data/public/javascripts/wymeditor/iframe/default/lbl-blockquote.png +0 -0
  95. data/public/javascripts/wymeditor/iframe/default/lbl-h1.png +0 -0
  96. data/public/javascripts/wymeditor/iframe/default/lbl-h2.png +0 -0
  97. data/public/javascripts/wymeditor/iframe/default/lbl-h3.png +0 -0
  98. data/public/javascripts/wymeditor/iframe/default/lbl-h4.png +0 -0
  99. data/public/javascripts/wymeditor/iframe/default/lbl-h5.png +0 -0
  100. data/public/javascripts/wymeditor/iframe/default/lbl-h6.png +0 -0
  101. data/public/javascripts/wymeditor/iframe/default/lbl-p.png +0 -0
  102. data/public/javascripts/wymeditor/iframe/default/lbl-pre.png +0 -0
  103. data/public/javascripts/wymeditor/iframe/default/wymiframe.css +90 -0
  104. data/public/javascripts/wymeditor/iframe/default/wymiframe.html +26 -0
  105. data/public/javascripts/wymeditor/jquery.wymeditor.js +4688 -0
  106. data/public/javascripts/wymeditor/jquery.wymeditor.min.js +1 -0
  107. data/public/javascripts/wymeditor/jquery.wymeditor.pack.js +1 -0
  108. data/public/javascripts/wymeditor/lang/bg.js +45 -0
  109. data/public/javascripts/wymeditor/lang/ca.js +45 -0
  110. data/public/javascripts/wymeditor/lang/cs.js +45 -0
  111. data/public/javascripts/wymeditor/lang/cy.js +45 -0
  112. data/public/javascripts/wymeditor/lang/de.js +45 -0
  113. data/public/javascripts/wymeditor/lang/en.js +45 -0
  114. data/public/javascripts/wymeditor/lang/es.js +45 -0
  115. data/public/javascripts/wymeditor/lang/fa.js +46 -0
  116. data/public/javascripts/wymeditor/lang/fi.js +44 -0
  117. data/public/javascripts/wymeditor/lang/fr.js +45 -0
  118. data/public/javascripts/wymeditor/lang/gl.js +45 -0
  119. data/public/javascripts/wymeditor/lang/he.js +45 -0
  120. data/public/javascripts/wymeditor/lang/hr.js +45 -0
  121. data/public/javascripts/wymeditor/lang/hu.js +45 -0
  122. data/public/javascripts/wymeditor/lang/it.js +45 -0
  123. data/public/javascripts/wymeditor/lang/nb.js +45 -0
  124. data/public/javascripts/wymeditor/lang/nl.js +45 -0
  125. data/public/javascripts/wymeditor/lang/nn.js +45 -0
  126. data/public/javascripts/wymeditor/lang/pl.js +45 -0
  127. data/public/javascripts/wymeditor/lang/pt-br.js +45 -0
  128. data/public/javascripts/wymeditor/lang/pt.js +45 -0
  129. data/public/javascripts/wymeditor/lang/ru.js +45 -0
  130. data/public/javascripts/wymeditor/lang/sv.js +45 -0
  131. data/public/javascripts/wymeditor/lang/tr.js +45 -0
  132. data/public/javascripts/wymeditor/lang/zh_cn.js +47 -0
  133. data/public/javascripts/wymeditor/plugins/embed/jquery.wymeditor.embed.js +52 -0
  134. data/public/javascripts/wymeditor/plugins/fullscreen/icon_fullscreen.gif +0 -0
  135. data/public/javascripts/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js +127 -0
  136. data/public/javascripts/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js +57 -0
  137. data/public/javascripts/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js +91 -0
  138. data/public/javascripts/wymeditor/plugins/resizable/readme.txt +124 -0
  139. data/public/javascripts/wymeditor/plugins/tidy/README +19 -0
  140. data/public/javascripts/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js +82 -0
  141. data/public/javascripts/wymeditor/plugins/tidy/tidy.php +36 -0
  142. data/public/javascripts/wymeditor/plugins/tidy/wand.png +0 -0
  143. data/public/javascripts/wymeditor/skins/compact/icons.png +0 -0
  144. data/public/javascripts/wymeditor/skins/compact/skin.css +134 -0
  145. data/public/javascripts/wymeditor/skins/compact/skin.js +35 -0
  146. data/public/javascripts/wymeditor/skins/default/icons.png +0 -0
  147. data/public/javascripts/wymeditor/skins/default/skin.css +133 -0
  148. data/public/javascripts/wymeditor/skins/default/skin.js +40 -0
  149. data/public/javascripts/wymeditor/skins/minimal/images/bg.header.gif +0 -0
  150. data/public/javascripts/wymeditor/skins/minimal/images/bg.selector.silver.gif +0 -0
  151. data/public/javascripts/wymeditor/skins/minimal/images/bg.wymeditor.png +0 -0
  152. data/public/javascripts/wymeditor/skins/minimal/images/icons.silver.gif +0 -0
  153. data/public/javascripts/wymeditor/skins/minimal/skin.css +131 -0
  154. data/public/javascripts/wymeditor/skins/minimal/skin.js +30 -0
  155. data/public/javascripts/wymeditor/skins/silver/COPYING +674 -0
  156. data/public/javascripts/wymeditor/skins/silver/README +27 -0
  157. data/public/javascripts/wymeditor/skins/silver/images/bg.header.gif +0 -0
  158. data/public/javascripts/wymeditor/skins/silver/images/bg.selector.silver.gif +0 -0
  159. data/public/javascripts/wymeditor/skins/silver/images/bg.wymeditor.png +0 -0
  160. data/public/javascripts/wymeditor/skins/silver/images/icons.silver.gif +0 -0
  161. data/public/javascripts/wymeditor/skins/silver/skin.css +297 -0
  162. data/public/javascripts/wymeditor/skins/silver/skin.js +61 -0
  163. data/public/javascripts/wymeditor/skins/twopanels/icons.png +0 -0
  164. data/public/javascripts/wymeditor/skins/twopanels/skin.css +134 -0
  165. data/public/javascripts/wymeditor/skins/twopanels/skin.js +39 -0
  166. data/public/javascripts/wymeditor/skins/wymeditor_icon.png +0 -0
  167. data/public/javascripts/wymeditor.tar +0 -0
  168. data/public/robots.txt +5 -0
  169. data/public/stylesheets/comatose/admin.css +488 -0
  170. data/public/stylesheets/comatose/base.css +9 -0
  171. data/spec/controllers/comatose/base_controller_spec.rb +14 -0
  172. data/spec/controllers/foos_controller_spec.rb +5 -0
  173. data/spec/helpers/foos_helper_spec.rb +15 -0
  174. data/spec/routing/base_routing_spec.rb +12 -0
  175. data/spec/spec_helper.rb +27 -0
  176. data/test/behaviors.rb +106 -0
  177. data/test/fixtures/comatose_pages.yml +96 -0
  178. data/test/functional/comatose_admin_controller_test.rb +114 -0
  179. data/test/functional/comatose_controller_test.rb +45 -0
  180. data/test/integration/comatose_routing_test.rb +17 -0
  181. data/test/javascripts/test.html +26 -0
  182. data/test/javascripts/test_runner.js +307 -0
  183. data/test/old_test_helper.rb +43 -0
  184. data/test/performance/browsing_test.rb +9 -0
  185. data/test/test_helper.rb +13 -0
  186. data/test/unit/class_options_test.rb +52 -0
  187. data/test/unit/comatose_page_test.rb +128 -0
  188. data/test/unit/processing_context_test.rb +108 -0
  189. data/test/unit/text_filters_test.rb +52 -0
  190. data.tar.gz.sig +1 -0
  191. metadata +379 -0
  192. metadata.gz.sig +0 -0
@@ -0,0 +1,96 @@
1
+ # Page attributes
2
+ # - parent_id
3
+ # - title
4
+ # - full_path
5
+ # - slug
6
+ # - keywords
7
+ # - body
8
+ # - author
9
+ # - filter_type
10
+ # - position
11
+ # - version
12
+ # - updated_at
13
+ # - created_at
14
+
15
+ root:
16
+ id: 1
17
+ parent_id:
18
+ full_path: ""
19
+ slug: home-page
20
+ title: Home Page
21
+ body: |-
22
+ h1. {{ page.title }}
23
+
24
+ This is your *home page*.
25
+ author: Comatose
26
+ keywords: "test, cms"
27
+ filter_type: Textile
28
+ position: 0
29
+ created_at: <%= 10.days.ago.to_s :db %>
30
+ updated_at: <%= 10.days.ago.to_s :db %>
31
+
32
+ faq:
33
+ id: 2
34
+ parent_id: 1
35
+ full_path: "faq"
36
+ slug: faq
37
+ title: Frequently Asked Questions
38
+ body: |-
39
+ h1. {{ page.title }}
40
+ {% for c in page.children %}
41
+ h2. {{ c.link }}
42
+
43
+ {{ c.to_html }}
44
+
45
+ {% endfor %}
46
+ created_at: <%= 10.days.ago.to_s :db %>
47
+ updated_at: <%= 10.days.ago.to_s :db %>
48
+ author: Comatose
49
+ keywords: faq
50
+ filter_type: Textile
51
+ position: 0
52
+
53
+ question_one:
54
+ id: 3
55
+ parent_id: 2
56
+ full_path: "faq/question-one"
57
+ slug: question-one
58
+ title: Question One?
59
+ body: |-
60
+ Content for *question one*.
61
+ created_at: <%= 10.days.ago.to_s :db %>
62
+ updated_at: <%= 10.days.ago.to_s :db %>
63
+ author: Comatose
64
+ keywords: faq
65
+ filter_type: Textile
66
+ position: 0
67
+
68
+ question_two:
69
+ id: 4
70
+ parent_id: 2
71
+ full_path: "faq/question-two"
72
+ slug: question-two
73
+ title: Question Two?
74
+ body: |-
75
+ Content for *question two*.
76
+ created_at: <%= 10.days.ago.to_s :db %>
77
+ updated_at: <%= 10.days.ago.to_s :db %>
78
+ author: Comatose
79
+ keywords: faq
80
+ filter_type: Textile
81
+ position: 1
82
+
83
+ param_driven:
84
+ id: 5
85
+ parent_id: 1
86
+ full_path: "params"
87
+ slug: params
88
+ title: Params
89
+ body: |-
90
+ I'm {{ extra }}
91
+ created_at: <%= 10.days.ago.to_s :db %>
92
+ updated_at: <%= 10.days.ago.to_s :db %>
93
+ author: Comatose
94
+ keywords:
95
+ filter_type: Textile
96
+ position: 0
@@ -0,0 +1,114 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'comatose_admin_controller'
3
+ require 'comatose_admin_helper'
4
+ require 'text_filters'
5
+
6
+ # Re-raise errors caught by the controller.
7
+ class AdminController
8
+ def rescue_action(e) raise e end
9
+ end
10
+
11
+ class ComatoseAdminControllerTest < Test::Unit::TestCase
12
+
13
+ fixtures :comatose_pages
14
+
15
+ def setup
16
+ @controller = AdminController.new
17
+ @request = ActionController::TestRequest.new
18
+ @response = ActionController::TestResponse.new
19
+ Comatose.config.admin_get_author = nil
20
+ Comatose.config.admin_authorization = nil
21
+ end
22
+
23
+ should "show the index action" do
24
+ get :index
25
+ assert_response :success
26
+ assert assigns(:root_pages)
27
+ end
28
+
29
+ should "show the new action" do
30
+ get :new
31
+ assert_response :success
32
+ assert assigns(:page)
33
+ end
34
+
35
+ should "successfully create pages" do
36
+ post :new, :page=>{:title=>"Test page", :body=>'This is a *test*', :parent_id=>1, :filter_type=>'Textile'}
37
+ assert_response :redirect
38
+ assert_redirected_to :controller=>'comatose_admin', :action=>'index'
39
+ end
40
+
41
+ should "create a page with an empty body" do
42
+ post :new, :page=>{:title=>"Test page", :body=>nil, :parent_id=>1, :filter_type=>'Textile'}
43
+ assert_response :redirect
44
+ assert_redirected_to :controller=>'comatose_admin', :action=>'index'
45
+ end
46
+
47
+ should "not create a page with a missing title" do
48
+ post :new, :page=>{:title=>nil, :body=>'This is a *test*', :parent_id=>1, :filter_type=>'Textile'}
49
+ assert_response :success
50
+ assert assigns.has_key?('page'), "Page assignment"
51
+ assert (assigns['page'].errors.length > 0), "Page errors"
52
+ assert_equal 'must be present', assigns['page'].errors.on('title')
53
+ end
54
+
55
+ should "not create a page associated to an invalid parent" do
56
+ post :new, :page=>{:title=>'Test page', :body=>'This is a *test*', :parent_id=>nil, :filter_type=>'Textile'}
57
+ assert_response :success
58
+ assert assigns.has_key?('page'), "Page assignment"
59
+ assert (assigns['page'].errors.length > 0), "Page errors"
60
+ assert_equal 'must be present', assigns['page'].errors.on('parent_id')
61
+ end
62
+
63
+ should "contain all the correct options for filter_type" do
64
+ get :new
65
+ assert_response :success
66
+ assert_select 'SELECT[id=page_filter_type]>*', :count=>TextFilters.all_titles.length
67
+ end
68
+
69
+ should "show the edit action" do
70
+ get :edit, :id=>1
71
+ assert_response :success
72
+ end
73
+
74
+ should "update pages with valid data" do
75
+ post :edit, :id=>1, :page=>{ :title=>'A new title' }
76
+ assert_response :redirect
77
+ assert_redirected_to :action=>"index"
78
+ end
79
+
80
+ should "not update pages with invalid data" do
81
+ post :edit, :id=>1, :page=>{ :title=>nil }
82
+ assert_response :success
83
+ assert_equal 'must be present', assigns['page'].errors.on('title')
84
+ end
85
+
86
+ should "delete a page" do
87
+ post :delete, :id=>1
88
+ assert_response :redirect
89
+ assert_redirected_to :action=>"index"
90
+ end
91
+
92
+ should "reorder pages" do
93
+ q1 = comatose_page :question_one
94
+ assert_not_nil q1
95
+ assert_difference q1, :position do
96
+ post :reorder, :id=>q1.parent.id, :page=>q1.id, :cmd=>'down'
97
+ assert_response :redirect
98
+ assert_redirected_to :action=>"reorder"
99
+ q1.reload
100
+ end
101
+ end
102
+
103
+ should "set runtime mode" do
104
+ assert_equal :plugin, AdminController.runtime_mode
105
+ comatose_admin_view_path = File.expand_path(File.join( File.dirname(__FILE__), '..', '..', 'views'))
106
+
107
+ if AdminController.respond_to?(:template_root)
108
+ assert_equal comatose_admin_view_path, AdminController.template_root
109
+ else
110
+ assert AdminController.view_paths.include?(comatose_admin_view_path)
111
+ end
112
+ end
113
+
114
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'comatose_controller'
3
+ require 'comatose_helper'
4
+
5
+ # Re-raise errors caught by the controller.
6
+ class ComatoseController
7
+ def rescue_action(e) raise e end
8
+ end
9
+
10
+
11
+ class ComatoseControllerTest < Test::Unit::TestCase
12
+
13
+ fixtures :comatose_pages
14
+
15
+ def setup
16
+ @controller = ComatoseController.new
17
+ @request = ActionController::TestRequest.new
18
+ @response = ActionController::TestResponse.new
19
+ end
20
+
21
+
22
+ def test_truth
23
+ assert true
24
+ end
25
+
26
+ should "show pages based on path_info" do
27
+
28
+ # Get the faq page...
29
+ get :show, :page=>'faq', :index=>'', :layout=>'base.html.erb', :use_cache=>'false'
30
+ assert_response :success
31
+ assert_tag :tag=>'h1', :child=>/Frequently Asked Questions/
32
+
33
+ # Get a question page using rails 2.0 array style...
34
+ get :show, :page=>['faq','question-one'], :index=>'', :layout=>'base.html.erb', :use_cache=>'false'
35
+ assert_response :success
36
+ assert_tag :tag=>'title', :child=>/Question/
37
+
38
+ # Get a question page using rails 1.x path style...
39
+ get :show, :page=>ActionController::Routing::PathSegment::Result.new_escaped(['faq','question-one']),
40
+ :index=>'', :layout=>'base.html.erb', :use_cache=>'false'
41
+ assert_response :success
42
+ assert_tag :tag=>'title', :child=>/Question/
43
+ end
44
+
45
+ end
@@ -0,0 +1,17 @@
1
+ require 'test_helper'
2
+ require 'action_dispatch/testing/assertions/routing'
3
+ require 'comatose/base_controller'
4
+ require 'comatose/base_helper'
5
+
6
+ # Re-raise errors caught by the controller.
7
+ class Comatose::BaseController
8
+ def rescue_action(e) raise e end
9
+ end
10
+
11
+ class ComatoseRoutingTest < Test::Unit::TestCase
12
+ include ActionDispatch::Assertions::RoutingAssertions
13
+ def test_route_works
14
+ opts = { :controller => "comatose/base" }
15
+ assert_routing "/en", opts
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ <html>
2
+ <!-- Required Scripts -->
3
+ <script src="../../../../../public/javascripts/prototype.js" type="text/javascript"></script>
4
+ <script src="../../../../../public/javascripts/effects.js" type="text/javascript"></script>
5
+ <script src="../../../../../public/javascripts/dragdrop.js" type="text/javascript"></script>
6
+ <script src="../../../../../public/javascripts/controls.js" type="text/javascript"></script>
7
+ <script src="../../public/javascripts/comatose/admin.js"></script>
8
+ <!-- Unit Tests -->
9
+
10
+ <script>
11
+ var Tests = {
12
+ title: "Comatose JS Tests",
13
+ // description: "Methods that start with testFail test that assertions fail property.",
14
+
15
+ test_String_toSlug: function() {
16
+ assertEqual( 'hello-how-are-you', 'Hello, How Are You?'.toSlug() );
17
+ assertEqual( 'i-have-too-much-space', 'I have too much space'.toSlug() );
18
+ assertEqual( 'what-about-dashes', 'What about - dashes?'.toSlug() );
19
+ assertEqual( 'a-bizarre-title', 'A !@!@#$%^&*()_+{} Bizarre TiTle!'.toSlug() );
20
+ assertEqual( '001-numbers-too', '001 Numbers too'.toSlug() );
21
+ }
22
+ }
23
+ </script>
24
+ <!-- UnitTestRunner -->
25
+ <script src="test_runner.js"></script>
26
+ </html>
@@ -0,0 +1,307 @@
1
+ /*
2
+ = Test Framework
3
+ version 1.0
4
+ created by M@ McCray (http://www.mattmccray.com)
5
+
6
+ This is a simple JavaScript test framework.
7
+
8
+ = TODO:
9
+
10
+ * Add support for calling Tests.setup() and Tests.teardown()
11
+ * Documentation!
12
+ * Add support for methods that don't start with 'test'?
13
+ * Make test method names more English?
14
+ */
15
+
16
+ // We're gonna run all this in it's own scope so it doesn't pollute the test namespace
17
+ (function(){
18
+ var HTML = {
19
+ _all_tags: ['a','abbr','acronym','address','area','b','base','bdo','big','blockquote','body','br','button','caption','cite','code','col','colgroup','dd','del','dfn','div','dl','DOCTYPE','dt','em','fieldset','form','h1','h2','h3','h4','h5','h6','head','html','hr','i','img','input','ins','kbd','label','legend','li','link','map','meta','noscript','object','ol','optgroup','option','p','param','pre','q','samp','script','select','small','span','strong','style','sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','ul'],
20
+ _init: function() {
21
+ for(var $i=0; $i<this._all_tags.length; $i++) {
22
+ var $tag = this._all_tags[$i]
23
+ eval( 'HTML.'+ $tag +' = function (){ return HTML._write_tag("'+ $tag +'", arguments); }' );
24
+ //this[$tag] = new Function("return HTML._write_tag('"+ $tag +"', arguments);")
25
+ this.namespace += ';var '+ $tag +' = HTML.'+ $tag;
26
+ }
27
+ },
28
+ _write_tag: function(tag, options) {
29
+ var $content = ''; var $atts = "";
30
+ for(var $i=0; $i<options.length; $i++) {
31
+ var $arg = options[$i];
32
+ if (typeof($arg) == 'string' || typeof($arg) == 'number')
33
+ $content += $arg.toString();
34
+ else if (typeof($arg) == 'function')
35
+ $content += $arg();
36
+ else if ( $arg instanceof Object)
37
+ for($prop in $arg) $atts += ' '+ $prop +'="'+ $arg[$prop] +'"';
38
+ }
39
+ if($content == '')
40
+ return '<'+ tag + $atts +'/>';
41
+ else
42
+ return '<'+ tag + $atts +'>'+ $content +'</'+ tag +'>';
43
+ },
44
+ namespace: 'var text = HTML.text',
45
+ toString: function() { return this.namespace; },
46
+ text: function() {
47
+ var $content='';
48
+ for(var $i=0; $i<arguments.length; $i++) $content += arguments[$i].toString();
49
+ return $content;
50
+ }
51
+ };
52
+ HTML._init();
53
+ eval(HTML.namespace);
54
+
55
+ var list_html = "";
56
+ var page_title = "Test Cases";
57
+ var page_desc = "";
58
+
59
+ window.methodList = [];
60
+ if( typeof(Tests) != 'undefined' ) {
61
+ if(Tests.title) page_title = Tests.title;
62
+ if(Tests.description) page_desc = Tests.description;
63
+
64
+ for(func in Tests) {
65
+ if(/test/.test(func)) {
66
+ methodList.push(func);
67
+ list_html += li ({id:func, 'class':'untested'},
68
+ span (func.toString()),
69
+ div (' ', {id: (func +'-error')})
70
+ )
71
+ }
72
+ }
73
+ } else {
74
+ list_html = li('No tests defined!', {'class':'fail'})
75
+ }
76
+
77
+ // Generate HTML
78
+
79
+ if( page_desc != '' ) page_desc = p( page_desc,{'class':'description'});
80
+
81
+ document.write(
82
+ head (
83
+ title ( "(", page_title, ")", " :: JavaScript Test Framework" ),
84
+ style (
85
+ "BODY { font-family:Helvetica,Verdana,Sans-Serif; background:#E0E0E0; }",
86
+ "LI { padding:3px; }",
87
+ "H1 { margin-top:0; color:navy; }",
88
+ "INPUT { font-size:105%; font-weight:bold; }",
89
+ "#main { width:650px; margin:0 auto; background:#FFF; padding:20px; border:1px solid #BBB; }",
90
+ "#status { padding:10px; }",
91
+ "#sidebar { background:#F0F0F0; float:right; width:200px; padding:5px 15px; font-size:85%; border:10px solid white; border-top:0px; }",
92
+ ".description { background:#FFC; padding:10px; font-size:85%; }",
93
+ ".credit { padding:0px 2px; font-size:90%; color:gray; }",
94
+ ".untested { color:#C5C5C5; }",
95
+ ".untested SPAN { color:black; }",
96
+ ".pass { color:#0F0; }",
97
+ ".pass SPAN { color:#363; }",
98
+ ".fail { color:red; }",
99
+ ".fail DIV { font-size:85%; color:#666; }",
100
+ ".fail SPAN { color:maroon; }",
101
+ ".fail UL { margin:0px; padding:0px; padding-left:10px; list-style:none; }",
102
+ ".fail LI { padding:2px; }",
103
+ ".assertion-type { color:black !important; font-weight:bold; }",
104
+ ".exception-type { color:red !important; font-weight:bold; }"
105
+ )
106
+ ),
107
+ body (
108
+ div ({id:'main'},
109
+ div ({id:'sidebar'},
110
+ p ("This is a simple JavaScript test framework."),
111
+ p ("To read the tests, just view-source."),
112
+ p ("Created by M@ McCray. Released under the MIT license.", {'class':'credit'})
113
+ ),
114
+ h1 (page_title),
115
+ page_desc,
116
+ ul ({id:'test-list'},
117
+ list_html
118
+ ),
119
+ table( tr(
120
+ td(
121
+ input ({ type:'button', onclick:'runAllTests()', value:'Run All Tests'})
122
+ ),
123
+ td(
124
+ div ('&nbsp;',{id:'status'})
125
+ )
126
+ ))
127
+ ),
128
+ div ('&nbsp;', {id:'work-area'})
129
+ )
130
+ );
131
+
132
+ window.assertionCount = 0;
133
+ window.assertionFailCount = 0;
134
+ window.assertionErrorCount = 0;
135
+
136
+ var assertionFailures = [];
137
+
138
+ // Exported functions
139
+ window.runAllTests = function() {
140
+ var errors = [];
141
+ assertionCount = 0;
142
+ assertionFailCount = 0;
143
+
144
+ forEach(methodList, function(func){
145
+ setStatus('Evaluating '+ func +'...');
146
+
147
+ assertionFailures = [];
148
+ assertionExceptions = [];
149
+ try {
150
+ Tests[func]()
151
+ } catch (ex) {
152
+ assertionErrorCount++;
153
+ assertionExceptions.push(ex)
154
+ }
155
+ if( assertionFailures.length == 0 && assertionExceptions.length == 0) {
156
+ $(func).className = 'pass';
157
+ } else {
158
+ $(func).className = 'fail';
159
+ var results = ""
160
+
161
+ forEach(assertionFailures, function(err){
162
+ results += li (
163
+ span (err.assertionType, {'class':'assertion-type'}), ': ',
164
+ (err.message || err.extraInformation)
165
+ );
166
+ });
167
+
168
+ forEach(assertionExceptions, function(err){
169
+ results += li (
170
+ span ('Error', {'class':'exception-type'}), ': ',
171
+ (err.description || err.message || err)
172
+ );
173
+ });
174
+
175
+ setResults( func, ul (results) )
176
+ }
177
+ });
178
+
179
+ setStatus( div (
180
+ assertionCount,
181
+ " assertions, ",
182
+ span ((assertionCount - assertionFailCount), {'class':'pass'}),
183
+ " passed",
184
+ show_if (assertionFailCount, text( ", ",
185
+ span (assertionFailCount, {'class':'fail'}),
186
+ " failed" )
187
+ ),
188
+ show_if (assertionErrorCount, text( ", ",
189
+ span (assertionErrorCount, {'class':'fail'}),
190
+ " error(s)")
191
+ ),
192
+ "."
193
+ ));
194
+ }
195
+
196
+ // Assertions
197
+ window.assert = function(condition, msg) {
198
+ window.assertionCount++;
199
+ if(!condition) {
200
+ ex = 'true was expected, but value was '+ condition;
201
+ assertError(msg, 'assert', ex);
202
+ }
203
+ }
204
+
205
+ window.assertFalse = function(condition, msg) {
206
+ window.assertionCount++;
207
+ if(condition) {
208
+ ex = 'false was expected, but value was '+ condition;
209
+ assertError(msg, 'assertFalse', ex);
210
+ }
211
+ }
212
+
213
+ window.assertNull = function(condition, msg) {
214
+ window.assertionCount++;
215
+ if(null != condition) {
216
+ ex = 'null was expected, but value was '+ condition;
217
+ assertError(msg, 'assertNull', ex);
218
+ }
219
+ }
220
+
221
+ window.assertNotNull = function(condition, msg) {
222
+ window.assertionCount++;
223
+ if(null == condition) {
224
+ ex = 'null was not expected, but value was '+ condition;
225
+ assertError(msg, 'assertNotNull', ex);
226
+ }
227
+ }
228
+
229
+ window.assertEqual = function(condition1, condition2, msg) {
230
+ window.assertionCount++;
231
+ ex = condition1 +' was expected, but value was '+ condition2;
232
+ if(condition1 != condition2) {
233
+ assertError(msg, 'assertEqual', ex);
234
+ }
235
+ }
236
+
237
+ window.assertNotEqual = function(condition1, condition2, msg) {
238
+ window.assertionCount++;
239
+ if(condition1 == condition2) {
240
+ ex = condition1 +' was not expected, but value was '+ condition2;
241
+ assertError(msg, 'assertNotEqual', ex);
242
+ }
243
+ }
244
+
245
+ window.assertUndefined = function(object, msg) {
246
+ window.assertionCount++;
247
+ if(object != 'undefined' ) {
248
+ ex = object +' was defined';
249
+ assertError(msg, 'assertUndefined', ex);
250
+ }
251
+ }
252
+
253
+ window.assertDefined = function(object, msg) {
254
+ window.assertionCount++;
255
+ if(object == 'undefined' ) {
256
+ ex = object +' was undefined';
257
+ assertError(msg, 'assertDefined', ex);
258
+ }
259
+ }
260
+
261
+ // Private functions
262
+ function $(elem) {
263
+ return document.getElementById(elem);
264
+ }
265
+
266
+ function log() {
267
+ var msg = [];
268
+ forEach(arguments, function(arg){ msg.push( arg || '' ); });
269
+ if(window.console && window.console.log) {
270
+ window.console.log(msg.join(' '))
271
+ } else if(window.console && window.console.info) {
272
+ window.console.info(msg.join(' '))
273
+ }
274
+ }
275
+
276
+ function forEach(array, block, context) {
277
+ for (var i = 0; i < array.length; i++) {
278
+ block.call(context, array[i], i, array);
279
+ }
280
+ }
281
+
282
+ function show_if(list, html) {
283
+ if(list > 0)
284
+ return html;
285
+ else
286
+ return '';
287
+ }
288
+
289
+ function setStatus(msg) {
290
+ $('status').innerHTML = msg;
291
+ }
292
+
293
+ function setResults(func, msg) {
294
+ $(func+'-error').innerHTML = msg;
295
+ }
296
+
297
+ function assertError(errorMessage, assertionType, extraInfo) {
298
+ window.assertionFailCount++;
299
+ assertionFailures.push({
300
+ assertionType: assertionType,
301
+ message: errorMessage,
302
+ extraInformation: extraInfo.toString().replace(/</g, '&lt;'),
303
+ description: errorMessage +"\n"+ extraInfo.toString().replace(/</g, '&lt;')
304
+ });
305
+ }
306
+
307
+ })();
@@ -0,0 +1,43 @@
1
+ ENV["RAILS_ENV"] = 'test'
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
4
+
5
+ require 'test/unit'
6
+ require 'test_help'
7
+
8
+ class Test::Unit::TestCase
9
+
10
+ self.fixture_path = File.expand_path( File.join(File.dirname(__FILE__), 'fixtures') )
11
+
12
+ self.use_transactional_fixtures = true
13
+ self.use_instantiated_fixtures = false
14
+
15
+ def create_page(options={})
16
+ Page.create({ :title => 'Comatose Page', :author=>'test', :parent_id=>1 }.merge(options))
17
+ end
18
+
19
+ def comatose_page(sym)
20
+ Page.find_by_slug(sym.to_s.dasherize)
21
+ end
22
+
23
+ def assert_difference(object, method = nil, difference = 1)
24
+ initial_value = object.send(method)
25
+ yield
26
+ assert_equal initial_value + difference, object.send(method), "#{object}##{method}"
27
+ end
28
+
29
+ def assert_no_difference(object, method, &block)
30
+ assert_difference object, method, 0, &block
31
+ end
32
+
33
+ class << self
34
+ def should(behave,&block)
35
+ method_name = "test_should_#{behave.gsub(' ', '_')}"
36
+ if block
37
+ define_method method_name, &block
38
+ else
39
+ puts ">>> Untested: #{name.sub(/Test$/,'')} should #{behave}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'rails/performance_test_help'
3
+
4
+ # Profiling results for each test method are written to tmp/performance.
5
+ class BrowsingTest < ActionDispatch::PerformanceTest
6
+ def test_homepage
7
+ get '/'
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path('../../config/environment', __FILE__)
3
+ require 'rails/test_help'
4
+
5
+ class ActiveSupport::TestCase
6
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
7
+ #
8
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
9
+ # -- they do not yet inherit this setting
10
+ fixtures :all
11
+
12
+ # Add more helper methods to be used by all tests here...
13
+ end