Soks 0.0.7 → 1.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 (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