gf-Soks 1.0.4
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.
- data/LICENSE.txt +66 -0
- data/README.txt +64 -0
- data/bin/soks-create-wiki.rb +193 -0
- data/contrib/diff/lcs.rb +1105 -0
- data/contrib/diff/lcs/array.rb +21 -0
- data/contrib/diff/lcs/block.rb +51 -0
- data/contrib/diff/lcs/callbacks.rb +322 -0
- data/contrib/diff/lcs/change.rb +169 -0
- data/contrib/diff/lcs/hunk.rb +257 -0
- data/contrib/diff/lcs/ldiff.rb +226 -0
- data/contrib/diff/lcs/string.rb +19 -0
- data/contrib/diff_licence.txt +76 -0
- data/contrib/easyprompt.rb +58 -0
- data/contrib/easyprompt_licence.txt +504 -0
- data/contrib/redcloth-3.0.3.rb +1113 -0
- data/contrib/redcloth_license.txt +27 -0
- data/lib/authenticators.rb +121 -0
- data/lib/helpers/counter-helpers.rb +132 -0
- data/lib/helpers/default-helpers.rb +416 -0
- data/lib/helpers/mail2wiki-helper.rb +105 -0
- data/lib/helpers/maintenance-helpers.rb +149 -0
- data/lib/helpers/rss2wiki-helper.rb +47 -0
- data/lib/helpers/wiki2html.rb +60 -0
- data/lib/soks-model.rb +271 -0
- data/lib/soks-servlet.rb +177 -0
- data/lib/soks-storage.rb +187 -0
- data/lib/soks-upgrade-0.0.2.rb +70 -0
- data/lib/soks-utils.rb +327 -0
- data/lib/soks-view.rb +399 -0
- data/lib/soks.rb +27 -0
- data/rakefile +109 -0
- data/templates/default/attachment/favicon.ico +0 -0
- data/templates/default/attachment/logo.jpg +0 -0
- data/templates/default/attachment/logo.png +0 -0
- data/templates/default/attachment/logo.tiff +0 -0
- data/templates/default/attachment/newpage.js +41 -0
- data/templates/default/attachment/print_stylesheet.css +2 -0
- data/templates/default/attachment/robots.txt +6 -0
- data/templates/default/attachment/rss.png +0 -0
- data/templates/default/attachment/stylesheet.css +219 -0
- data/templates/default/banned_titles.txt +67 -0
- data/templates/default/caches/readme.txt +1 -0
- data/templates/default/content/Api%20for%20classes%20to%20modify%20the%20wiki.textile +30 -0
- data/templates/default/content/Author.textile +16 -0
- data/templates/default/content/Automatic%20Summaries.textile +40 -0
- data/templates/default/content/Automatic%20counters.textile +22 -0
- data/templates/default/content/Automatic%20exporters.textile +23 -0
- data/templates/default/content/Automatic%20importers.textile +59 -0
- data/templates/default/content/Automatic%20linking.textile +7 -0
- data/templates/default/content/Automatic%20maintenance%20helpers.textile +39 -0
- data/templates/default/content/Bug%3A%20Competing%20edits.textile +22 -0
- data/templates/default/content/Bug%3A%20Does%20not%20make%20use%20of%20if%2Dmodified%2Dsince%20r.textile +3 -0
- data/templates/default/content/Bug%3A%20Email%20adresses%20in%20page%20titles%20cause%20incorrec.textile +3 -0
- data/templates/default/content/Bug%3A%20GEM%20limits%20title%20lengths.textile +3 -0
- data/templates/default/content/Bug%3A%20Memory%20leak.textile +13 -0
- data/templates/default/content/Bug%3A%20Page%2Einserted%5Finto%20is%20never%20purged.textile +17 -0
- data/templates/default/content/Bug%3A%20Pages%20that%20link%20here%20may%20not%20appear%20on%20r.textile +13 -0
- data/templates/default/content/Bug%3A%20Textile%20mishandles%20paragraphs.textile +37 -0
- data/templates/default/content/Bug%3A%20Unanticipated%20Rollbacks.textile +23 -0
- data/templates/default/content/Bug%3A%20notextile%20does%20not%20prevent%20page%20inserts.textile +3 -0
- data/templates/default/content/Home%20Page.textile +22 -0
- data/templates/default/content/How%20to%20administrate%20this%20wiki.textile +57 -0
- data/templates/default/content/How%20to%20change%20the%20way%20this%20wiki%20looks.textile +32 -0
- data/templates/default/content/How%20to%20export%20a%20site%20from%20this%20wiki.textile +82 -0
- data/templates/default/content/How%20to%20get%20the%20latest%20Soks%20from%20cvs.textile +45 -0
- data/templates/default/content/How%20to%20hack%20soks.textile +66 -0
- data/templates/default/content/How%20to%20import%20a%20site%20from%20instiki.textile +15 -0
- data/templates/default/content/How%20to%20import%20data.textile +41 -0
- data/templates/default/content/How%20to%20install%20Soks.textile +33 -0
- data/templates/default/content/How%20to%20password%20protect%20your%20wiki.textile +53 -0
- data/templates/default/content/How%20to%20re%2Dbuild%20the%20page%20cache.textile +71 -0
- data/templates/default/content/How%20to%20report%20a%20bug.textile +9 -0
- data/templates/default/content/How%20to%20upgrade%20soks.textile +32 -0
- data/templates/default/content/How%20to%20use%20the%20Automatic%20Helper%20classes.textile +12 -0
- data/templates/default/content/How%20to%20use%20this%20wiki.textile +30 -0
- data/templates/default/content/List%20of%20changes.textile +10 -0
- data/templates/default/content/News%3A%20Version%201%2D0%2D0%20released.textile +19 -0
- data/templates/default/content/News%3A%20Version%201%2D0%2D1%20released.textile +12 -0
- data/templates/default/content/Pages%20to%20include%20in%20the%20distribution.textile +55 -0
- data/templates/default/content/Per%20Wiki%20Templates.textile +37 -0
- data/templates/default/content/Picture%20of%20a%20pair%20of%20soks.textile +1 -0
- data/templates/default/content/Planned%20Features.textile +74 -0
- data/templates/default/content/README.textile +64 -0
- data/templates/default/content/RSS%20feed.textile +9 -0
- data/templates/default/content/Recent%20changes%20to%20this%20site.textile +352 -0
- data/templates/default/content/SOKS%20features.textile +19 -0
- data/templates/default/content/Sidebar%20Page.textile +6 -0
- data/templates/default/content/Site%20Index.textile +241 -0
- data/templates/default/content/Soks%27s%20Licence.textile +66 -0
- data/templates/default/content/Tag%3A%20Include%20this%20page%20in%20the%20distribution.textile +6 -0
- data/templates/default/start.rb +90 -0
- data/templates/default/version.txt +1 -0
- data/templates/default/views/Page_content.rhtml +1 -0
- data/templates/default/views/Page_edit.rhtml +79 -0
- data/templates/default/views/Page_find.rhtml +35 -0
- data/templates/default/views/Page_linksfromrss.rhtml +24 -0
- data/templates/default/views/Page_listrss.rhtml +46 -0
- data/templates/default/views/Page_meta.rhtml +44 -0
- data/templates/default/views/Page_print.rhtml +6 -0
- data/templates/default/views/Page_revision.rhtml +39 -0
- data/templates/default/views/Page_revisions.rhtml +36 -0
- data/templates/default/views/Page_rss.rhtml +57 -0
- data/templates/default/views/Page_view.rhtml +8 -0
- data/templates/default/views/UploadPage_edit.rhtml +63 -0
- data/templates/default/views/frame.rhtml +63 -0
- data/templates/default/views/messages.yaml +7 -0
- data/test/html/2006Mar.html +66 -0
- data/test/html/poignant.html +36 -0
- data/test/html/poignant.textile +36 -0
- data/test/mock-objects.rb +69 -0
- data/test/test_counter-helper.rb +162 -0
- data/test/test_soks-helper-maintenance.rb +106 -0
- data/test/test_soks-helpers.rb +145 -0
- data/test/test_soks-model.rb +144 -0
- data/test/test_soks-servlet.rb +240 -0
- data/test/test_soks-storage.rb +108 -0
- data/test/test_soks-utils.rb +226 -0
- data/test/test_soks-view.rb +193 -0
- data/test/test_soks.rb +9 -0
- metadata +182 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<h3>False</h3>
|
|
2
|
+
|
|
3
|
+
<p style="float:left"><img src="i/blix-neg.gif" title="Shape of a cat." alt="Shape of a cat." /></p>
|
|
4
|
+
|
|
5
|
+
<p><em>The cat Trady Blix. Frozen in emptiness. Immaculate whiskers rigid. Placid eyes of lake. Tail of warm icicle. Sponsored by a Very Powerful Pause Button.</em></p>
|
|
6
|
+
|
|
7
|
+
<p>The darkness surrounding Blix can be called <strong>negative space</strong>. Hang on to that phrase. Let it suggest that the emptiness has a negative connotation. In a similar way, <code>nil</code> has a slightly sour note that it whistles.</p>
|
|
8
|
+
|
|
9
|
+
<p>Generally speaking, everything in Ruby has a positive charge to it. This spark flows through strings, numbers, regexps, all of it. Only two keywords wear a shady cloak: <code>nil</code> and <code>false</code> draggin us down.</p>
|
|
10
|
+
|
|
11
|
+
<p>You can test that charge with an <code>if</code> keyword. It looks very much like the <code>do</code> blocks we saw in the last chapter, in that both end with an <code>end</code>.</p>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<pre>
|
|
15
|
+
if plastic_cup
|
|
16
|
+
print "Plastic cup is on the up 'n' up!"
|
|
17
|
+
end
|
|
18
|
+
</pre>
|
|
19
|
+
<p>If <code>plastic_cup</code> contains either <code>nil</code> or <code>false</code>, you won’t see anything print to the screen. They’re not on the <code>if</code> guest list. So <code>if</code> isn’t going to run any of the code it’s protecting.</p>
|
|
20
|
+
|
|
21
|
+
<p>But <code>nil</code> and <code>false</code> need not walk away in shame. They may be of questionable character, but <code>unless</code> runs a smaller establishment that caters to the bedraggled. The <code>unless</code> keyword has a policy of only allowing those with a negative charge in. Who are: <code>nil</code> and <code>false</code>.</p>
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
<pre>
|
|
25
|
+
unless plastic_cup
|
|
26
|
+
print "Plastic cup is on the down low."
|
|
27
|
+
end
|
|
28
|
+
</pre>
|
|
29
|
+
<p>You can also use <code>if</code> and <code>unless</code> at the end of a single line of code, if that’s all that is being protected.</p>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<pre>
|
|
33
|
+
print "Yeah, plastic cup is up again!" if plastic_cup
|
|
34
|
+
print "Hardly. It's down." unless plastic_cup
|
|
35
|
+
</pre>
|
|
36
|
+
<p>Now that you’ve met <code>false</code>, I’m sure you can see what’s on next.</p>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
h3. False
|
|
2
|
+
|
|
3
|
+
!<i/blix-neg.gif(Shape of a cat.)!
|
|
4
|
+
|
|
5
|
+
_The cat Trady Blix. Frozen in emptiness. Immaculate whiskers rigid. Placid eyes of lake. Tail of warm icicle. Sponsored by a Very Powerful Pause Button._
|
|
6
|
+
|
|
7
|
+
The darkness surrounding Blix can be called *negative space*. Hang on to that phrase. Let it suggest that the emptiness has a negative connotation. In a similar way, @nil@ has a slightly sour note that it whistles.
|
|
8
|
+
|
|
9
|
+
Generally speaking, everything in Ruby has a positive charge to it. This spark flows through strings, numbers, regexps, all of it. Only two keywords wear a shady cloak: @nil@ and @false@ draggin us down.
|
|
10
|
+
|
|
11
|
+
You can test that charge with an @if@ keyword. It looks very much like the @do@ blocks we saw in the last chapter, in that both end with an @end@.
|
|
12
|
+
|
|
13
|
+
<pre>
|
|
14
|
+
if plastic_cup
|
|
15
|
+
print "Plastic cup is on the up 'n' up!"
|
|
16
|
+
end
|
|
17
|
+
</pre>
|
|
18
|
+
|
|
19
|
+
If @plastic_cup@ contains either @nil@ or @false@, you won't see anything print to the screen. They're not on the @if@ guest list. So @if@ isn't going to run any of the code it's protecting.
|
|
20
|
+
|
|
21
|
+
But @nil@ and @false@ need not walk away in shame. They may be of questionable character, but @unless@ runs a smaller establishment that caters to the bedraggled. The @unless@ keyword has a policy of only allowing those with a negative charge in. Who are: @nil@ and @false@.
|
|
22
|
+
|
|
23
|
+
<pre>
|
|
24
|
+
unless plastic_cup
|
|
25
|
+
print "Plastic cup is on the down low."
|
|
26
|
+
end
|
|
27
|
+
</pre>
|
|
28
|
+
|
|
29
|
+
You can also use @if@ and @unless@ at the end of a single line of code, if that's all that is being protected.
|
|
30
|
+
|
|
31
|
+
<pre>
|
|
32
|
+
print "Yeah, plastic cup is up again!" if plastic_cup
|
|
33
|
+
print "Hardly. It's down." unless plastic_cup
|
|
34
|
+
</pre>
|
|
35
|
+
|
|
36
|
+
Now that you've met @false@, I'm sure you can see what's on next.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
$:.unshift( "contrib" )
|
|
2
|
+
|
|
3
|
+
require 'yaml'
|
|
4
|
+
$MESSAGES = YAML.load( IO.readlines("templates/default/views/messages.yaml").join )
|
|
5
|
+
|
|
6
|
+
require 'logger'
|
|
7
|
+
$LOG = Logger.new(STDOUT)
|
|
8
|
+
$LOG.level = Logger::WARN
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
require 'rubygems'
|
|
12
|
+
require_gem 'ruby-breakpoint'
|
|
13
|
+
rescue LoadError
|
|
14
|
+
$LOG.info "Breakpoint library not found. Shouldn't matter"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
require 'fileutils'
|
|
18
|
+
require 'soks'
|
|
19
|
+
|
|
20
|
+
class MockWikiStore
|
|
21
|
+
include WikiFlatFileStore
|
|
22
|
+
|
|
23
|
+
def initialize( folder )
|
|
24
|
+
@folder = folder
|
|
25
|
+
@pages = {}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def mutate( pagename )
|
|
29
|
+
p yield( @pages[pagename.downcase] ||= Page.new( pagename ) )
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module TearDownableWiki
|
|
34
|
+
include FileUtils
|
|
35
|
+
|
|
36
|
+
def setup
|
|
37
|
+
@wiki = Wiki.new( folder )
|
|
38
|
+
@view = View.new( @wiki, 'http://testsite.com','testcontent/views' )
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def teardown
|
|
42
|
+
rmtree( folder )
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def create_file( name, content )
|
|
48
|
+
File.open( File.join( folder, name ), 'w') { |f| f.puts content }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def files
|
|
52
|
+
Dir.entries( folder ).delete_if { |name| name =~ /^(\.+|attachment|views)$/ }.sort
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def folder
|
|
56
|
+
@folder ||= make_folder
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def make_folder
|
|
60
|
+
mkdir( 'testcontent' )
|
|
61
|
+
mkdir('testcontent/attachment')
|
|
62
|
+
File.symlink(File.join(Dir.getwd,'templates/default/views'),'testcontent/views')
|
|
63
|
+
'testcontent'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def wait_for_queue_to_empty
|
|
67
|
+
sleep(0.1) until @wiki.event_queue.empty?
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'mock-objects'
|
|
4
|
+
require 'generator'
|
|
5
|
+
require 'helpers/counter-helpers'
|
|
6
|
+
|
|
7
|
+
class TestViewCountHelper < Test::Unit::TestCase
|
|
8
|
+
include TearDownableWiki
|
|
9
|
+
|
|
10
|
+
def test_notification
|
|
11
|
+
results = []
|
|
12
|
+
@wiki.watch_for(:page_viewed) { |*results| }
|
|
13
|
+
@view.render( 'test-page','view','test-viewer')
|
|
14
|
+
wait_for_queue_to_empty
|
|
15
|
+
assert_equal( :page_viewed, results[0] )
|
|
16
|
+
assert_equal( 'test-page', results[1].name )
|
|
17
|
+
assert_equal( 'view', results[2] )
|
|
18
|
+
assert_equal( 'test-viewer', results[3] )
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_total_count
|
|
22
|
+
count = ViewCountHelper.new(@wiki).counts
|
|
23
|
+
@view.render( 'test-page','view','test-viewer')
|
|
24
|
+
@view.render( 'test-page','view','test-viewer')
|
|
25
|
+
@view.render( 'test-page','view','test-viewer')
|
|
26
|
+
wait_for_queue_to_empty
|
|
27
|
+
assert_equal( 3, count.total )
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_page_count
|
|
31
|
+
count = ViewCountHelper.new(@wiki, ['view'], 'Popular Pages', :test_event, 2 ).counts
|
|
32
|
+
@wiki.revise( 'count1','1','t1')
|
|
33
|
+
@wiki.revise( 'count2','2','t2')
|
|
34
|
+
@wiki.revise( 'count3','3','t3')
|
|
35
|
+
3.times { @view.render( 'count1' ) }
|
|
36
|
+
3.times { @view.render( 'count1', 'edit' ) }
|
|
37
|
+
2.times { @view.render( 'count2' ) }
|
|
38
|
+
1.times { @view.render( 'count3' ) }
|
|
39
|
+
wait_for_queue_to_empty
|
|
40
|
+
p1,p2,p3 = @wiki.page('count1'), @wiki.page('count2'), @wiki.page('count3')
|
|
41
|
+
assert_equal( 3, count[p1.name] )
|
|
42
|
+
assert_equal( 2, count[p2.name] )
|
|
43
|
+
assert_equal( 1, count[p3.name] )
|
|
44
|
+
assert_equal( 6, count.total )
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_page_render
|
|
48
|
+
start_time = Time.now
|
|
49
|
+
test_page_count
|
|
50
|
+
@wiki.notify( :test_event )
|
|
51
|
+
wait_for_queue_to_empty
|
|
52
|
+
content = @wiki.page('Popular Pages').content.split "\n"
|
|
53
|
+
[ [ 0, "h1. Popular Pages" ],
|
|
54
|
+
[ 4, "| count1 | 3 |" ],
|
|
55
|
+
[ 5, "| count2 | 2 |" ],
|
|
56
|
+
[ 6, "| 1 others | 1 |" ],
|
|
57
|
+
[ 7, "| *Total* | *6* |" ] ].each do |i,line|
|
|
58
|
+
assert_equal line, content[i]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class TestViewerCountHelper < Test::Unit::TestCase
|
|
65
|
+
include TearDownableWiki
|
|
66
|
+
|
|
67
|
+
def test_notification
|
|
68
|
+
results = []
|
|
69
|
+
@wiki.watch_for(:page_viewed) { |*results| }
|
|
70
|
+
@view.render( 'test-page','view','test-viewer')
|
|
71
|
+
wait_for_queue_to_empty
|
|
72
|
+
assert_equal( :page_viewed, results[0] )
|
|
73
|
+
assert_equal( 'test-page', results[1].name )
|
|
74
|
+
assert_equal( 'view', results[2] )
|
|
75
|
+
assert_equal( 'test-viewer', results[3] )
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_total_count
|
|
79
|
+
count = ViewerCountHelper.new(@wiki).counts
|
|
80
|
+
@view.render( 'test-page','view','test-viewer')
|
|
81
|
+
@view.render( 'test-page','view','test-viewer')
|
|
82
|
+
@view.render( 'test-page','view','test-viewer')
|
|
83
|
+
wait_for_queue_to_empty
|
|
84
|
+
assert_equal( 3, count.total )
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_viewer_count
|
|
88
|
+
count = ViewerCountHelper.new(@wiki, ['view'], 'Popular Pages', :test_event, 2 ).counts
|
|
89
|
+
@wiki.revise( 'count1','1','t1')
|
|
90
|
+
@wiki.revise( 'count2','2','t2')
|
|
91
|
+
@wiki.revise( 'count3','3','t3')
|
|
92
|
+
3.times { @view.render( 'count1', 'view', "Author1" ) }
|
|
93
|
+
3.times { @view.render( 'count1', 'edit', "Author1" ) }
|
|
94
|
+
2.times { @view.render( 'count2', 'view', "Author2" ) }
|
|
95
|
+
1.times { @view.render( 'count3', 'view', "Author3" ) }
|
|
96
|
+
wait_for_queue_to_empty
|
|
97
|
+
assert_equal( 3, count['Author1'] )
|
|
98
|
+
assert_equal( 2, count['Author2'] )
|
|
99
|
+
assert_equal( 1, count['Author3'] )
|
|
100
|
+
assert_equal( 6, count.total )
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_page_render
|
|
104
|
+
start_time = Time.now
|
|
105
|
+
test_viewer_count
|
|
106
|
+
@wiki.notify( :test_event )
|
|
107
|
+
wait_for_queue_to_empty
|
|
108
|
+
content = @wiki.page('Popular Pages').content.split "\n"
|
|
109
|
+
[ [ 0, "h1. Popular Pages" ],
|
|
110
|
+
[ 4, "| Author1 | 3 |" ],
|
|
111
|
+
[ 5, "| Author2 | 2 |" ],
|
|
112
|
+
[ 6, "| 1 others | 1 |" ],
|
|
113
|
+
[ 7, "| *Total* | *6* |" ] ].each do |i,line|
|
|
114
|
+
assert_equal line, content[i]
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class TestAuthorCountHelper < Test::Unit::TestCase
|
|
121
|
+
include TearDownableWiki
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def test_total_count
|
|
125
|
+
count = AuthorCountHelper.new(@wiki,'Principal Authors', :test_event, 2 ).counts
|
|
126
|
+
@wiki.revise( 'count1','1','t1')
|
|
127
|
+
@wiki.revise( 'count2','2','t2')
|
|
128
|
+
@wiki.revise( 'count3','3','t3')
|
|
129
|
+
wait_for_queue_to_empty
|
|
130
|
+
assert_equal( 3, count.total )
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_author_count
|
|
134
|
+
count = AuthorCountHelper.new(@wiki,'Principal Authors', :test_event, 2 ).counts
|
|
135
|
+
@wiki.revise( 'count1','1','t1')
|
|
136
|
+
@wiki.revise( 'count2','1','t1')
|
|
137
|
+
@wiki.revise( 'count2','2','t2')
|
|
138
|
+
@wiki.revise( 'count3','1','t1')
|
|
139
|
+
@wiki.revise( 'count3','2','t2')
|
|
140
|
+
@wiki.revise( 'count3','3','t3')
|
|
141
|
+
wait_for_queue_to_empty
|
|
142
|
+
assert_equal( 3, count['t1'] )
|
|
143
|
+
assert_equal( 2, count['t2'] )
|
|
144
|
+
assert_equal( 1, count['t3'] )
|
|
145
|
+
assert_equal( 6, count.total )
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def test_page_render
|
|
149
|
+
start_time = Time.now
|
|
150
|
+
test_author_count
|
|
151
|
+
@wiki.notify( :test_event )
|
|
152
|
+
wait_for_queue_to_empty
|
|
153
|
+
content = @wiki.page('Principal Authors').content.split "\n"
|
|
154
|
+
[ [ 0, "h1. Principal Authors" ],
|
|
155
|
+
[ 4, "| t1 | 3 |" ],
|
|
156
|
+
[ 5, "| t2 | 2 |" ],
|
|
157
|
+
[ 6, "| 1 others | 1 |" ],
|
|
158
|
+
[ 7, "| *Total* | *6* |" ] ].each do |i,line|
|
|
159
|
+
assert_equal line, content[i]
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'mock-objects'
|
|
3
|
+
require 'helpers/maintenance-helpers'
|
|
4
|
+
|
|
5
|
+
class TestDeleteOldPages < Test::Unit::TestCase
|
|
6
|
+
include TearDownableWiki
|
|
7
|
+
|
|
8
|
+
def setup
|
|
9
|
+
super
|
|
10
|
+
DeleteOldPagesHelper.new( @wiki, :an_event, 2 )
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def test_delete_old_pages
|
|
14
|
+
assert_equal([],files)
|
|
15
|
+
@wiki.revise( 'home page', 'hello world', 'tamc2')
|
|
16
|
+
assert_equal( true, @wiki.exists?('home page') )
|
|
17
|
+
assert_equal( false, @wiki.page('home page').deleted? )
|
|
18
|
+
assert_equal(['home%20page.textile','home%20page.yaml'],files)
|
|
19
|
+
|
|
20
|
+
@wiki.delete( 'home page', 'tamc2')
|
|
21
|
+
@wiki.notify(:an_event )
|
|
22
|
+
wait_for_queue_to_empty
|
|
23
|
+
|
|
24
|
+
# Should be too soon
|
|
25
|
+
assert_equal( false, @wiki.exists?('home page') )
|
|
26
|
+
assert_equal( true, @wiki.page('home page').deleted? )
|
|
27
|
+
assert_equal(['home%20page.textile','home%20page.yaml'],files)
|
|
28
|
+
|
|
29
|
+
sleep( 2 )
|
|
30
|
+
@wiki.notify(:an_event )
|
|
31
|
+
wait_for_queue_to_empty
|
|
32
|
+
|
|
33
|
+
# Should now have deleted
|
|
34
|
+
assert_equal( false, @wiki.exists?('home page') )
|
|
35
|
+
assert_equal( false, @wiki.page('home page').deleted? )
|
|
36
|
+
assert_equal([],files)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class TestDeleteOldRevisions < Test::Unit::TestCase
|
|
42
|
+
include TearDownableWiki
|
|
43
|
+
|
|
44
|
+
def setup
|
|
45
|
+
super
|
|
46
|
+
DeleteOldRevisionsHelper.new( @wiki, :an_event, 2, 2)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_delete_old_revisions
|
|
50
|
+
1.upto(5) do |i|
|
|
51
|
+
@wiki.revise('revision delete test page',"#{i}","test author")
|
|
52
|
+
end
|
|
53
|
+
page = @wiki.page('revision delete test page')
|
|
54
|
+
assert_equal(5,page.revisions.size)
|
|
55
|
+
|
|
56
|
+
@wiki.notify(:an_event )
|
|
57
|
+
wait_for_queue_to_empty
|
|
58
|
+
|
|
59
|
+
# Should be too soon
|
|
60
|
+
assert_equal(5,page.revisions.size)
|
|
61
|
+
|
|
62
|
+
sleep( 2 )
|
|
63
|
+
@wiki.notify(:an_event )
|
|
64
|
+
wait_for_queue_to_empty
|
|
65
|
+
|
|
66
|
+
# Should now have turned last 3 revisions into one
|
|
67
|
+
assert_equal(3,page.revisions.size)
|
|
68
|
+
assert_equal('Automatic Revision Remover',page.revisions.first.author)
|
|
69
|
+
assert_equal('3',page.revisions.first.content)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class TestMergeOldRevisions < Test::Unit::TestCase
|
|
74
|
+
include TearDownableWiki
|
|
75
|
+
|
|
76
|
+
def setup
|
|
77
|
+
super
|
|
78
|
+
MergeOldRevisionsHelper.new( @wiki, :an_event, 2, 10)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_merge_old_revisions
|
|
82
|
+
1.upto(3) do |i|
|
|
83
|
+
@wiki.revise('revision merge test page',"#{i}","author1")
|
|
84
|
+
end
|
|
85
|
+
3.upto(5) do |i|
|
|
86
|
+
@wiki.revise('revision merge test page',"#{i}","author2")
|
|
87
|
+
end
|
|
88
|
+
page = @wiki.page('revision merge test page')
|
|
89
|
+
assert_equal(5,page.revisions.size)
|
|
90
|
+
|
|
91
|
+
@wiki.notify(:an_event )
|
|
92
|
+
wait_for_queue_to_empty
|
|
93
|
+
|
|
94
|
+
# Should be too soon
|
|
95
|
+
assert_equal(5,page.revisions.size)
|
|
96
|
+
|
|
97
|
+
sleep( 2 )
|
|
98
|
+
@wiki.notify(:an_event )
|
|
99
|
+
wait_for_queue_to_empty
|
|
100
|
+
|
|
101
|
+
# Should now have merged each author's revisions
|
|
102
|
+
assert_equal(2,page.revisions.size)
|
|
103
|
+
assert_equal('3',page.revision(0).content)
|
|
104
|
+
assert_equal('5',page.revision(1).content)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
require 'mock-objects'
|
|
4
|
+
require 'helpers/default-helpers'
|
|
5
|
+
require 'generator'
|
|
6
|
+
|
|
7
|
+
class TestAutomaticSummary < Test::Unit::TestCase
|
|
8
|
+
include TearDownableWiki
|
|
9
|
+
|
|
10
|
+
def test_basics
|
|
11
|
+
AutomaticSummary.new( @wiki, 'automatic summary' ) { |page| page.name =~ /hello/i }
|
|
12
|
+
@wiki.revise 'hello world', 'hello world', 'test author'
|
|
13
|
+
@wiki.revise 'hello john', 'hello john', 'test author'
|
|
14
|
+
@wiki.revise 'hello frank', 'hello frank', 'test author'
|
|
15
|
+
@wiki.revise 'hello frank', 'page deleted', 'test author'
|
|
16
|
+
@wiki.revise 'goodbye world', 'goodbye world', 'test author'
|
|
17
|
+
wait_for_queue_to_empty
|
|
18
|
+
content = @wiki.page('automatic summary').content
|
|
19
|
+
assert_match /hello world/, content
|
|
20
|
+
assert_match /hello john/, content
|
|
21
|
+
assert_no_match /goodbye world/, content
|
|
22
|
+
assert_no_match /hello frank/, content
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_updates_on_revision
|
|
26
|
+
as = AutomaticSummary.new( @wiki, 'update on revision test' ) { |page| page.name =~ /summarise/i }
|
|
27
|
+
@wiki.revise('summarise 1','initial content','test author')
|
|
28
|
+
wait_for_queue_to_empty
|
|
29
|
+
assert_match(/initial content/,@wiki.page('update on revision test').content )
|
|
30
|
+
@wiki.revise('summarise 1','updated content','test author')
|
|
31
|
+
wait_for_queue_to_empty
|
|
32
|
+
assert_match(/updated content/,@wiki.page('update on revision test').content )
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_removes_when_no_longer_true
|
|
36
|
+
AutomaticSummary.new( @wiki, 'remove when not true test' ) { |page| page.content =~ /hello/i }
|
|
37
|
+
@wiki.revise('summarise 1','hello','test author')
|
|
38
|
+
wait_for_queue_to_empty
|
|
39
|
+
assert_match(/hello/,@wiki.page('remove when not true test').content )
|
|
40
|
+
@wiki.revise('summarise 1','bye','test author')
|
|
41
|
+
wait_for_queue_to_empty
|
|
42
|
+
assert_no_match(/hello/,@wiki.page('remove when not true test').content )
|
|
43
|
+
assert_no_match(/bye/,@wiki.page('remove when not true test').content )
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class TestRecentChanges < Test::Unit::TestCase
|
|
49
|
+
include TearDownableWiki
|
|
50
|
+
|
|
51
|
+
def test_detect_change
|
|
52
|
+
rc = AutomaticRecentChanges.new( @wiki)
|
|
53
|
+
@wiki.revise( 'testpage','B','normal person')
|
|
54
|
+
@wiki.revise( 'testpage2','A','normal person')
|
|
55
|
+
wait_for_queue_to_empty
|
|
56
|
+
assert_equal(2, rc.summary.to_a.size)
|
|
57
|
+
assert_match( /normal person/i, rctextile )
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_merge_author_change
|
|
61
|
+
rc = AutomaticRecentChanges.new( @wiki)
|
|
62
|
+
@wiki.revise( 'testpage','B','normal person')
|
|
63
|
+
@wiki.revise( 'testpage','A','normal person')
|
|
64
|
+
wait_for_queue_to_empty
|
|
65
|
+
assert_equal(1, rc.summary.to_a.size)
|
|
66
|
+
assert_match( /normal person/i, rctextile )
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_dont_merge_different_authors_change
|
|
70
|
+
@rc = AutomaticRecentChanges.new( @wiki)
|
|
71
|
+
@wiki.revise( 'testpage','B','p1')
|
|
72
|
+
@wiki.revise( 'testpage','A','p2')
|
|
73
|
+
wait_for_queue_to_empty
|
|
74
|
+
assert_equal(2, @rc.summary.to_a.size)
|
|
75
|
+
assert_match( /p1/i, rctextile )
|
|
76
|
+
assert_match( /p2/i, rctextile )
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_exclude_helpers_initially
|
|
80
|
+
@wiki.revise( 'testpage','B','normal person')
|
|
81
|
+
@wiki.revise( 'testpage2','content moved from','AutomaticPageMover')
|
|
82
|
+
@wiki.revise( 'testpage2','A','normal person')
|
|
83
|
+
rc = AutomaticRecentChanges.new( @wiki)
|
|
84
|
+
assert_equal(['recent changes to this site','testpage','testpage2'],@wiki.map{|name,page| name }.sort)
|
|
85
|
+
assert_equal(2, rc.summary.to_a.size)
|
|
86
|
+
assert_match( /normal person/i, rctextile )
|
|
87
|
+
assert_no_match( /AutomaticPageMover/i, rctextile )
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_exclude_helpers_later
|
|
91
|
+
rc = AutomaticRecentChanges.new( @wiki)
|
|
92
|
+
@wiki.revise( 'testpage','B','normal person')
|
|
93
|
+
@wiki.revise( 'testpage2','content moved from','AutomaticPageMover')
|
|
94
|
+
@wiki.revise( 'testpage2','A','normal person')
|
|
95
|
+
wait_for_queue_to_empty
|
|
96
|
+
assert_equal(['recent changes to this site','testpage','testpage2'],@wiki.map{|name,page| name }.sort)
|
|
97
|
+
assert_equal(2, rc.summary.to_a.size)
|
|
98
|
+
assert_match( /normal person/i, rctextile )
|
|
99
|
+
assert_no_match( /AutomaticPageMover/i, rctextile )
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def test_change_in_page_capitalisation
|
|
103
|
+
rc = AutomaticRecentChanges.new( @wiki)
|
|
104
|
+
@wiki.revise( 'testpage','B','normal person')
|
|
105
|
+
wait_for_queue_to_empty
|
|
106
|
+
assert_match( /\[\[testpage\]\]/, rctextile )
|
|
107
|
+
assert_no_match( /\[\[TestPage\]\]/, rctextile )
|
|
108
|
+
@wiki.revise( 'TestPage','C','normal person')
|
|
109
|
+
wait_for_queue_to_empty
|
|
110
|
+
assert_match( /\[\[TestPage\]\]/, rctextile )
|
|
111
|
+
assert_equal( 1, count_matches( /\[\[TestPage\]\]/ ) )
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
def count_matches( regexp )
|
|
117
|
+
count = 0
|
|
118
|
+
rctextile.gsub( regexp ) { |m| count += 1 }
|
|
119
|
+
count
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def rctextile
|
|
123
|
+
@wiki.page("Recent Changes to This Site").textile
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
class TestCalendar < Test::Unit::TestCase
|
|
128
|
+
include TearDownableWiki
|
|
129
|
+
|
|
130
|
+
def setup
|
|
131
|
+
super
|
|
132
|
+
AutomaticCalendar.new( @wiki )
|
|
133
|
+
AutomaticUpdateCrossLinks.new( @wiki, @view )
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_2006_Mar_html
|
|
137
|
+
wait_for_queue_to_empty
|
|
138
|
+
page = @wiki.page('2006 Mar')
|
|
139
|
+
desired_html = IO.readlines('test/html/2006Mar.html')
|
|
140
|
+
actual_html = @view.redcloth( page ).split("\n").map { |l| "#{l}\n" }
|
|
141
|
+
SyncEnumerator.new(desired_html,actual_html).each do |desired,actual|
|
|
142
|
+
assert_equal( desired, actual )
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|