Soks 0.0.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/LICENSE.txt +2 -0
  2. data/README.txt +3 -2
  3. data/TODO.txt +31 -0
  4. data/bin/soks-create-wiki.rb +0 -1
  5. data/lib/authenticators.rb +30 -4
  6. data/lib/helpers/counter-helpers.rb +132 -0
  7. data/lib/helpers/default-helpers.rb +170 -169
  8. data/lib/helpers/mail2wiki-helper.rb +18 -22
  9. data/lib/helpers/maintenance-helpers.rb +149 -0
  10. data/lib/helpers/rss2wiki-helper.rb +7 -8
  11. data/lib/soks-model.rb +82 -54
  12. data/lib/soks-servlet.rb +126 -108
  13. data/lib/soks-storage.rb +74 -11
  14. data/lib/soks-utils.rb +77 -3
  15. data/lib/soks-view.rb +169 -103
  16. data/lib/soks.rb +5 -23
  17. data/templates/default/attachment/newpage.js +4 -13
  18. data/templates/default/attachment/print_stylesheet.css +2 -7
  19. data/templates/default/caches/readme.txt +1 -0
  20. data/templates/default/content/Api%20for%20classes%20to%20modify%20the%20wiki.textile +2 -0
  21. data/templates/default/content/Author.textile +4 -1
  22. data/templates/default/content/Automatic%20Summaries.textile +16 -53
  23. data/templates/default/content/Automatic%20linking%20between%20pages.textile +3 -3
  24. data/templates/default/content/{bug%3A%20competing%20edits.textile → Bug%3A%20Competing%20edits.textile} +9 -0
  25. data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +2 -0
  26. data/templates/default/content/Bug%3A%20E%2Dmail%20addresses%20with%20hyphens%20not%20recognised.textile +17 -0
  27. data/templates/default/content/Bug%3A%20Email%20adresses%20in%20page%20titles%20cause%20incorrec.textile +3 -0
  28. data/templates/default/content/Bug%3A%20GEM%20limits%20title%20lengths.textile +3 -1
  29. data/templates/default/content/Bug%3A%20Memory%20leak.textile +13 -0
  30. data/templates/default/content/Bug%3A%20Pages%20that%20link%20here%20may%20not%20appear%20on%20r.textile +13 -0
  31. data/templates/default/content/Bug%3A%20Textile%20mishandles%20paragraphs.textile +4 -0
  32. data/templates/default/content/Bug%3A%20Unanticipated%20Rollbacks.textile +2 -0
  33. data/templates/default/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +2 -0
  34. data/templates/default/content/Home%20Page.textile +3 -1
  35. data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +23 -13
  36. data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +3 -1
  37. data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +22 -0
  38. data/templates/default/content/How%20to%20get%20the%20latest%20Soks%20from%20cvs.textile +2 -0
  39. data/templates/default/content/How%20to%20hack%20soks.textile +2 -0
  40. data/templates/default/content/How%20to%20import%20a%20site%20from%20instiki.textile +2 -0
  41. data/templates/default/content/{How%20to%20import%20data%20to%20this%20wiki.textile → How%20to%20import%20data.textile} +3 -7
  42. data/templates/default/content/How%20to%20install%20Soks.textile +2 -0
  43. data/templates/default/content/How%20to%20password%20protect%20your%20wiki.textile +21 -11
  44. data/templates/default/content/How%20to%20report%20a%20bug.textile +2 -1
  45. data/templates/default/content/How%20to%20upgrade%20soks.textile +22 -0
  46. data/templates/default/content/How%20to%20use%20the%20keyboard%20shortcuts.textile +2 -2
  47. data/templates/default/content/How%20to%20use%20this%20wiki.textile +3 -1
  48. data/templates/default/content/List%20of%20changes.textile +84 -118
  49. data/templates/default/content/News%3A%20Version%201%2D0%2D0%20released.textile +19 -0
  50. data/templates/default/content/Pages%20to%20include%20in%20the%20distribution.textile +51 -0
  51. data/templates/default/content/Per%20Wiki%20Templates.textile +2 -0
  52. data/templates/default/content/Planned%20Features.textile +30 -9
  53. data/templates/default/content/README.textile +3 -2
  54. data/templates/default/content/RSS%20feed.textile +1 -1
  55. data/templates/default/content/Recent%20changes%20to%20this%20site.textile +283 -0
  56. data/templates/default/content/SOKS%20features.textile +3 -0
  57. data/templates/default/content/Site%20Index.textile +202 -0
  58. data/templates/default/content/Soks%20Licence.textile +2 -0
  59. data/templates/default/content/Tag%3A%20Include%20this%20page%20in%20the%20distribution.textile +6 -0
  60. data/templates/default/start.rb +67 -123
  61. data/templates/default/version.txt +1 -1
  62. data/templates/default/views/Page_edit.rhtml +7 -7
  63. data/templates/default/views/{Page_search_results.rhtml → Page_find.rhtml} +9 -3
  64. data/templates/default/views/Page_linksfromrss.rhtml +24 -0
  65. data/templates/default/views/Page_listrss.rhtml +46 -0
  66. data/templates/default/views/Page_meta.rhtml +1 -1
  67. data/templates/default/views/Page_revision.rhtml +39 -0
  68. data/templates/default/views/Page_revisions.rhtml +13 -5
  69. data/templates/default/views/Page_rss.rhtml +8 -8
  70. data/templates/default/views/Page_view.rhtml +3 -3
  71. data/templates/default/views/UploadPage_edit.rhtml +8 -8
  72. data/templates/default/views/frame.rhtml +8 -8
  73. data/templates/default/views/messages.yaml +1 -0
  74. data/test/html/2006Mar.html +66 -0
  75. data/test/html/poignant.html +36 -0
  76. data/test/html/poignant.textile +36 -0
  77. data/test/mock-objects.rb +69 -0
  78. data/test/stress_url_calls.rb +33 -0
  79. data/test/stress_urls.txt +68 -0
  80. data/test/test_counter-helper.rb +158 -0
  81. data/test/test_soks-helper-maintenance.rb +106 -0
  82. data/test/test_soks-helpers.rb +104 -0
  83. data/test/test_soks-model.rb +144 -0
  84. data/test/test_soks-servlet.rb +231 -0
  85. data/test/test_soks-storage.rb +70 -31
  86. data/test/test_soks-utils.rb +112 -13
  87. data/test/test_soks-view.rb +141 -3
  88. metadata +38 -27
  89. data/templates/default/content/A%20page%20with%20an%20umlaut%20%F6%20in%20its%20title.textile +0 -1
  90. data/templates/default/content/All%20News.textile +0 -26
  91. data/templates/default/content/Bil%20Kleb.textile +0 -1
  92. data/templates/default/content/Bil.textile +0 -1
  93. data/templates/default/content/Bill%20Wood.textile +0 -3
  94. data/templates/default/content/Bug%3A%20RSS%20feed%20does%20not%20validate.textile +0 -10
  95. data/templates/default/content/Bug%3A%20Type%20a%20title%20here.textile +0 -31
  96. data/templates/default/content/Instructions%20and%20Howtos.textile +0 -21
  97. data/templates/default/content/Latest%20News.textile +0 -26
  98. data/templates/default/content/New%20Recent%20Changes%20class.textile +0 -68
  99. data/templates/default/content/New%20page%20templates%20or%20categories%20code.textile +0 -68
  100. data/templates/default/content/News%3A%20Version%200%2E0%2E6%20Released.textile +0 -13
  101. data/templates/default/content/Recent%20Blog%20Entries.textile +0 -5
  102. data/templates/default/content/Recent%20Changes%20to%20This%20Site.textile +0 -286
  103. data/templates/default/content/Ruby.textile +0 -9
  104. data/templates/default/content/Skorgu.textile +0 -3
  105. data/templates/default/content/ctrl%2Dn.textile +0 -1
  106. data/templates/default/content/let%20me%20know.textile +0 -1
  107. data/templates/default/content/sandbox.textile +0 -20
  108. data/templates/default/content/tamc.textile +0 -1
  109. data/templates/default/content/tamc2.textile +0 -1
@@ -0,0 +1,231 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+ require 'mock-objects'
4
+
5
+ class MockFileData
6
+
7
+ attr_accessor :filename, :list
8
+
9
+ def initialize( filename = 'test file.txt', list = ['0123456789'])
10
+ @filename, @list = filename, list
11
+ end
12
+ end
13
+
14
+ class WEBrick::HTTPServlet::FileHandler
15
+
16
+ def service( request, response )
17
+ response.body = "File #{request.script_name.downcase} #{request.path_info}"
18
+ end
19
+
20
+ end
21
+
22
+ class MockRequest < Hash
23
+
24
+ def path_info
25
+ return path
26
+ end
27
+
28
+ def method_missing( method, *args )
29
+ if method.to_s[-1,1] == '=' && args.length == 1
30
+ self[method.to_s[0...-1].to_sym] = args.first
31
+ else
32
+ self[method]
33
+ end
34
+ end
35
+
36
+ end
37
+
38
+ class MockResponse < Hash
39
+
40
+ def set_redirect( type, destination )
41
+ self[:redirect_type] = type
42
+ self[:redirect_destination] = destination
43
+ end
44
+
45
+ def method_missing( method, *args )
46
+ if method.to_s[-1,1] == '=' && args.length == 1
47
+ self[method.to_s[0...-1].to_sym] = args.first
48
+ else
49
+ self[method]
50
+ end
51
+ end
52
+ end
53
+
54
+ class MockServer
55
+
56
+ def config
57
+ {:Logger => 'a' }
58
+ end
59
+
60
+ end
61
+
62
+ class TestWikiServlet < Test::Unit::TestCase
63
+ include TearDownableWiki
64
+
65
+ def setup
66
+ super
67
+ @servlet = WikiServlet.new( MockServer.new, ServletSettings.new(@wiki,@view) )
68
+ @servlet.settings.static_file_directories['Attachment'] = "#{folder}/attachment"
69
+ @servlet.settings.upload_directory = 'Attachment'
70
+ end
71
+
72
+ def test_static_files
73
+ @servlet.service( re = MockRequest[ :path => '/favicon.ico' ], rp = MockResponse.new )
74
+ assert_equal( nil, rp[:redirect_destination] )
75
+ assert_equal( "File attachment /favicon.ico", rp[:body])
76
+ @servlet.service( re = MockRequest[ :path => '/robots.txt' ], rp = MockResponse.new )
77
+ assert_equal( nil, rp[:redirect_destination] )
78
+ assert_equal( "File attachment /robots.txt", rp[:body])
79
+ end
80
+
81
+ def test_standard_attachment
82
+ @servlet.service( re = MockRequest[ :path => '/attachment/logo.jpg' ], rp = MockResponse.new )
83
+ assert_equal( nil, rp[:redirect_destination] )
84
+ assert_equal( "File attachment /attachment/logo.jpg", rp[:body])
85
+ end
86
+
87
+ def test_second_attachment
88
+ @servlet.settings.static_file_directories['Www'] = '/var/www'
89
+ test_standard_attachment
90
+ @servlet.service( re = MockRequest[ :path => '/www/logo.jpg' ], rp = MockResponse.new )
91
+ assert_equal( nil, rp[:redirect_destination] )
92
+ assert_equal( "File www /www/logo.jpg", rp[:body])
93
+ end
94
+
95
+ def test_redirect_to_home_page
96
+ @servlet.service( re = MockRequest[ :path => '/' ], rp = MockResponse.new )
97
+ assert_equal( 'http://testsite.com/view/HomePage', rp[:redirect_destination])
98
+ end
99
+
100
+ def test_redirect_to_view
101
+ @servlet.service( re = MockRequest[ :path => '/randompage' ], rp = MockResponse.new )
102
+ assert_equal( 'http://testsite.com/view/Randompage', rp[:redirect_destination])
103
+ end
104
+
105
+ def test_missing_view
106
+ assert_raise(WEBrick::HTTPStatus::NotFound) { @servlet.service( re = MockRequest[ :path => '/missing/randompage', :user => 'test user' ], rp = MockResponse.new ) }
107
+ end
108
+
109
+ def test_view_page
110
+ @wiki.revise('test view','hello world','tamc2')
111
+ assert_equal('hello world', @wiki.page('test view').content )
112
+ @servlet.service( re = MockRequest[ :path => '/view/test view', :user => 'test user', :query => {} ], rp = MockResponse.new )
113
+ assert_equal( nil, rp[:redirect_destination] )
114
+ assert_match( /<p>hello world<\/p>/, rp[:body])
115
+ end
116
+
117
+ def test_name_to_url_conversion
118
+ @wiki.revise('page!','exclamation','one')
119
+ @wiki.revise('page?','question','one')
120
+ @servlet.service( re = MockRequest[ :path => '/view/Page', :user => 'test user', :query => {} ], rp = MockResponse.new )
121
+ assert_match( /<p>exclamation<\/p>/, rp[:body])
122
+ @servlet.service( re = MockRequest[ :path => '/view/Page-2', :user => 'test user', :query => {} ], rp = MockResponse.new )
123
+ assert_match( /<p>question<\/p>/, rp[:body])
124
+ end
125
+
126
+ def test_create_page
127
+ @servlet.service( re = MockRequest[ :path => '/save/test save', :user => 'test user', :query => { 'content' => 'hello world', 'newtitle' => 'test save' } ], rp = MockResponse.new )
128
+ assert_equal( 'http://testsite.com/view/TestSave', rp[:redirect_destination] )
129
+ page = @wiki.page('test save')
130
+ assert_equal( 'test user', page.author )
131
+ assert_equal( 'hello world', page.content )
132
+ end
133
+
134
+ def test_revise_page
135
+ @wiki.revise('test save','stuff','someone')
136
+ @servlet.service( re = MockRequest[ :path => '/save/TestSave', :user => 'test user', :query => { 'content' => 'hello world', 'newtitle' => 'test save' } ], rp = MockResponse.new )
137
+ assert_equal( 'http://testsite.com/view/TestSave', rp[:redirect_destination] )
138
+ page = @wiki.page('test save')
139
+ assert_equal( 'test save',page.name )
140
+ assert_equal( 'test user', page.author )
141
+ assert_equal( 'hello world', page.content )
142
+ end
143
+
144
+ def test_revise_prefix_page
145
+ @servlet.service( re = MockRequest[ :path => '/save/test save', :user => 'test user', :query => { 'content' => 'hello world', 'titleprefix' => 'test ', 'newtitle' => 'save' } ], rp = MockResponse.new )
146
+ assert_equal( 'http://testsite.com/view/TestSave', rp[:redirect_destination] )
147
+ page = @wiki.page('test save')
148
+ assert_equal( 'test user', page.author )
149
+ assert_equal( 'hello world', page.content )
150
+ end
151
+
152
+ def test_revise_change_capitalisation_on_page
153
+ @servlet.service( re = MockRequest[ :path => '/edit/test caps', :user => 'test user', :query => {} ], rp = MockResponse.new )
154
+ @servlet.service( re = MockRequest[ :path => '/save/TestCaps', :user => 'test user', :query => { 'content' => 'hello world', 'newtitle' => 'test caps' } ], rp = MockResponse.new )
155
+ assert_equal( 'http://testsite.com/view/TestCaps', rp[:redirect_destination] )
156
+ assert_equal('test caps', @wiki.page('test caps').name )
157
+ @servlet.service( re = MockRequest[ :path => '/save/TestCaps', :user => 'test user', :query => { 'content' => 'hello world', 'newtitle' => 'Test Caps' } ], rp = MockResponse.new )
158
+ assert_equal( 'http://testsite.com/view/TestCaps', rp[:redirect_destination] )
159
+ assert_equal('Test Caps', @wiki.page('test caps').name )
160
+ end
161
+
162
+ def test_revise_and_move_page
163
+ @wiki.revise('test view','hello world','tamc2')
164
+ assert_equal('hello world', @wiki.page('test view').content )
165
+ @servlet.service( re = MockRequest[ :path => '/save/test view', :user => 'test user', :query => { 'content' => 'hello world', 'newtitle' => 'test save' } ], rp = MockResponse.new )
166
+ assert_equal( 'http://testsite.com/view/TestSave', rp[:redirect_destination] )
167
+ newpage = @wiki.page('test save')
168
+ assert_equal( 'test user', newpage.author )
169
+ assert_equal( 'hello world', newpage.content )
170
+ oldpage = @wiki.page('test view')
171
+ assert_equal( 'test user', oldpage.author )
172
+ assert_equal( 'content moved to [[test save]]', oldpage.content )
173
+ end
174
+
175
+ def test_revise_and_dont_move_template_page
176
+ @wiki.revise('test type a title here','hello world','tamc2')
177
+ @servlet.service( re = MockRequest[ :path => '/save/test type a title here', :user => 'test user', :query => { 'content' => 'hello world', 'newtitle' => 'test save' } ], rp = MockResponse.new )
178
+ assert_equal( 'http://testsite.com/view/TestSave', rp[:redirect_destination] )
179
+ newpage = @wiki.page('test save')
180
+ assert_equal( 'test user', newpage.author )
181
+ assert_equal( 'hello world', newpage.content )
182
+ oldpage = @wiki.page('test type a title here')
183
+ assert_equal( 'tamc2', oldpage.author )
184
+ assert_equal( 'hello world', oldpage.content )
185
+ end
186
+
187
+ def test_delete_page
188
+ @wiki.revise('test delete','hello world','tamc2')
189
+ page = @wiki.page('test delete')
190
+ assert_equal('hello world', page.content )
191
+ assert_equal( false, page.deleted? )
192
+ @servlet.service( re = MockRequest[ :path => '/delete/test delete', :user => 'test user', :query => {} ], rp = MockResponse.new )
193
+ assert_equal( 'http://testsite.com/view/TestDelete', rp[:redirect_destination] )
194
+ assert_equal( 'test user', page.author )
195
+ assert_equal('page deleted', page.content )
196
+ assert_equal( true, page.deleted? )
197
+ end
198
+
199
+ def test_rollback_page
200
+ 0.upto(5) { |i| @wiki.revise('rollback test', i.to_s, 'test') }
201
+ assert_equal( '5', @wiki.page('rollback test').textile )
202
+ assert_equal( 'test', @wiki.page('rollback test').author )
203
+ @servlet.service( re = MockRequest[ :path => '/rollback/rollback test', :user => 'rollbacker', :query => { 'revision' => 3 } ], rp = MockResponse.new )
204
+ assert_equal( 'http://testsite.com/view/RollbackTest', rp[:redirect_destination] )
205
+ assert_equal( '3', @wiki.page('rollback test').textile )
206
+ assert_equal( 'rollbacker', @wiki.page('rollback test').author )
207
+ end
208
+
209
+ def test_upload
210
+ filedata = MockFileData.new
211
+ @servlet.service( re = MockRequest[ :path => '/upload/upload test', :user => 'uploader', :query => { 'file' => filedata, 'titleprefix' => 'upload ', 'newtitle' => 'test'} ], rp = MockResponse.new )
212
+ assert_equal( 'http://testsite.com/view/UploadTest', rp[:redirect_destination] )
213
+ page = @wiki.page('upload test')
214
+ assert_equal( 'uploader', page.author )
215
+ assert_equal( '/Attachment/testfile.txt', page.content )
216
+ end
217
+
218
+ def test_move_upload
219
+ test_upload
220
+ filedata = MockFileData.new
221
+ @servlet.service( re = MockRequest[ :path => '/upload/upload test', :user => 'uploader2', :query => { 'file' => filedata, 'titleprefix' => 'upload ', 'newtitle' => 'second test'} ], rp = MockResponse.new )
222
+ assert_equal( 'http://testsite.com/view/UploadSecondTest', rp[:redirect_destination] )
223
+ newpage = @wiki.page('upload second test')
224
+ assert_equal( 'uploader2', newpage.author )
225
+ assert_equal( '/Attachment/testfile1.txt', newpage.content )
226
+ oldpage = @wiki.page('upload test')
227
+ assert_equal( 'uploader2', oldpage.author )
228
+ assert_equal( 'content moved to [[upload second test]]', oldpage.content )
229
+ end
230
+
231
+ end
@@ -1,28 +1,44 @@
1
1
  require 'test/unit'
2
2
  require 'fileutils'
3
+ require 'mock-objects'
3
4
  require 'soks-storage'
4
5
 
5
- class MockWiki
6
- include WikiFlatFileStore
6
+ module TestMod
7
+ class TestClass
8
+ def initialize(stuff)
9
+ @stuff = stuff
10
+ end
11
+ end
12
+ end
13
+
14
+ class TestWikiCacheStore < Test::Unit::TestCase
15
+ include WikiCacheStore
16
+ include TearDownableWiki
17
+
18
+ def setup
19
+ @cache_folder = folder
20
+ end
7
21
 
8
- def initialize( folder )
9
- @folder = folder
10
- @pages = {}
22
+ def test_no_cache
23
+ @cache_folder = nil
24
+ save_cache( :test, "test class" )
25
+ assert_equal( [], files )
26
+ assert_equal( nil, load_cache( :test ) )
11
27
  end
12
28
 
13
- def mutate( pagename )
14
- p yield( @pages[pagename.downcase] ||= Page.new( pagename ) )
29
+ def test_cache
30
+ save_cache( :test, "test class" )
31
+ assert_equal( ['test.marshal'], files )
32
+ assert_equal( "test class", load_cache( :test ) )
33
+ assert_equal( [], files ) # Caches deleted on load
34
+ assert_equal( nil, load_cache( :test ) )
15
35
  end
16
36
  end
17
37
 
18
38
  class TestWikiFlatFileStore < Test::Unit::TestCase
19
- include FileUtils
39
+ include TearDownableWiki
20
40
 
21
- def setup
22
- @wiki = MockWiki.new(folder)
23
- end
24
-
25
- def test_rename
41
+ def test_rename_if_not_url_encoded
26
42
  create_file 'a handy file.textile', 'hello world'
27
43
  assert_equal( ['a handy file.textile'], files )
28
44
  @wiki.move_files_if_names_are_not_url_encoded
@@ -33,37 +49,60 @@ class TestWikiFlatFileStore < Test::Unit::TestCase
33
49
  create_file 'a&b.textile', 'hello world'
34
50
  assert_equal( ['a&b.textile'], files )
35
51
  @wiki.move_files_if_names_are_not_url_encoded
36
- assert_equal( ['ab.textile'], files )
52
+ assert_equal( ['a%26b.textile'], files )
37
53
  end
38
54
 
39
55
  def test_avoid_overwriting_on_rename
40
56
  create_file 'a&b.textile', 'hello world'
41
- create_file 'ab.textile', 'hello world'
42
- assert_equal( ['a&b.textile','ab.textile'], files )
57
+ create_file 'a%26b.textile', 'hello world'
58
+ assert_equal( ['a%26b.textile','a&b.textile'], files )
43
59
  @wiki.move_files_if_names_are_not_url_encoded
44
- assert_equal( ['ab.textile','ab1.textile'], files )
60
+ assert_equal( ['a%26b.textile','a%26b1.textile'], files )
45
61
  end
46
62
 
47
- def teardown
48
- rmtree( folder )
63
+ def test_rename_on_caps_change
64
+ create_file 'Hello%20World.textile', 'hello world'
65
+ create_file 'Hello%20World.yaml', 'hello world'
66
+ assert_equal( ['Hello%20World.textile', 'Hello%20World.yaml'], files)
67
+ @wiki.move_files_for_page( 'Hello World', 'hello world' )
68
+ assert_equal( ['hello%20world.textile','hello%20world.yaml'], files)
49
69
  end
50
-
51
- private
52
70
 
53
- def create_file( name, content )
54
- File.open( File.join( folder, name ), 'w') { |f| f.puts content }
71
+ def test_delete_files_for_page
72
+ create_file 'Hello%20World.textile', 'hello world'
73
+ create_file 'Hello%20World.yaml', 'hello world'
74
+ assert_equal( ['Hello%20World.textile', 'Hello%20World.yaml'], files)
75
+ @wiki.delete_files_for_page( 'Hello World')
76
+ assert_equal( [], files)
55
77
  end
56
78
 
57
- def files
58
- Dir.entries( folder ).delete_if { |name| name =~ /^\.+$/ }
79
+ def test_write_all_revisions
80
+ 1.upto(5) do |i|
81
+ @wiki.revise('test page',"#{i}","test author")
82
+ end
83
+
84
+ page = @wiki.page('test page')
85
+ assert_equal( 5, page.revisions.size )
86
+
87
+ revisions = @wiki.load_revisions( page )
88
+ assert_equal( 5, revisions.size )
89
+
90
+ page.revisions = [ [0,[[[0,'+','5']]],'test author',Time.now] ]
91
+ assert_equal( 1, page.revisions.size )
92
+ @wiki.revise('test page','extra revision', 'second author')
93
+ assert_equal( 2, page.revisions.size )
94
+ assert_equal( 5, @wiki.load_revisions( page ).size )
95
+
96
+ @wiki.save_all_revisions( page )
97
+ revisions = @wiki.load_revisions( page )
98
+ assert_equal( 2, revisions.size )
99
+ assert_equal( 'second author', revisions[1].author )
59
100
  end
60
101
 
61
- def folder
62
- @folder ||= make_folder
63
- end
102
+ private
64
103
 
65
- def make_folder
66
- mkdir( 'testcontent' )
67
- 'testcontent'
104
+ def create_file( name, content )
105
+ File.open( File.join( folder, name ), 'w') { |f| f.puts content }
68
106
  end
107
+
69
108
  end
@@ -37,7 +37,7 @@ class ToTimeUnitsMT < Test::Unit::TestCase
37
37
  end
38
38
  end
39
39
 
40
- class TimeSameDay < Test::Unit::TestCase
40
+ class TimeSameDayTest < Test::Unit::TestCase
41
41
 
42
42
  def test_simple
43
43
  other_day = Time.local(2005,04,01,9,30)
@@ -53,18 +53,18 @@ class TimeSameDay < Test::Unit::TestCase
53
53
  end
54
54
  end
55
55
 
56
- class StringToValidPageName < Test::Unit::TestCase
57
-
58
- def test_punctuation
59
- assert_equal( 'abcdefghijklm', 'a/b\\c[d]e?f{g}h&i^j`k<l>m'.to_valid_pagename )
60
- end
61
-
62
- def test_trailing_space
63
- assert_equal( 'abcdefghijklm', ' abcdefghijklm '.to_valid_pagename )
64
- end
65
- end
56
+ #class StringToValidPageNameTest < Test::Unit::TestCase
57
+ #
58
+ # def test_punctuation
59
+ # assert_equal( 'abcdefghijklm', 'a/b\\c[d]e?f{g}h&i^j`k<l>m'.to_valid_pagename )
60
+ # end
61
+ #
62
+ # def test_trailing_space
63
+ # assert_equal( 'abcdefghijklm', ' abcdefghijklm '.to_valid_pagename )
64
+ # end
65
+ #end
66
66
 
67
- class FileUniqueFilename < Test::Unit::TestCase
67
+ class FileUniqueFilenameTest < Test::Unit::TestCase
68
68
  include FileUtils
69
69
 
70
70
  def teardown
@@ -118,4 +118,103 @@ class FileUniqueFilename < Test::Unit::TestCase
118
118
  'testcontent'
119
119
  end
120
120
 
121
- end
121
+ end
122
+
123
+ class TimeNextText < Test::Unit::TestCase
124
+
125
+ def test_next_second
126
+ assert_equal( Time.local(2004,12,31,23,0,1), Time.local(2004,12,31,23,0,0).next(:sec) )
127
+ assert_equal( Time.local(2005,1,1), Time.local(2004,12,31,23,59,59).next(:sec) )
128
+ end
129
+
130
+ def test_next_minute
131
+ assert_equal( Time.local(2004,12,31,23,1), Time.local(2004,12,31,23,0).next(:min) )
132
+ assert_equal( Time.local(2005,1,1), Time.local(2004,12,31,23,59).next(:min) )
133
+ end
134
+
135
+ def test_next_hour
136
+ assert_equal( Time.local(2004,12,31,23,0), Time.local(2004,12,31,22,59).next(:hour) )
137
+ assert_equal( Time.local(2005,1,1), Time.local(2004,12,31,23).next(:hour) )
138
+ end
139
+
140
+ def test_next_day
141
+ assert_equal( Time.local(2004,12,31,0,0), Time.local(2004,12,30,22,00).next(:day) )
142
+ assert_equal( Time.local(2005,1,1), Time.local(2004,12,31,23).next(:day) )
143
+ end
144
+
145
+ def test_next_month
146
+ assert_equal( Time.local(2004,12), Time.local(2004,11,30,22,00).next(:month) )
147
+ assert_equal( Time.local(2005,1,1), Time.local(2004,12,31,23).next(:month) )
148
+ assert_equal( Time.local(2005,2,1), Time.local(2005,1,31).next(:month) )
149
+ assert_equal( Time.local(2005,2), Time.local(2005,1).next(:month) )
150
+ end
151
+
152
+ def test_next_year
153
+ assert_equal( Time.local(2005), Time.local(2004,11,30,22,00).next(:year) )
154
+ assert_equal( Time.local(2005,1,1), Time.local(2004,12,31,23).next(:year) )
155
+ assert_equal( Time.local(2006), Time.local(2005).next(:year) )
156
+ end
157
+
158
+ end
159
+
160
+ class DaysFromTest < Test::Unit::TestCase
161
+
162
+ def test_days_from
163
+ t1 = Time.local( 2005,01,01,19,27)
164
+ assert_equal(0, t1.days_from( t1 ) )
165
+ assert_equal(-1, t1.days_from( Time.local( 2005,01,02 ) ) )
166
+ assert_equal(1, t1.days_from( Time.local( 2004,12,31 ) ) )
167
+ end
168
+
169
+ end
170
+
171
+ class RelativeDayTest < Test::Unit::TestCase
172
+
173
+ def test_today
174
+ assert_equal("Today", Time.now.relative_day )
175
+ end
176
+
177
+ def test_yesterday
178
+ assert_equal(-1, (Time.now-24*60*60).days_from( Time.now ) )
179
+ assert_equal("Yesterday", (Time.now-24*60*60).relative_day)
180
+ end
181
+
182
+ def test_some_time_ago
183
+ some_time_ago = Time.now - (10*24*60*60)
184
+ assert_equal(some_time_ago.strftime('%d %b'), some_time_ago.relative_day)
185
+ end
186
+
187
+ def test_long_time_ago
188
+ some_time_ago = Time.now - (400*24*60*60)
189
+ assert_equal(some_time_ago.strftime('%d %b %Y'), some_time_ago.relative_day)
190
+ end
191
+
192
+ end
193
+
194
+ class PeriodicNotificationTest < Test::Unit::TestCase
195
+
196
+ def test_seconds
197
+ time_at_last_call = Time.now
198
+ total_time_between_calls = 0
199
+ total_number_of_calls = 0
200
+ PeriodicNotification.new(:second) do |period|
201
+ total_time_between_calls = total_time_between_calls + (Time.now - time_at_last_call)
202
+ time_at_last_call = Time.now
203
+ total_number_of_calls += 1
204
+ end
205
+ sleep( 3 )
206
+ assert_equal( 3, total_number_of_calls )
207
+ assert_equal( 1, (total_time_between_calls/total_number_of_calls).round )
208
+ end
209
+
210
+ end
211
+
212
+ class StringDiffsTest < Test::Unit::TestCase
213
+
214
+ def test_simple
215
+ version_one = "A\nB\nC\n"
216
+ version_two = "A\nC\nC\n"
217
+ assert_equal( [[['-',1,'B'],['+',1,'C']]], version_two.changes_from( version_one ) )
218
+ end
219
+
220
+ end