motiro 0.6.8 → 0.6.9

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 (206) hide show
  1. data/AUTHORS +15 -0
  2. data/README +2 -2
  3. data/README.en +1 -2
  4. data/README.pt-br +1 -2
  5. data/app/controllers/account_controller.rb +1 -1
  6. data/app/controllers/application.rb +13 -12
  7. data/app/controllers/javascript_controller.rb +1 -1
  8. data/app/controllers/report_controller.rb +1 -1
  9. data/app/controllers/wiki_controller.rb +3 -5
  10. data/app/core/cache_reporter.rb +1 -1
  11. data/app/core/cache_reporter_fetcher.rb +1 -1
  12. data/app/core/chief_editor.rb +1 -1
  13. data/app/core/reporter.rb +1 -1
  14. data/app/core/reporter_driver.rb +1 -1
  15. data/app/core/reporter_fetcher.rb +1 -1
  16. data/app/core/settings.rb +1 -1
  17. data/app/core/version.rb +1 -1
  18. data/app/core/wiki_reporter.rb +1 -1
  19. data/app/helpers/application_helper.rb +5 -1
  20. data/app/helpers/default_page_provider.rb +6 -2
  21. data/app/helpers/report_helper.rb +14 -1
  22. data/app/models/change.rb +1 -1
  23. data/app/models/chunk.rb +1 -1
  24. data/app/models/feed_observer.rb +1 -1
  25. data/app/models/headline.rb +1 -1
  26. data/app/models/page.rb +38 -4
  27. data/app/models/revision.rb +1 -1
  28. data/app/models/user.rb +1 -1
  29. data/app/models/wiki_reference.rb +21 -0
  30. data/app/models/wiki_sweeper.rb +17 -2
  31. data/app/ports/chdir_runner.rb +1 -1
  32. data/app/ports/runner.rb +1 -1
  33. data/app/reporters/darcs_connection.rb +1 -1
  34. data/app/reporters/darcs_reporter.rb +1 -1
  35. data/app/reporters/darcs_temp_repo.rb +1 -1
  36. data/app/reporters/events_reporter.rb +1 -1
  37. data/app/reporters/features_reporter.rb +1 -1
  38. data/app/reporters/subversion_reporter.rb +1 -1
  39. data/app/reporters/svn_connection.rb +1 -1
  40. data/app/reporters/svn_settings.rb +1 -1
  41. data/app/views/report/list.rhtml +6 -7
  42. data/app/views/report/older.rhtml +1 -2
  43. data/app/views/report/rss.rxml +1 -1
  44. data/app/views/report/show.rhtml +2 -2
  45. data/app/views/wiki/_edit_event.rhtml +2 -0
  46. data/app/views/wiki/_edit_feature.rhtml +2 -0
  47. data/app/views/wiki/_properties_edit.rhtml +3 -5
  48. data/app/views/wiki/_properties_show.rhtml +4 -5
  49. data/app/views/wiki/_show_event.rhtml +3 -0
  50. data/app/views/wiki/_show_feature.rhtml +2 -0
  51. data/app/views/wiki/show.rhtml +1 -1
  52. data/bin/motiro +3 -3
  53. data/config/routes.rb +1 -1
  54. data/db/migrate/024_add_feature_status.rb +11 -0
  55. data/db/migrate/025_add_page_references.rb +12 -0
  56. data/db/migrate/026_convert_link_syntax.rb +12 -0
  57. data/db/migrate/027_register_page_references.rb +12 -0
  58. data/db/motirodb.sqlite.initial +0 -0
  59. data/db/schema_version +1 -1
  60. data/db/translation/pt-BR.rb +7 -1
  61. data/lib/array_extensions.rb +1 -1
  62. data/lib/diff_chunk_builder.rb +1 -1
  63. data/lib/differ.rb +1 -1
  64. data/lib/string_extensions.rb +13 -6
  65. data/lib/stub_hash.rb +1 -1
  66. data/lib/tasks/packaging.rake +10 -12
  67. data/lib/tasks/testing.rake +1 -1
  68. data/lib/tick_daemon.rb +1 -1
  69. data/lib/{wiki_url_generator.rb → wiki_link_handler.rb} +13 -3
  70. data/lib/wiki_renderer.rb +63 -34
  71. data/public/images/done.png +0 -0
  72. data/public/images/not-done.png +0 -0
  73. data/public/stylesheets/motiro.css +8 -0
  74. data/script/ticker +1 -1
  75. data/test/acceptance/account_test.rb +1 -1
  76. data/test/acceptance/darcs_test.rb +1 -1
  77. data/test/acceptance/events_test.rb +1 -1
  78. data/test/acceptance/main_page_test.rb +1 -1
  79. data/test/acceptance/subversion_test.rb +1 -1
  80. data/test/acceptance/ts_all_suites.rb +1 -1
  81. data/test/acceptance/wiki_test.rb +3 -3
  82. data/test/contract/darcs_test.rb +1 -1
  83. data/test/contract/remote_darcs_test.rb +1 -1
  84. data/test/contract/svn_test.rb +1 -1
  85. data/test/fixtures/pages.yml +20 -1
  86. data/test/fixtures/revisions.yml +40 -1
  87. data/test/fixtures/wiki_references.yml +5 -0
  88. data/test/functional/report_controller_test.rb +1 -1
  89. data/test/functional/report_features_test.rb +8 -1
  90. data/test/functional/report_subversion_test.rb +1 -1
  91. data/test/functional/root_controller_test.rb +1 -1
  92. data/test/functional/wiki_controller_test.rb +67 -2
  93. data/test/lib/acceptance_test_case.rb +1 -1
  94. data/test/lib/darcs_excerpts.rb +1 -1
  95. data/test/lib/darcs_repo.rb +1 -1
  96. data/test/lib/hash_extensions.rb +22 -0
  97. data/test/lib/live_mode_test.rb +1 -1
  98. data/test/lib/netutils.rb +1 -1
  99. data/test/lib/platform_thread.rb +1 -1
  100. data/test/lib/selenium_extensions.rb +1 -1
  101. data/test/lib/stubio.rb +1 -1
  102. data/test/lib/webserver.rb +1 -1
  103. data/test/meta/darcs_repo_test.rb +1 -1
  104. data/test/meta/local_svn_test.rb +1 -1
  105. data/test/meta/platform_thread_test.rb +1 -1
  106. data/test/meta/stubio_test.rb +1 -1
  107. data/test/stubs/{url_generator.rb → wiki_link_handler.rb} +8 -4
  108. data/test/test_helper.rb +3 -1
  109. data/test/unit/array_extensions_test.rb +1 -1
  110. data/test/unit/cache_reporter_fetcher_test.rb +1 -1
  111. data/test/unit/cache_reporter_test.rb +1 -1
  112. data/test/unit/change_test.rb +1 -1
  113. data/test/unit/chdir_runner_test.rb +1 -1
  114. data/test/unit/chief_editor_test.rb +1 -1
  115. data/test/unit/darcs_connection_test.rb +1 -1
  116. data/test/unit/darcs_reporter_test.rb +4 -4
  117. data/test/unit/darcs_temp_repo_test.rb +1 -1
  118. data/test/unit/default_page_provider_test.rb +23 -13
  119. data/test/unit/diff_chunk_builder_test.rb +1 -1
  120. data/test/unit/page_test.rb +67 -4
  121. data/test/unit/reporter_driver_test.rb +1 -1
  122. data/test/unit/reporter_test.rb +1 -1
  123. data/test/unit/revision_test.rb +1 -1
  124. data/test/unit/runner_test.rb +1 -1
  125. data/test/unit/string_extensions_test.rb +15 -3
  126. data/test/unit/svn_connection_test.rb +1 -1
  127. data/test/unit/svn_reporter_interaction_test.rb +1 -1
  128. data/test/unit/svn_reporter_test.rb +1 -1
  129. data/test/unit/svn_settings_test.rb +1 -1
  130. data/test/unit/user_test.rb +1 -1
  131. data/test/unit/{wiki_url_generator_test.rb → wiki_link_handler_test.rb} +3 -3
  132. data/test/unit/wiki_renderer_test.rb +75 -20
  133. data/test/unit/wiki_reporter_test.rb +1 -1
  134. data/vendor/mediacloth-trunk/MIT-LICENSE +20 -0
  135. data/vendor/mediacloth-trunk/README +32 -0
  136. data/vendor/mediacloth-trunk/Rakefile +33 -0
  137. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikiast.rb +122 -0
  138. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikihtmlgenerator.rb +252 -0
  139. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikilexer.rb +821 -0
  140. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikilinkhandler.rb +68 -0
  141. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikiparams.rb +33 -0
  142. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikiparser.rb +1218 -0
  143. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikiparser.y +493 -0
  144. data/vendor/mediacloth-trunk/lib/mediacloth/mediawikiwalker.rb +146 -0
  145. data/vendor/mediacloth-trunk/lib/mediacloth.rb +29 -0
  146. data/vendor/mediacloth-trunk/mediacloth.gemspec +24 -0
  147. data/vendor/mediacloth-trunk/mediacloth.kdevelop +117 -0
  148. data/vendor/mediacloth-trunk/setup.rb +1585 -0
  149. data/vendor/mediacloth-trunk/test/data/html1 +26 -0
  150. data/vendor/mediacloth-trunk/test/data/html10 +130 -0
  151. data/vendor/mediacloth-trunk/test/data/html11 +17 -0
  152. data/vendor/mediacloth-trunk/test/data/html12 +12 -0
  153. data/vendor/mediacloth-trunk/test/data/html13 +11 -0
  154. data/vendor/mediacloth-trunk/test/data/html2 +2 -0
  155. data/vendor/mediacloth-trunk/test/data/html3 +1 -0
  156. data/vendor/mediacloth-trunk/test/data/html4 +47 -0
  157. data/vendor/mediacloth-trunk/test/data/html5 +57 -0
  158. data/vendor/mediacloth-trunk/test/data/html6 +8 -0
  159. data/vendor/mediacloth-trunk/test/data/html7 +45 -0
  160. data/vendor/mediacloth-trunk/test/data/html8 +1 -0
  161. data/vendor/mediacloth-trunk/test/data/html9 +14 -0
  162. data/vendor/mediacloth-trunk/test/data/input1 +34 -0
  163. data/vendor/mediacloth-trunk/test/data/input10 +124 -0
  164. data/vendor/mediacloth-trunk/test/data/input11 +17 -0
  165. data/vendor/mediacloth-trunk/test/data/input12 +15 -0
  166. data/vendor/mediacloth-trunk/test/data/input13 +10 -0
  167. data/vendor/mediacloth-trunk/test/data/input2 +2 -0
  168. data/vendor/mediacloth-trunk/test/data/input3 +2 -0
  169. data/vendor/mediacloth-trunk/test/data/input4 +50 -0
  170. data/vendor/mediacloth-trunk/test/data/input5 +63 -0
  171. data/vendor/mediacloth-trunk/test/data/input6 +8 -0
  172. data/vendor/mediacloth-trunk/test/data/input7 +45 -0
  173. data/vendor/mediacloth-trunk/test/data/input8 +1 -0
  174. data/vendor/mediacloth-trunk/test/data/input9 +14 -0
  175. data/vendor/mediacloth-trunk/test/data/lex1 +26 -0
  176. data/vendor/mediacloth-trunk/test/data/lex10 +85 -0
  177. data/vendor/mediacloth-trunk/test/data/lex11 +17 -0
  178. data/vendor/mediacloth-trunk/test/data/lex12 +15 -0
  179. data/vendor/mediacloth-trunk/test/data/lex13 +3 -0
  180. data/vendor/mediacloth-trunk/test/data/lex2 +2 -0
  181. data/vendor/mediacloth-trunk/test/data/lex3 +1 -0
  182. data/vendor/mediacloth-trunk/test/data/lex4 +47 -0
  183. data/vendor/mediacloth-trunk/test/data/lex5 +57 -0
  184. data/vendor/mediacloth-trunk/test/data/lex6 +8 -0
  185. data/vendor/mediacloth-trunk/test/data/lex7 +45 -0
  186. data/vendor/mediacloth-trunk/test/data/lex8 +1 -0
  187. data/vendor/mediacloth-trunk/test/data/lex9 +14 -0
  188. data/vendor/mediacloth-trunk/test/data/result1 +48 -0
  189. data/vendor/mediacloth-trunk/test/dataproducers/html.rb +18 -0
  190. data/vendor/mediacloth-trunk/test/dataproducers/lex.rb +15 -0
  191. data/vendor/mediacloth-trunk/test/debugwalker.rb +68 -0
  192. data/vendor/mediacloth-trunk/test/htmlgenerator.rb +97 -0
  193. data/vendor/mediacloth-trunk/test/lexer.rb +542 -0
  194. data/vendor/mediacloth-trunk/test/linkhandler.rb +39 -0
  195. data/vendor/mediacloth-trunk/test/parser.rb +22 -0
  196. data/vendor/mediacloth-trunk/test/testhelper.rb +27 -0
  197. data/vendor/mediacloth.rb +3 -0
  198. data/vendor/motiro-installer.rb +1 -1
  199. data/vendor/plugins/cache_test-0.2/CHANGELOG +14 -0
  200. data/vendor/plugins/cache_test-0.2/MIT-LICENSE +20 -0
  201. data/vendor/plugins/cache_test-0.2/README +124 -0
  202. data/vendor/plugins/cache_test-0.2/init.rb +8 -0
  203. data/vendor/plugins/cache_test-0.2/lib/fragment_cache_test.rb +205 -0
  204. data/vendor/plugins/cache_test-0.2/lib/page_cache_test.rb +140 -0
  205. data/vendor/plugins/global_routing/init.rb +1 -1
  206. metadata +517 -455
@@ -0,0 +1,39 @@
1
+ require 'mediacloth/mediawikilinkhandler'
2
+
3
+ require 'test/unit'
4
+ require 'testhelper'
5
+
6
+ class LinkHandler_Test < Test::Unit::TestCase
7
+
8
+ def test_resolves_single_links
9
+ handler = create_handler
10
+ assert_equal '<a href="http://example.com/wiki/MyPage">this is my page</a>',
11
+ handler.link_for('MyPage', 'this is my page')
12
+ end
13
+
14
+ def test_forgets_previous_links
15
+ handler = create_handler
16
+ handler.link_for('MyPage', 'this is my page')
17
+ assert_equal '<a href="http://example.com/wiki/YourPage">this page is yours</a>',
18
+ handler.link_for('YourPage', 'this page is yours')
19
+ end
20
+
21
+ def test_provides_suitable_elem_method_for_subclasses
22
+ handler = create_handler
23
+ def handler.link_for(page, text)
24
+ elem.span(:class => 'empty') {|x| x << text }
25
+ end
26
+ assert_equal '<span class="empty">Here is my page</span>',
27
+ handler.link_for('MyPage', 'Here is my page')
28
+ end
29
+
30
+ private
31
+
32
+ def create_handler
33
+ handler = MediaWikiLinkHandler.new
34
+ def handler.url_for(page); "http://example.com/wiki/#{page}"; end
35
+ handler
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,22 @@
1
+ require 'mediacloth/mediawikilexer'
2
+ require 'mediacloth/mediawikiparser'
3
+
4
+ require 'test/unit'
5
+ require 'testhelper'
6
+ require 'debugwalker'
7
+
8
+ class Parser_Test < Test::Unit::TestCase
9
+
10
+ include TestHelper
11
+
12
+ def test_input
13
+ test_files("result") { |input,result|
14
+ parser = MediaWikiParser.new
15
+ parser.lexer = MediaWikiLexer.new
16
+ ast = parser.parse(input)
17
+ walker = DebugWalker.new
18
+ walker.parse(ast)
19
+ }
20
+ end
21
+
22
+ end
@@ -0,0 +1,27 @@
1
+ module TestHelper
2
+
3
+ #Helper method for file-based comparison tests.
4
+ #
5
+ #Looks in "data/" directory for files named "inputXXX",
6
+ #substitutes "input" with baseName and loads the contents
7
+ #of "inputXXX" file into the "input" variable and the
8
+ #contents of "baseNameXXX" into the "result" variable.
9
+ #
10
+ #Then it calls the block with input and result as parameters.
11
+ def test_files(baseName, &action)
12
+ Dir.glob(File.dirname(__FILE__) + "/data/input*").each do |filename|
13
+ resultname = filename.gsub(/input(.*)/, "#{baseName}\\1")
14
+ #exclude backup files
15
+ if not resultname.include?("~")
16
+ input_file = File.new(filename, "r")
17
+ input = input_file.read
18
+ if File.exists?(resultname)
19
+ result_file = File.new(resultname, "r")
20
+ result = result_file.read
21
+
22
+ yield(input, result, resultname)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ $:.push File.expand_path(File.dirname(__FILE__) + '/mediacloth-trunk/lib/')
2
+
3
+ require 'mediacloth-trunk/lib/mediacloth'
@@ -1,5 +1,5 @@
1
1
  # Motiro - A project tracking tool
2
- # Copyright (C) 2006-2007 Thiago Arrais
2
+ # Copyright (C) 2006-2008 Thiago Arrais
3
3
  #
4
4
  # This program is free software; you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -0,0 +1,14 @@
1
+ *0.2* (October 17th, 2006)
2
+
3
+ * overrides default page caching method to record page cached and
4
+ expired and use that information instead of going to the filesystem
5
+ to see if cached file exists or not.
6
+
7
+ * add unit testing
8
+
9
+ * add method for action and fragment caching
10
+
11
+ *0.1* (October 5th, 2006)
12
+
13
+ * first plugin release
14
+
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Damien Merenne
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,124 @@
1
+ = Cache Test Plugin
2
+
3
+ This plugin adds assertions in test cases to check the caching
4
+ logic of your application.
5
+
6
+
7
+ == 1. Installation
8
+
9
+ Unpack into the vendor/plugin and that should be it.
10
+
11
+ == 2. Usage
12
+
13
+ === Testing page caching
14
+
15
+ First create an integration test. Then, to test caching of the
16
+ "/pages/about" and "/pages/contact" pages, add a method like this:
17
+
18
+ def test_caching
19
+ assert_cache_pages("/pages/about", "/pages/contact")
20
+ end
21
+
22
+ The assert_cache_pages method will
23
+
24
+ - first make sure that the urls are not cached,
25
+ - execute a get on each request,
26
+ - assert that the corresponding cache files have been created.
27
+
28
+ You can also give a block to the assert_cache_pages method. Instead
29
+ of executing a get on each url, it will yield the urls. For example:
30
+
31
+ def test_caching
32
+ assert_cache_pages("/pages/about", "/pages/contact") do |url_about, url_contact|
33
+ post url_about
34
+ post url_contact
35
+ end
36
+ end
37
+
38
+ === Testing expiration of pages
39
+
40
+ You will also certainly want (and that's really the most interesting
41
+ part) to check if your cached pages expires when the user is doing
42
+ some action. For that, here is the assert_expire method:
43
+
44
+ def test_expiring
45
+ assert_expire_pages("/news/list", "/news/show/1") do |*urls|
46
+ post "/news/delete/1"
47
+ end
48
+ end
49
+
50
+ Here the assert_expire_pages method will
51
+
52
+ - check that the urls are cached,
53
+ - execute the post request,
54
+ - and assert that the urls are no more cached.
55
+
56
+ This is great for testing your cache sweepers logic.
57
+
58
+ === Testing action caching
59
+
60
+ To test caching of the "bar" action of the foo "controller"
61
+ in an integration test, do
62
+
63
+ assert_cache_actions(:controller => "foo", :action => "bar") do
64
+ get "/foo/bar"
65
+ end
66
+
67
+ The assert_cache_actions method will
68
+ - first make sure that the actions are not cached,
69
+ - yield the given block
70
+ - assert that the corresponding action fragment have been stored.
71
+
72
+ === Testing expiration of actions
73
+
74
+ To check that some actions are expired, use the assert_expire_actions method:
75
+
76
+ assert_expire_actions(:controller => "foo", :action => "bar") do |*urls|
77
+ post "/foo/expire_cache"
78
+ end
79
+
80
+ Here the assert_expire_actions method will
81
+
82
+ - check that the actions fragments are cached,
83
+ - execute the post request,
84
+ - and assert that the fragments are no more cached.
85
+
86
+ In functional test, there can be only one controller, so you are
87
+ not required to give the :controller option and if they are no
88
+ parameters to the action, you can simply call
89
+
90
+ assert_cache_actions(:foo, :bar) do
91
+ get :bar
92
+ get :foo
93
+ end
94
+
95
+ == Testing fragments caching
96
+
97
+ To check that your fragments are cached when doing some action,
98
+ do
99
+
100
+ assert_cache_fragments(:controller => "foo", :action => "bar", :action_suffix => "baz") do
101
+ get "/foo/bar"
102
+ end
103
+
104
+ == Testing expiration of fragments
105
+
106
+ To check that your fragments are expired when doing some action,
107
+ do
108
+
109
+ assert_expire_fragments(:controller => "foo", :action => "bar", :action_suffix => "baz") do
110
+ get "/foo/expire"
111
+ end
112
+
113
+ In functional test, your not required to give the :controller option.
114
+
115
+ == 3. License
116
+
117
+ This plugin is licensed under the MIT license. Complete license text
118
+ is included in the MIT-LICENSE[link:files/MIT-LICENSE.html] file.
119
+
120
+ == 4. Author
121
+
122
+ This plugin was created by Damien Merenne <dam@cosinux.org> and is
123
+ located at http://blog.cosinux.org/pages/page-cache-test.
124
+
@@ -0,0 +1,8 @@
1
+ if RAILS_ENV == "test"
2
+ require 'page_cache_test'
3
+ require 'fragment_cache_test'
4
+
5
+ Cosinux::PageCacheTest.configure
6
+ Cosinux::FragmentCacheTest.configure
7
+ end
8
+
@@ -0,0 +1,205 @@
1
+ module Cosinux
2
+ module FragmentCacheTest #:nodoc:
3
+ class NoRequestInBlockError < StandardError #:nodoc:
4
+ end
5
+
6
+ class NoControllerDefinedError < StandardError #:nodoc:
7
+ end
8
+
9
+ # This fragment store remembers the fragments that have been
10
+ # cached or deleted so that we can use it to check if
11
+ # caching or expiring of fragment was done or not.
12
+ class TestStore < ActionController::Caching::Fragments::MemoryStore #:nodoc:
13
+ attr_reader :written, :deleted, :deleted_matchers
14
+
15
+ def initialize
16
+ super
17
+ @written = []
18
+ @deleted = []
19
+ @deleted_matchers = []
20
+ end
21
+
22
+ def reset
23
+ @data.clear
24
+ @written.clear
25
+ @deleted.clear
26
+ @deleted_matchers.clear
27
+ end
28
+
29
+ def write(name, value, options = nil)
30
+ @written.push(name)
31
+ super
32
+ end
33
+
34
+ def delete(name, options = nil)
35
+ @deleted.push(name)
36
+ super
37
+ end
38
+
39
+ def delete_matched(matcher, options = nil)
40
+ @deleted_matchers.push(matcher)
41
+ end
42
+
43
+ def written?(name)
44
+ @written.include?(name)
45
+ end
46
+
47
+ def deleted?(name)
48
+ @deleted.include?(name) || @deleted_matchers.detect { |matcher| name =~ matcher }
49
+ end
50
+ end
51
+
52
+ def self.configure #:nodoc:
53
+ ActionController::Base.perform_caching = true
54
+ ActionController::Base.fragment_cache_store = TestStore.new
55
+
56
+ Test::Unit::TestCase.class_eval do
57
+ include Assertions
58
+ end
59
+ end
60
+
61
+ # This module define method to validate the fragment and action caching logic of
62
+ # your application in both integration and functional tests.
63
+ #
64
+ # == Testing action caching
65
+ #
66
+ # To test caching of the "bar" action of the foo "controller"
67
+ # in an integration test, do
68
+ #
69
+ # assert_cache_actions(:controller => "foo", :action => "bar") do
70
+ # get "/foo/bar"
71
+ # end
72
+ #
73
+ # The assert_cache_actions method will
74
+ # - first make sure that the actions are not cached,
75
+ # - yield the given block
76
+ # - assert that the corresponding action fragment have been stored.
77
+ #
78
+ # == Testing expiring of actions
79
+ #
80
+ # To check that some actions are expired, use the assert_expire_actions method:
81
+ #
82
+ # assert_expire_actions(:controller => "foo", :action => "bar") do |*urls|
83
+ # post "/foo/expire_cache"
84
+ # end
85
+ #
86
+ # Here the assert_expire_actions method will
87
+ #
88
+ # - check that the actions fragments are cached,
89
+ # - execute the post request,
90
+ # - and assert that the fragments are no more cached.
91
+ #
92
+ # In functional test, there can be only one controller, so you are
93
+ # not required to give the :controller option and if they are no
94
+ # parameters to the action, you can simply call
95
+ #
96
+ # assert_cache_actions(:foo, :bar) do
97
+ # get :bar
98
+ # get :foo
99
+ # end
100
+ #
101
+ # == Testing fragments caching
102
+ #
103
+ # To check that your fragments are cached when doing some action,
104
+ # do
105
+ #
106
+ # assert_cache_fragments(:controller => "foo", :action => "bar", :action_suffix => "baz") do
107
+ # get "/foo/bar"
108
+ # end
109
+ #
110
+ # == Testing expiration of fragments
111
+ #
112
+ # To check that your fragments are expired when doing some action,
113
+ # do
114
+ #
115
+ # assert_expire_fragments(:controller => "foo", :action => "bar", :action_suffix => "baz") do
116
+ # get "/foo/expire"
117
+ # end
118
+ #
119
+ # In functional test, your not required to give the :controller option.
120
+ module Assertions
121
+ # asserts that the list of given fragment name are being cached
122
+ def assert_cache_fragments(*names)
123
+ # in integration test, we need the know the controller
124
+ check_options_has_controller(names) if self.is_a?(ActionController::IntegrationTest)
125
+
126
+ fragment_cache_store.reset
127
+
128
+ yield *names
129
+
130
+ # if there is no variable @controller, then we haven't done any request
131
+ raise NoRequestInBlockError.new("no request was send while executing block.") if @controller.nil?
132
+
133
+ names.each do |name|
134
+ assert_block("#{name.inspect} is not cached after executing block") do
135
+ fragment_cache_store.written?(@controller.fragment_cache_key(name))
136
+ end
137
+ end
138
+ end
139
+
140
+ # assert that the list of given fragment are being expired
141
+ def assert_expire_fragments(*names)
142
+ check_options_has_controller(names) if self.is_a?(ActionController::IntegrationTest)
143
+
144
+ fragment_cache_store.reset
145
+
146
+ yield *names
147
+
148
+ raise NoRequestInBlockError.new("no request was send while executing block.") if @controller.nil?
149
+
150
+ names.each do |name|
151
+ assert_block("#{name.inspect} is cached after executing block") do
152
+ fragment_cache_store.deleted?(@controller.fragment_cache_key(name))
153
+ end
154
+ end
155
+ end
156
+
157
+ # assert that the given actions are being cached
158
+ def assert_cache_actions(*actions)
159
+ check_options_has_controller(actions) if self.is_a?(ActionController::IntegrationTest)
160
+
161
+ fragment_cache_store.reset
162
+
163
+ yield *actions
164
+
165
+ raise NoRequestInBlockError.new("no request was send while executing block.") if @controller.nil?
166
+
167
+ actions.each do |action|
168
+ action = { :action => action } unless action.is_a?(Hash)
169
+ assert_block("#{action.inspect} is not cached after executing block") do
170
+ fragment_cache_store.written?(@controller.fragment_cache_key(action))
171
+ end
172
+ end
173
+ end
174
+
175
+ # assert that the given actions are being expired
176
+ def assert_expire_actions(*actions)
177
+ check_options_has_controller(actions) if self.is_a?(ActionController::IntegrationTest)
178
+
179
+ fragment_cache_store.reset
180
+
181
+ yield *actions
182
+
183
+ raise NoRequestInBlockError.new("no request was send while executing block.") if @controller.nil?
184
+
185
+ actions.each do |action|
186
+ action = { :action => action } unless action.is_a?(Hash)
187
+ assert_block("#{action.inspect} is cached after executing block") do
188
+ fragment_cache_store.deleted?(@controller.fragment_cache_key(action))
189
+ end
190
+ end
191
+ end
192
+
193
+ private
194
+ def fragment_cache_store
195
+ ActionController::Base.fragment_cache_store
196
+ end
197
+
198
+ def check_options_has_controller(options)
199
+ if option = options.detect { |option| option[:controller].nil? }
200
+ raise NoControllerDefinedError.new("no controller given in option #{option.inspect} in integration test")
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,140 @@
1
+ module Cosinux #:nodoc:
2
+ module PageCacheTest #:nodoc:
3
+
4
+ def self.configure #:nodoc:
5
+ ActionController::Base.perform_caching = true
6
+
7
+ # overwrite class caching methods
8
+ ActionController::Base.class_eval do
9
+ include ClassCachingMethods
10
+ end
11
+
12
+ # include integration test methods
13
+ Test::Unit::TestCase.class_eval do
14
+ include IntegrationTestMethods
15
+ end
16
+ end
17
+
18
+ module ClassCachingMethods #:nodoc:
19
+ def self.included(base)
20
+ base.extend(ClassMethods)
21
+ base.class_eval do
22
+ @@test_page_cached = []
23
+ cattr_accessor :test_page_cached
24
+ @@test_page_expired = []
25
+ cattr_accessor :test_page_expired
26
+ end
27
+ end
28
+
29
+ module ClassMethods #:nodoc:
30
+ def cache_page(content, path)
31
+ logger.info "Cached page: #{page_cache_file(path)}"
32
+ test_page_cached.push(path)
33
+ end
34
+
35
+ def expire_page(path)
36
+ logger.info "Expired page: #{page_cache_file(path)}"
37
+ test_page_expired.push(path)
38
+ end
39
+
40
+ def cached?(path)
41
+ test_page_cached.include?(path)
42
+ end
43
+
44
+ def expired?(path)
45
+ test_page_expired.include?(path)
46
+ end
47
+
48
+ def reset_cache
49
+ test_page_cached.clear
50
+ test_page_expired.clear
51
+ end
52
+ end
53
+
54
+ def cached?(options = {})
55
+ self.class.cached?(url_for(options.merge({ :only_path => true, :skip_relative_url_root => true })))
56
+ end
57
+
58
+ def expired?(options = {})
59
+ self.class.expired?(url_for(options.merge({ :only_path => true, :skip_relative_url_root => true })))
60
+ end
61
+ end
62
+
63
+ # This module define method to validate the page caching logic of
64
+ # your application in integration tests.
65
+ #
66
+ # == Testing page caching
67
+ #
68
+ # To test caching of the "/pages/about" and "/pages/contact"
69
+ # pages, add a method like this:
70
+ #
71
+ # def test_caching
72
+ # assert_cache_pages("/pages/about", "/pages/contact")
73
+ # end
74
+ #
75
+ # The assert_cache method will
76
+ # - first make sure that the urls are not cached,
77
+ # - execute a get on each request,
78
+ # - assert that the corresponding cache files have been created.
79
+ #
80
+ # You can also give a block to the assert_cache method. Instead
81
+ # of executing a get on each url, it will yield the urls. For example:
82
+ #
83
+ # def test_caching
84
+ # assert_cache_pages("/pages/about", "/pages/contact") do |url_about, url_contact|
85
+ # post url_about
86
+ # post url_contact
87
+ # end
88
+ # end
89
+ #
90
+ # == Testing expiring of pages
91
+ #
92
+ # You will also certainly want to check if your cached pages
93
+ # expires when the user is doing some action. For that, here is
94
+ # the assert_expire method:
95
+ #
96
+ # def test_expiring
97
+ # assert_expire_pages("/news/list", "/news/show/1") do |*urls|
98
+ # post "/news/delete/1"
99
+ # end
100
+ # end
101
+ #
102
+ # Here the assert_expire_pages method will
103
+ #
104
+ # - check that the urls are cached,
105
+ # - execute the post request,
106
+ # - and assert that the urls are no more cached.
107
+ #
108
+ module IntegrationTestMethods
109
+ # asserts that the list of given url are being cached
110
+ def assert_cache_pages(*urls)
111
+ ActionController::Base.reset_cache
112
+
113
+ if block_given?
114
+ yield *urls
115
+ else
116
+ urls.each { |url| get url }
117
+ end
118
+
119
+ urls.each do |url|
120
+ assert_block("#{url.inspect} is not cached after executing block") do
121
+ ActionController::Base.cached?(url)
122
+ end
123
+ end
124
+ end
125
+
126
+ # asserts that the list of given url are being expired
127
+ def assert_expire_pages(*urls)
128
+ ActionController::Base.reset_cache
129
+
130
+ yield *urls
131
+
132
+ urls.each do |url|
133
+ assert_block("#{url.inspect} is cached after executing block") do
134
+ ActionController::Base.expired?(url)
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -1,5 +1,5 @@
1
1
  # Motiro - A project tracking tool
2
- # Copyright (C) 2006-2007 Thiago Arrais
2
+ # Copyright (C) 2006-2008 Thiago Arrais
3
3
  #
4
4
  # This program is free software; you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by