read-only-gollum 1.4.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 (176) hide show
  1. data/Gemfile +4 -0
  2. data/HISTORY.md +102 -0
  3. data/Home.md +3 -0
  4. data/LICENSE +21 -0
  5. data/README.md +477 -0
  6. data/Rakefile +142 -0
  7. data/bin/read-only-gollum +126 -0
  8. data/docs/sanitization.md +32 -0
  9. data/lib/gollum.rb +41 -0
  10. data/lib/gollum/blob_entry.rb +78 -0
  11. data/lib/gollum/committer.rb +218 -0
  12. data/lib/gollum/file.rb +64 -0
  13. data/lib/gollum/frontend/app.rb +225 -0
  14. data/lib/gollum/frontend/public/css/dialog.css +141 -0
  15. data/lib/gollum/frontend/public/css/editor.css +537 -0
  16. data/lib/gollum/frontend/public/css/gollum.css +660 -0
  17. data/lib/gollum/frontend/public/css/ie7.css +69 -0
  18. data/lib/gollum/frontend/public/css/template.css +381 -0
  19. data/lib/gollum/frontend/public/images/icon-sprite.png +0 -0
  20. data/lib/gollum/frontend/public/javascript/editor/gollum.editor.js +1096 -0
  21. data/lib/gollum/frontend/public/javascript/editor/langs/asciidoc.js +167 -0
  22. data/lib/gollum/frontend/public/javascript/editor/langs/creole.js +104 -0
  23. data/lib/gollum/frontend/public/javascript/editor/langs/markdown.js +211 -0
  24. data/lib/gollum/frontend/public/javascript/editor/langs/org.js +173 -0
  25. data/lib/gollum/frontend/public/javascript/editor/langs/pod.js +111 -0
  26. data/lib/gollum/frontend/public/javascript/editor/langs/rdoc.js +74 -0
  27. data/lib/gollum/frontend/public/javascript/editor/langs/textile.js +175 -0
  28. data/lib/gollum/frontend/public/javascript/gollum.dialog.js +263 -0
  29. data/lib/gollum/frontend/public/javascript/gollum.js +161 -0
  30. data/lib/gollum/frontend/public/javascript/gollum.placeholder.js +54 -0
  31. data/lib/gollum/frontend/public/javascript/jquery.color.js +123 -0
  32. data/lib/gollum/frontend/public/javascript/jquery.js +7179 -0
  33. data/lib/gollum/frontend/templates/compare.mustache +38 -0
  34. data/lib/gollum/frontend/templates/create.mustache +17 -0
  35. data/lib/gollum/frontend/templates/edit.mustache +17 -0
  36. data/lib/gollum/frontend/templates/editor.mustache +116 -0
  37. data/lib/gollum/frontend/templates/error.mustache +8 -0
  38. data/lib/gollum/frontend/templates/history.mustache +58 -0
  39. data/lib/gollum/frontend/templates/layout.mustache +28 -0
  40. data/lib/gollum/frontend/templates/page.mustache +37 -0
  41. data/lib/gollum/frontend/templates/pages.mustache +35 -0
  42. data/lib/gollum/frontend/templates/search.mustache +36 -0
  43. data/lib/gollum/frontend/templates/searchbar.mustache +10 -0
  44. data/lib/gollum/frontend/views/compare.rb +94 -0
  45. data/lib/gollum/frontend/views/create.rb +48 -0
  46. data/lib/gollum/frontend/views/edit.rb +52 -0
  47. data/lib/gollum/frontend/views/editable.rb +13 -0
  48. data/lib/gollum/frontend/views/error.rb +7 -0
  49. data/lib/gollum/frontend/views/history.rb +44 -0
  50. data/lib/gollum/frontend/views/layout.rb +20 -0
  51. data/lib/gollum/frontend/views/page.rb +57 -0
  52. data/lib/gollum/frontend/views/pages.rb +19 -0
  53. data/lib/gollum/frontend/views/search.rb +20 -0
  54. data/lib/gollum/git_access.rb +248 -0
  55. data/lib/gollum/markup.rb +489 -0
  56. data/lib/gollum/page.rb +430 -0
  57. data/lib/gollum/pagination.rb +61 -0
  58. data/lib/gollum/sanitization.rb +174 -0
  59. data/lib/gollum/tex.rb +89 -0
  60. data/lib/gollum/web_sequence_diagram.rb +43 -0
  61. data/lib/gollum/wiki.rb +636 -0
  62. data/read-only-gollum.gemspec +224 -0
  63. data/templates/formatting.html +92 -0
  64. data/test/examples/empty.git/HEAD +1 -0
  65. data/test/examples/empty.git/config +5 -0
  66. data/test/examples/empty.git/description +1 -0
  67. data/test/examples/empty.git/hooks/applypatch-msg.sample +15 -0
  68. data/test/examples/empty.git/hooks/commit-msg.sample +24 -0
  69. data/test/examples/empty.git/hooks/post-commit.sample +8 -0
  70. data/test/examples/empty.git/hooks/post-receive.sample +15 -0
  71. data/test/examples/empty.git/hooks/post-update.sample +8 -0
  72. data/test/examples/empty.git/hooks/pre-applypatch.sample +14 -0
  73. data/test/examples/empty.git/hooks/pre-commit.sample +46 -0
  74. data/test/examples/empty.git/hooks/pre-rebase.sample +169 -0
  75. data/test/examples/empty.git/hooks/prepare-commit-msg.sample +36 -0
  76. data/test/examples/empty.git/hooks/update.sample +128 -0
  77. data/test/examples/empty.git/info/exclude +6 -0
  78. data/test/examples/empty.git/objects/info/.gitkeep +0 -0
  79. data/test/examples/empty.git/objects/pack/.gitkeep +0 -0
  80. data/test/examples/empty.git/refs/heads/.gitkeep +0 -0
  81. data/test/examples/lotr.git/COMMIT_EDITMSG +1 -0
  82. data/test/examples/lotr.git/HEAD +1 -0
  83. data/test/examples/lotr.git/ORIG_HEAD +1 -0
  84. data/test/examples/lotr.git/config +12 -0
  85. data/test/examples/lotr.git/description +1 -0
  86. data/test/examples/lotr.git/index +0 -0
  87. data/test/examples/lotr.git/info/exclude +6 -0
  88. data/test/examples/lotr.git/logs/HEAD +3 -0
  89. data/test/examples/lotr.git/logs/refs/heads/master +3 -0
  90. data/test/examples/lotr.git/objects/06/131480411710c92a82fe2d1e76932c70feb2e5 +0 -0
  91. data/test/examples/lotr.git/objects/0a/de1e2916346d4c1f2fb63b863fd3c16808fe44 +0 -0
  92. data/test/examples/lotr.git/objects/0e/d8cbe0a25235bd867e65193c7d837c66b328ef +3 -0
  93. data/test/examples/lotr.git/objects/12/629d666c5e3178f82f533f543d61b53dc78c0b +0 -0
  94. data/test/examples/lotr.git/objects/1d/b89ebba7e2c14d93b94ff98cfa3708a4f0d4e3 +2 -0
  95. data/test/examples/lotr.git/objects/24/49c2681badfd3c189e8ed658dacffe8ba48fe5 +0 -0
  96. data/test/examples/lotr.git/objects/25/4bdc1ba27d8b8a794538a8522d9a2b56ec2dd9 +0 -0
  97. data/test/examples/lotr.git/objects/2c/b9156ad383914561a8502fc70f5a1d887e48ad +4 -0
  98. data/test/examples/lotr.git/objects/5d/cac289a8603188d2c5caf481dcba2985126aaa +0 -0
  99. data/test/examples/lotr.git/objects/60/f12f4254f58801b9ee7db7bca5fa8aeefaa56b +0 -0
  100. data/test/examples/lotr.git/objects/71/4323c104239440a5c66ab12a67ed07a83c404f +0 -0
  101. data/test/examples/lotr.git/objects/84/0ec5b1ba1320e8ec443f28f99566f615d5af10 +0 -0
  102. data/test/examples/lotr.git/objects/93/6b83ee0dd8837adb82511e40d5e4ebe59bb675 +0 -0
  103. data/test/examples/lotr.git/objects/94/523d7ae48aeba575099dd12926420d8fd0425d +2 -0
  104. data/test/examples/lotr.git/objects/96/97dc65e095658bbd1b8e8678e08881e86d32f1 +0 -0
  105. data/test/examples/lotr.git/objects/a3/1ca2a7c352c92531a8b99815d15843b259e814 +0 -0
  106. data/test/examples/lotr.git/objects/a6/59b3763b822dd97544621fd0beef162ea37b14 +4 -0
  107. data/test/examples/lotr.git/objects/a8/ad3c09dd842a3517085bfadd37718856dee813 +0 -0
  108. data/test/examples/lotr.git/objects/aa/b61fe89d56f8614c0a8151da34f939dcedfa68 +0 -0
  109. data/test/examples/lotr.git/objects/bc/4b5fc0ce2c2ba3acef6647e4f67256ee45ab60 +0 -0
  110. data/test/examples/lotr.git/objects/c3/b43e9f08966b088e7a0192e436b7a884542e05 +0 -0
  111. data/test/examples/lotr.git/objects/dc/596d6b2dd89ab05c66f4abd7d5eb706bc17f19 +0 -0
  112. data/test/examples/lotr.git/objects/ec/da3205bee14520aab5a7bb307392064b938e83 +0 -0
  113. data/test/examples/lotr.git/objects/f4/84ebb1f40f8eb20d1bcd8d1d71934d2b8ae961 +0 -0
  114. data/test/examples/lotr.git/objects/fa/e7ef5344202bba4129abdc13060d9297d99465 +3 -0
  115. data/test/examples/lotr.git/objects/info/packs +2 -0
  116. data/test/examples/lotr.git/objects/pack/pack-dcbeaf3f6ff6c5eb08ea2b0a2d83626e8763546b.idx +0 -0
  117. data/test/examples/lotr.git/objects/pack/pack-dcbeaf3f6ff6c5eb08ea2b0a2d83626e8763546b.pack +0 -0
  118. data/test/examples/lotr.git/packed-refs +2 -0
  119. data/test/examples/lotr.git/refs/heads/master +1 -0
  120. data/test/examples/lotr.git/refs/remotes/origin/HEAD +1 -0
  121. data/test/examples/page_file_dir.git/COMMIT_EDITMSG +1 -0
  122. data/test/examples/page_file_dir.git/HEAD +1 -0
  123. data/test/examples/page_file_dir.git/config +6 -0
  124. data/test/examples/page_file_dir.git/description +1 -0
  125. data/test/examples/page_file_dir.git/index +0 -0
  126. data/test/examples/page_file_dir.git/info/exclude +6 -0
  127. data/test/examples/page_file_dir.git/logs/HEAD +1 -0
  128. data/test/examples/page_file_dir.git/logs/refs/heads/master +1 -0
  129. data/test/examples/page_file_dir.git/objects/0c/7d27db1f575263efdcab3dc650f4502a2dbcbf +0 -0
  130. data/test/examples/page_file_dir.git/objects/22/b404803c966dd92865614d86ff22ca12e50c1e +0 -0
  131. data/test/examples/page_file_dir.git/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 +0 -0
  132. data/test/examples/page_file_dir.git/objects/57/16ca5987cbf97d6bb54920bea6adde242d87e6 +0 -0
  133. data/test/examples/page_file_dir.git/objects/5b/43e14e0a15fb6f08feab1773d1c0991e9f71e2 +0 -0
  134. data/test/examples/page_file_dir.git/refs/heads/master +1 -0
  135. data/test/examples/revert.git/COMMIT_EDITMSG +1 -0
  136. data/test/examples/revert.git/HEAD +1 -0
  137. data/test/examples/revert.git/config +12 -0
  138. data/test/examples/revert.git/description +1 -0
  139. data/test/examples/revert.git/index +0 -0
  140. data/test/examples/revert.git/info/exclude +6 -0
  141. data/test/examples/revert.git/logs/HEAD +2 -0
  142. data/test/examples/revert.git/logs/refs/heads/master +2 -0
  143. data/test/examples/revert.git/objects/20/2ced67cea93c7b6bd2928aa1daef8d1d55a20d +0 -0
  144. data/test/examples/revert.git/objects/41/76394bfa11222363c66ce7e84b5f154095b6d9 +0 -0
  145. data/test/examples/revert.git/objects/6a/69f92020f5df77af6e8813ff1232493383b708 +0 -0
  146. data/test/examples/revert.git/objects/b4/785957bc986dc39c629de9fac9df46972c00fc +0 -0
  147. data/test/examples/revert.git/objects/f4/03b791119f8232b7cb0ba455c624ac6435f433 +0 -0
  148. data/test/examples/revert.git/objects/info/packs +2 -0
  149. data/test/examples/revert.git/objects/pack/pack-a561f8437234f74d0bacb9e0eebe52d207f5770d.idx +0 -0
  150. data/test/examples/revert.git/objects/pack/pack-a561f8437234f74d0bacb9e0eebe52d207f5770d.pack +0 -0
  151. data/test/examples/revert.git/packed-refs +2 -0
  152. data/test/examples/revert.git/refs/heads/master +1 -0
  153. data/test/examples/revert.git/refs/remotes/origin/HEAD +1 -0
  154. data/test/examples/yubiwa.git/HEAD +1 -0
  155. data/test/examples/yubiwa.git/config +5 -0
  156. data/test/examples/yubiwa.git/description +1 -0
  157. data/test/examples/yubiwa.git/info/exclude +6 -0
  158. data/test/examples/yubiwa.git/objects/10/fa2ddc4e3b4009d8a453aace10bd6148c1ad00 +0 -0
  159. data/test/examples/yubiwa.git/objects/52/4b82874327ea7cbf730389964ba7cb3de966de +0 -0
  160. data/test/examples/yubiwa.git/objects/58/3fc201cb457fb3f1480f3e1e5999b119633835 +0 -0
  161. data/test/examples/yubiwa.git/objects/87/bc1dd46ab3d3874d4e898d45dd512cc20a7cc8 +1 -0
  162. data/test/examples/yubiwa.git/objects/89/64ed1b4e21aa90e831763bbce9034bfda81b70 +0 -0
  163. data/test/examples/yubiwa.git/objects/9f/f6dd0660da5fba2d3374adb2b84fa653bb538b +0 -0
  164. data/test/examples/yubiwa.git/objects/ac/e97abf2b177815a1972d7db22f229f58c83309 +0 -0
  165. data/test/examples/yubiwa.git/objects/b1/f443863a4816628807fbf86141ebef055dda34 +0 -0
  166. data/test/examples/yubiwa.git/refs/heads/master +1 -0
  167. data/test/helper.rb +66 -0
  168. data/test/test_app.rb +169 -0
  169. data/test/test_committer.rb +64 -0
  170. data/test/test_file.rb +27 -0
  171. data/test/test_git_access.rb +52 -0
  172. data/test/test_markup.rb +628 -0
  173. data/test/test_page.rb +166 -0
  174. data/test/test_page_revert.rb +45 -0
  175. data/test/test_wiki.rb +462 -0
  176. metadata +470 -0
@@ -0,0 +1,27 @@
1
+ # ~*~ encoding: utf-8 ~*~
2
+ path = File.join(File.dirname(__FILE__), "helper")
3
+ require File.expand_path(path)
4
+
5
+ context "File" do
6
+ setup do
7
+ @wiki = Gollum::Wiki.new(testpath("examples/lotr.git"))
8
+ end
9
+
10
+ test "new file" do
11
+ file = Gollum::File.new(@wiki)
12
+ assert_nil file.raw_data
13
+ end
14
+
15
+ test "existing file" do
16
+ commit = @wiki.repo.commits.first
17
+ file = @wiki.file("Mordor/todo.txt")
18
+ assert_equal "[ ] Write section on Ents\n", file.raw_data
19
+ assert_equal 'todo.txt', file.name
20
+ assert_equal commit.id, file.version.id
21
+ assert_equal commit.author.name, file.version.author.name
22
+ end
23
+
24
+ test "accessing tree" do
25
+ assert_nil @wiki.file("Mordor")
26
+ end
27
+ end
@@ -0,0 +1,52 @@
1
+ # ~*~ encoding: utf-8 ~*~
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
3
+
4
+ context "GitAccess" do
5
+ setup do
6
+ @access = Gollum::GitAccess.new(testpath("examples/lotr.git"))
7
+ end
8
+
9
+ test "#commit fills commit_map cache" do
10
+ assert @access.commit_map.empty?
11
+ actual = @access.repo.commits.first
12
+ expected = @access.commit(actual.id)
13
+ assert_equal actual.message, expected.message
14
+ assert_equal actual.message, @access.commit_map[actual.id].message
15
+ end
16
+
17
+ test "#tree_map_for caches ref and tree" do
18
+ assert @access.ref_map.empty?
19
+ assert @access.tree_map.empty?
20
+ @access.tree 'master'
21
+ assert_equal({"master"=>"1db89ebba7e2c14d93b94ff98cfa3708a4f0d4e3"}, @access.ref_map)
22
+
23
+ map = @access.tree_map['1db89ebba7e2c14d93b94ff98cfa3708a4f0d4e3']
24
+ assert_equal 'Bilbo-Baggins.md', map[0].path
25
+ assert_equal '', map[0].dir
26
+ assert_equal map[0].path, map[0].name
27
+ assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path
28
+ assert_equal '/Mordor', map[3].dir
29
+ assert_equal 'Eye-Of-Sauron.md', map[3].name
30
+ end
31
+
32
+ test "#tree_map_for only caches tree for commit" do
33
+ assert @access.tree_map.empty?
34
+ @access.tree '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'
35
+ assert @access.ref_map.empty?
36
+
37
+ entry = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0]
38
+ assert_equal 'Bilbo-Baggins.md', entry.path
39
+ end
40
+
41
+ test "cannot access commit from invalid ref" do
42
+ assert_nil @access.commit('foo')
43
+ end
44
+
45
+ test "cannot access sha from invalid ref" do
46
+ assert_nil @access.ref_to_sha('foo')
47
+ end
48
+
49
+ test "cannot access tree from invalid ref" do
50
+ assert_equal [], @access.tree('foo')
51
+ end
52
+ end
@@ -0,0 +1,628 @@
1
+ # ~*~ encoding: utf-8 ~*~
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "helper"))
3
+
4
+ context "Markup" do
5
+ setup do
6
+ @path = testpath("examples/test.git")
7
+ FileUtils.rm_rf(@path)
8
+ Grit::Repo.init_bare(@path)
9
+ @wiki = Gollum::Wiki.new(@path)
10
+ end
11
+
12
+ teardown do
13
+ FileUtils.rm_r(File.join(File.dirname(__FILE__), *%w[examples test.git]))
14
+ end
15
+
16
+ test "formats page from Wiki#pages" do
17
+ @wiki.write_page("Bilbo Baggins", :markdown, "a [[Foo]][[Bar]] b", commit_details)
18
+ assert @wiki.pages[0].formatted_data
19
+ end
20
+
21
+ # This test is to assume that Sanitize.clean doesn't raise Encoding::CompatibilityError on ruby 1.9
22
+ test "formats non ASCII-7 character page from Wiki#pages" do
23
+ wiki = Gollum::Wiki.new(testpath("examples/yubiwa.git"))
24
+ assert_nothing_raised(defined?(Encoding) && Encoding::CompatibilityError) do
25
+ assert wiki.page("strider").formatted_data
26
+ end
27
+ end
28
+
29
+ test "Gollum::Markup#render yields a DocumentFragment" do
30
+ yielded = false
31
+ @wiki.write_page("Yielded", :markdown, "abc", commit_details)
32
+
33
+ page = @wiki.page("Yielded")
34
+ markup = Gollum::Markup.new(page)
35
+ markup.render do |doc|
36
+ assert_kind_of Nokogiri::HTML::DocumentFragment, doc
37
+ yielded = true
38
+ end
39
+ assert yielded
40
+ end
41
+
42
+ test "Gollum::Page#formatted_data yields a DocumentFragment" do
43
+ yielded = false
44
+ @wiki.write_page("Yielded", :markdown, "abc", commit_details)
45
+
46
+ page = @wiki.page("Yielded")
47
+ page.formatted_data do |doc|
48
+ assert_kind_of Nokogiri::HTML::DocumentFragment, doc
49
+ yielded = true
50
+ end
51
+ assert yielded
52
+ end
53
+
54
+ #########################################################################
55
+ #
56
+ # Links
57
+ #
58
+ #########################################################################
59
+
60
+ test "double page links no space" do
61
+ @wiki.write_page("Bilbo Baggins", :markdown, "a [[Foo]][[Bar]] b", commit_details)
62
+
63
+ # "<p>a <a class=\"internal absent\" href=\"/Foo\">Foo</a><a class=\"internal absent\" href=\"/Bar\">Bar</a> b</p>"
64
+ page = @wiki.page("Bilbo Baggins")
65
+ doc = Nokogiri::HTML page.formatted_data
66
+ paras = doc / :p
67
+ para = paras.first
68
+ anchors = para / :a
69
+ assert_equal 1, paras.size
70
+ assert_equal 2, anchors.size
71
+ assert_equal 'internal absent', anchors[0]['class']
72
+ assert_equal 'internal absent', anchors[1]['class']
73
+ assert_equal '/Foo', anchors[0]['href']
74
+ assert_equal '/Bar', anchors[1]['href']
75
+ assert_equal 'Foo', anchors[0].text
76
+ assert_equal 'Bar', anchors[1].text
77
+ end
78
+
79
+ test "double page links with space" do
80
+ @wiki.write_page("Bilbo Baggins", :markdown, "a [[Foo]] [[Bar]] b", commit_details)
81
+
82
+ # "<p>a <a class=\"internal absent\" href=\"/Foo\">Foo</a> <a class=\"internal absent\" href=\"/Bar\">Bar</a> b</p>"
83
+ page = @wiki.page("Bilbo Baggins")
84
+ doc = Nokogiri::HTML page.formatted_data
85
+ paras = doc / :p
86
+ para = paras.first
87
+ anchors = para / :a
88
+ assert_equal 1, paras.size
89
+ assert_equal 2, anchors.size
90
+ assert_equal 'internal absent', anchors[0]['class']
91
+ assert_equal 'internal absent', anchors[1]['class']
92
+ assert_equal '/Foo', anchors[0]['href']
93
+ assert_equal '/Bar', anchors[1]['href']
94
+ assert_equal 'Foo', anchors[0].text
95
+ assert_equal 'Bar', anchors[1].text
96
+ end
97
+
98
+ test "page link" do
99
+ @wiki.write_page("Bilbo Baggins", :markdown, "a [[Bilbo Baggins]] b", commit_details)
100
+
101
+ page = @wiki.page("Bilbo Baggins")
102
+ output = page.formatted_data
103
+ assert_match /class="internal present"/, output
104
+ assert_match /href="\/Bilbo-Baggins"/, output
105
+ assert_match /\>Bilbo Baggins\</, output
106
+ end
107
+
108
+ test "adds nofollow to links on historical pages" do
109
+ sha1 = @wiki.write_page("Sauron", :markdown, "a [[b]] c", commit_details)
110
+ page = @wiki.page("Sauron")
111
+ sha2 = @wiki.update_page(page, page.name, :markdown, "c [[b]] a", commit_details)
112
+ regx = /rel="nofollow"/
113
+ assert_no_match regx, page.formatted_data
114
+ assert_match regx, @wiki.page(page.name, sha1).formatted_data
115
+ assert_match regx, @wiki.page(page.name, sha2).formatted_data
116
+ end
117
+
118
+ test "absent page link" do
119
+ @wiki.write_page("Tolkien", :markdown, "a [[J. R. R. Tolkien]]'s b", commit_details)
120
+
121
+ page = @wiki.page("Tolkien")
122
+ output = page.formatted_data
123
+ assert_match /class="internal absent"/, output
124
+ assert_match /href="\/J\.\-R\.\-R\.\-Tolkien"/, output
125
+ assert_match /\>J\. R\. R\. Tolkien\</, output
126
+ end
127
+
128
+ test "page link with custom base path" do
129
+ ["/wiki", "/wiki/"].each_with_index do |path, i|
130
+ name = "Bilbo Baggins #{i}"
131
+ @wiki = Gollum::Wiki.new(@path, :base_path => path)
132
+ @wiki.write_page(name, :markdown, "a [[#{name}]] b", commit_details)
133
+
134
+ page = @wiki.page(name)
135
+ output = page.formatted_data
136
+ assert_match /class="internal present"/, output
137
+ assert_match /href="\/wiki\/Bilbo-Baggins-\d"/, output
138
+ assert_match /\>Bilbo Baggins \d\</, output
139
+ end
140
+ end
141
+
142
+ test "page link with included #" do
143
+ @wiki.write_page("Precious #1", :markdown, "a [[Precious #1]] b", commit_details)
144
+ page = @wiki.page('Precious #1')
145
+ output = page.formatted_data
146
+ assert_match /class="internal present"/, output
147
+ assert_match /href="\/Precious-%231"/, output
148
+ end
149
+
150
+ test "page link with extra #" do
151
+ @wiki.write_page("Potato", :markdown, "a [[Potato#1]] b", commit_details)
152
+ page = @wiki.page('Potato')
153
+ output = page.formatted_data
154
+ assert_match /class="internal present"/, output
155
+ assert_match /href="\/Potato#1"/, output
156
+ end
157
+
158
+ test "external page link" do
159
+ @wiki.write_page("Bilbo Baggins", :markdown, "a [[http://example.com]] b", commit_details)
160
+
161
+ page = @wiki.page("Bilbo Baggins")
162
+ assert_equal "<p>a <a href=\"http://example.com\">http://example.com</a> b</p>", page.formatted_data
163
+ end
164
+
165
+ test "page link with different text" do
166
+ @wiki.write_page("Potato", :markdown, "a [[Potato Heaad|Potato]] ", commit_details)
167
+ page = @wiki.page("Potato")
168
+ output = page.formatted_data
169
+ assert_equal "<p>a<aclass=\"internalpresent\"href=\"/Potato\">PotatoHeaad</a></p>", normal(output)
170
+ end
171
+
172
+ test "page link with different text on mediawiki" do
173
+ @wiki.write_page("Potato", :mediawiki, "a [[Potato|Potato Heaad]] ", commit_details)
174
+ page = @wiki.page("Potato")
175
+ output = page.formatted_data
176
+ assert_equal normal("<p>\na <a class=\"internal present\" href=\"/Potato\">Potato Heaad</a> </p>"), normal(output)
177
+ end
178
+
179
+ #########################################################################
180
+ #
181
+ # Images
182
+ #
183
+ #########################################################################
184
+
185
+ test "image with http url" do
186
+ ['http', 'https'].each do |scheme|
187
+ name = "Bilbo Baggins #{scheme}"
188
+ @wiki.write_page(name, :markdown, "a [[#{scheme}://example.com/bilbo.jpg]] b", commit_details)
189
+
190
+ page = @wiki.page(name)
191
+ output = page.formatted_data
192
+ assert_equal %{<p>a <img src="#{scheme}://example.com/bilbo.jpg"> b</p>}, output
193
+ end
194
+ end
195
+
196
+ test "image with extension in caps with http url" do
197
+ ['http', 'https'].each do |scheme|
198
+ name = "Bilbo Baggins #{scheme}"
199
+ @wiki.write_page(name, :markdown, "a [[#{scheme}://example.com/bilbo.JPG]] b", commit_details)
200
+
201
+ page = @wiki.page(name)
202
+ output = page.formatted_data
203
+ assert_equal %{<p>a <img src="#{scheme}://example.com/bilbo.JPG"> b</p>}, output
204
+ end
205
+ end
206
+
207
+ test "image with absolute path" do
208
+ @wiki = Gollum::Wiki.new(@path, :base_path => '/wiki')
209
+ index = @wiki.repo.index
210
+ index.add("alpha.jpg", "hi")
211
+ index.commit("Add alpha.jpg")
212
+ @wiki.write_page("Bilbo Baggins", :markdown, "a [[/alpha.jpg]] [[a | /alpha.jpg]] b", commit_details)
213
+
214
+ page = @wiki.page("Bilbo Baggins")
215
+ assert_equal %{<p>a <img src="/wiki/alpha.jpg"><a href="/wiki/alpha.jpg">a</a> b</p>}, page.formatted_data
216
+ end
217
+
218
+ test "image with relative path on root" do
219
+ @wiki = Gollum::Wiki.new(@path, :base_path => '/wiki')
220
+ index = @wiki.repo.index
221
+ index.add("alpha.jpg", "hi")
222
+ index.add("Bilbo-Baggins.md", "a [[alpha.jpg]] [[a | alpha.jpg]] b")
223
+ index.commit("Add alpha.jpg")
224
+
225
+ page = @wiki.page("Bilbo Baggins")
226
+ assert_equal %{<p>a <img src="/wiki/alpha.jpg"><a href="/wiki/alpha.jpg">a</a> b</p>}, page.formatted_data
227
+ end
228
+
229
+ test "image with relative path" do
230
+ @wiki = Gollum::Wiki.new(@path, :base_path => '/wiki')
231
+ index = @wiki.repo.index
232
+ index.add("greek/alpha.jpg", "hi")
233
+ index.add("greek/Bilbo-Baggins.md", "a [[alpha.jpg]] [[a | alpha.jpg]] b")
234
+ index.commit("Add alpha.jpg")
235
+
236
+ page = @wiki.page("Bilbo Baggins")
237
+ output = page.formatted_data
238
+ assert_equal %{<p>a <img src="/wiki/greek/alpha.jpg"><a href="/wiki/greek/alpha.jpg">a</a> b</p>}, output
239
+ end
240
+
241
+ test "image with absolute path on a preview" do
242
+ @wiki = Gollum::Wiki.new(@path, :base_path => '/wiki')
243
+ index = @wiki.repo.index
244
+ index.add("alpha.jpg", "hi")
245
+ index.commit("Add alpha.jpg")
246
+
247
+ page = @wiki.preview_page("Test", "a [[/alpha.jpg]] b", :markdown)
248
+ assert_equal %{<p>a <img src="/wiki/alpha.jpg"> b</p>}, page.formatted_data
249
+ end
250
+
251
+ test "image with relative path on a preview" do
252
+ @wiki = Gollum::Wiki.new(@path, :base_path => '/wiki')
253
+ index = @wiki.repo.index
254
+ index.add("alpha.jpg", "hi")
255
+ index.add("greek/alpha.jpg", "hi")
256
+ index.commit("Add alpha.jpg")
257
+
258
+ page = @wiki.preview_page("Test", "a [[alpha.jpg]] [[greek/alpha.jpg]] b", :markdown)
259
+ assert_equal %{<p>a <img src="/wiki/alpha.jpg"><img src="/wiki/greek/alpha.jpg"> b</p>}, page.formatted_data
260
+ end
261
+
262
+ test "image with alt" do
263
+ content = "a [[alpha.jpg|alt=Alpha Dog]] b"
264
+ output = %{<p>a <img src="/greek/alpha.jpg" alt="Alpha Dog"> b</p>}
265
+ relative_image(content, output)
266
+ end
267
+
268
+ test "image with em or px dimension" do
269
+ %w{em px}.each do |unit|
270
+ %w{width height}.each do |dim|
271
+ content = "a [[alpha.jpg|#{dim}=100#{unit}]] b"
272
+ output = "<p>a <img src=\"/greek/alpha.jpg\" #{dim}=\"100#{unit}\"> b</p>"
273
+ relative_image(content, output)
274
+ end
275
+ end
276
+ end
277
+
278
+ test "image with bogus dimension" do
279
+ %w{width height}.each do |dim|
280
+ content = "a [[alpha.jpg|#{dim}=100]] b"
281
+ output = "<p>a <img src=\"/greek/alpha.jpg\"> b</p>"
282
+ relative_image(content, output)
283
+ end
284
+ end
285
+
286
+ test "image with vertical align" do
287
+ %w{top texttop middle absmiddle bottom absbottom baseline}.each do |align|
288
+ content = "a [[alpha.jpg|align=#{align}]] b"
289
+ output = "<p>a <img src=\"/greek/alpha.jpg\" align=\"#{align}\"> b</p>"
290
+ relative_image(content, output)
291
+ end
292
+ end
293
+
294
+ test "image with horizontal align" do
295
+ %w{left center right}.each do |align|
296
+ content = "a [[alpha.jpg|align=#{align}]] b"
297
+ output = "<p>a <span class=\"align-#{align}\"><span><img src=\"/greek/alpha.jpg\"></span></span> b</p>"
298
+ relative_image(content, output)
299
+ end
300
+ end
301
+
302
+ test "image with float" do
303
+ content = "a\n\n[[alpha.jpg|float]]\n\nb"
304
+ output = "<p>a</p>\n\n<p><span class=\"float-left\"><span><img src=\"/greek/alpha.jpg\"></span></span></p>\n\n<p>b</p>"
305
+ relative_image(content, output)
306
+ end
307
+
308
+ test "image with float and align" do
309
+ %w{left right}.each do |align|
310
+ content = "a\n\n[[alpha.jpg|float|align=#{align}]]\n\nb"
311
+ output = "<p>a</p>\n\n<p><span class=\"float-#{align}\"><span><img src=\"/greek/alpha.jpg\"></span></span></p>\n\n<p>b</p>"
312
+ relative_image(content, output)
313
+ end
314
+ end
315
+
316
+ test "image with frame" do
317
+ content = "a\n\n[[alpha.jpg|frame]]\n\nb"
318
+ output = "<p>a</p>\n\n<p><span class=\"frame\"><span><img src=\"/greek/alpha.jpg\"></span></span></p>\n\n<p>b</p>"
319
+ relative_image(content, output)
320
+ end
321
+
322
+ test "absolute image with frame" do
323
+ content = "a\n\n[[http://example.com/bilbo.jpg|frame]]\n\nb"
324
+ output = "<p>a</p>\n\n<p><span class=\"frame\"><span><img src=\"http://example.com/bilbo.jpg\"></span></span></p>\n\n<p>b</p>"
325
+ relative_image(content, output)
326
+ end
327
+
328
+ test "image with frame and alt" do
329
+ content = "a\n\n[[alpha.jpg|frame|alt=Alpha]]\n\nb"
330
+ output = "<p>a</p>\n\n<p><span class=\"frame\"><span><img src=\"/greek/alpha.jpg\" alt=\"Alpha\"><span>Alpha</span></span></span></p>\n\n<p>b</p>"
331
+ relative_image(content, output)
332
+ end
333
+
334
+ #########################################################################
335
+ #
336
+ # File links
337
+ #
338
+ #########################################################################
339
+
340
+ test "file link with absolute path" do
341
+ index = @wiki.repo.index
342
+ index.add("alpha.jpg", "hi")
343
+ index.commit("Add alpha.jpg")
344
+ @wiki.write_page("Bilbo Baggins", :markdown, "a [[Alpha|/alpha.jpg]] b", commit_details)
345
+
346
+ page = @wiki.page("Bilbo Baggins")
347
+ output = Gollum::Markup.new(page).render
348
+ assert_equal %{<p>a <a href="/alpha.jpg">Alpha</a> b</p>}, output
349
+ end
350
+
351
+ test "file link with relative path" do
352
+ index = @wiki.repo.index
353
+ index.add("greek/alpha.jpg", "hi")
354
+ index.add("greek/Bilbo-Baggins.md", "a [[Alpha|alpha.jpg]] b")
355
+ index.commit("Add alpha.jpg")
356
+
357
+ page = @wiki.page("Bilbo Baggins")
358
+ output = Gollum::Markup.new(page).render
359
+ assert_equal %{<p>a <a href="/greek/alpha.jpg">Alpha</a> b</p>}, output
360
+ end
361
+
362
+ test "file link with external path" do
363
+ index = @wiki.repo.index
364
+ index.add("greek/Bilbo-Baggins.md", "a [[Alpha|http://example.com/alpha.jpg]] b")
365
+ index.commit("Add alpha.jpg")
366
+
367
+ page = @wiki.page("Bilbo Baggins")
368
+ assert_equal %{<p>a <a href="http://example.com/alpha.jpg">Alpha</a> b</p>}, page.formatted_data
369
+ end
370
+
371
+ #########################################################################
372
+ #
373
+ # Code
374
+ #
375
+ #########################################################################
376
+
377
+ test "code blocks" do
378
+ content = "a\n\n```ruby\nx = 1\n```\n\nb"
379
+ output = "<p>a</p>\n\n<div class=\"highlight\">\n<pre>" +
380
+ "<span class=\"n\">x</span> <span class=\"o\">=</span> " +
381
+ "<span class=\"mi\">1</span>\n</pre>\n</div>\n\n\n<p>b</p>"
382
+
383
+ index = @wiki.repo.index
384
+ index.add("Bilbo-Baggins.md", content)
385
+ index.commit("Add alpha.jpg")
386
+
387
+ page = @wiki.page("Bilbo Baggins")
388
+ rendered = Gollum::Markup.new(page).render
389
+ assert_equal output, rendered
390
+ end
391
+
392
+ test "code blocks with carriage returns" do
393
+ content = "a\r\n\r\n```ruby\r\nx = 1\r\n```\r\n\r\nb"
394
+ output = "<p>a</p>\n\n<div class=\"highlight\">\n<pre>" +
395
+ "<span class=\"n\">x</span> <span class=\"o\">=</span> " +
396
+ "<span class=\"mi\">1</span>\n</pre>\n</div>\n\n\n<p>b</p>"
397
+
398
+ index = @wiki.repo.index
399
+ index.add("Bilbo-Baggins.md", content)
400
+ index.commit("Add alpha.jpg")
401
+
402
+ page = @wiki.page("Bilbo Baggins")
403
+ rendered = Gollum::Markup.new(page).render
404
+ assert_equal output, rendered
405
+ end
406
+
407
+ test "code blocks with two-space indent" do
408
+ content = "a\n\n```ruby\n x = 1\n\n y = 2\n```\n\nb"
409
+ output = "<p>a</p>\n\n<div class=\"highlight\"><pre><span class=\"n\">" +
410
+ "x</span> <span class=\"o\">=</span> <span class=\"mi\">1" +
411
+ "</span>\n\n<span class=\"n\">y</span> <span class=\"o\">=" +
412
+ "</span> <span class=\"mi\">2</span>\n</pre>\n</div>\n\n\n<p>b</p>"
413
+ compare(content, output)
414
+ end
415
+
416
+ test "code blocks with one-tab indent" do
417
+ content = "a\n\n```ruby\n\tx = 1\n\n\ty = 2\n```\n\nb"
418
+ output = "<p>a</p>\n\n<div class=\"highlight\"><pre><span class=\"n\">" +
419
+ "x</span> <span class=\"o\">=</span> <span class=\"mi\">1" +
420
+ "</span>\n\n<span class=\"n\">y</span> <span class=\"o\">=" +
421
+ "</span> <span class=\"mi\">2</span>\n</pre>\n</div>\n\n\n<p>b</p>"
422
+ compare(content, output)
423
+ end
424
+
425
+ test "code blocks with multibyte caracters indent" do
426
+ content = "a\n\n```ruby\ns = 'やくしまるえつこ'\n```\n\nb"
427
+ output = "<p>a</p>\n\n<div class=\"highlight\">\n<pre><span class=\"n\">" +
428
+ "s</span> <span class=\"o\">=</span> <span class=\"s1\">'やくしまるえつこ'" +
429
+ "</span>\n</pre>\n</div>\n\n\n<p>b</p>"
430
+ index = @wiki.repo.index
431
+ index.add("Bilbo-Baggins.md", content)
432
+ index.commit("Add alpha.jpg")
433
+
434
+ page = @wiki.page("Bilbo Baggins")
435
+ rendered = Gollum::Markup.new(page).render(false, 'utf-8')
436
+ assert_equal output, rendered
437
+ end
438
+
439
+ test "code blocks with ascii characters" do
440
+ content = "a\n\n```\n├─foo\n```\n\nb"
441
+ output = "<p>a</p>\n\n<div class=\"highlight\"><pre>" +
442
+ "├─<span class=\"n\">foo</span>" +
443
+ "\n</pre>\n</div>\n\n<p>b</p>"
444
+ compare(content, output)
445
+ end
446
+
447
+ test "code with wiki links" do
448
+ content = <<-END
449
+ booya
450
+
451
+ ``` python
452
+ np.array([[2,2],[1,3]],np.float)
453
+ ```
454
+ END
455
+
456
+ # rendered with Gollum::Markup
457
+ page, rendered = render_page(content)
458
+ assert_markup_highlights_code Gollum::Markup, rendered
459
+ end
460
+
461
+ def assert_markup_highlights_code(markup_class, rendered)
462
+ assert_match /div class="highlight"/, rendered, "#{markup_class} doesn't highlight code\n #{rendered}"
463
+ assert_match /span class="n"/, rendered, "#{markup_class} doesn't highlight code\n #{rendered}"
464
+ assert_match /\(\[\[/, rendered, "#{markup_class} parses out wiki links\n#{rendered}"
465
+ end
466
+
467
+ #########################################################################
468
+ #
469
+ # Web Sequence Diagrams
470
+ #
471
+ #########################################################################
472
+
473
+ test "sequence diagram blocks" do
474
+ content = "a\n\n{{{default\nalice->bob: Test\n}}}\n\nb"
475
+ output = /.*<img src="http:\/\/www\.websequencediagrams\.com\/\?img=\w{9}" \/>.*/
476
+
477
+ index = @wiki.repo.index
478
+ index.add("Bilbo-Baggins.md", content)
479
+ index.commit("Add sequence diagram")
480
+
481
+ page = @wiki.page("Bilbo Baggins")
482
+ rendered = Gollum::Markup.new(page).render
483
+ assert_not_nil rendered.match(output)
484
+ end
485
+
486
+ #########################################################################
487
+ #
488
+ # Various
489
+ #
490
+ #########################################################################
491
+
492
+ test "strips javscript protocol urls" do
493
+ content = "[Hack me](javascript:hacked=true)"
494
+ output = "<p><a>Hackme</a></p>"
495
+ compare(content, output)
496
+ end
497
+
498
+ test "removes style blocks completely" do
499
+ content = "<style>body { color: red }</style>foobar"
500
+ output = "<p>foobar</p>"
501
+ compare(content, output)
502
+ end
503
+
504
+ test "removes script blocks completely" do
505
+ content = "<script>alert('hax');</script>foobar"
506
+ output = "<p>foobar</p>"
507
+ compare(content, output)
508
+ end
509
+
510
+ test "escaped wiki link" do
511
+ content = "a '[[Foo]], b"
512
+ output = "<p>a [[Foo]], b</p>"
513
+ compare(content, output)
514
+ end
515
+
516
+ test "quoted wiki link" do
517
+ content = "a '[[Foo]]', b"
518
+ output = "<p>a '<a class=\"internal absent\" href=\"/Foo\">Foo</a>', b</p>"
519
+ compare(content, output, 'md', [
520
+ /class="internal absent"/,
521
+ /href="\/Foo"/,
522
+ /\>Foo\</])
523
+ end
524
+
525
+ test "org mode style double links" do
526
+ content = "a [[http://google.com][Google]] b"
527
+ output = "<p class=\"title\">a <a href=\"http://google.com\">Google</a> b</p>"
528
+ compare(content, output, 'org')
529
+ end
530
+
531
+ test "org mode style double file links" do
532
+ content = "a [[file:f.org][Google]] b"
533
+ output = "<p class=\"title\">a <a class=\"internal absent\" href=\"/f\">Google</a> b</p>"
534
+ compare(content, output, 'org')
535
+ end
536
+
537
+ test "short double links" do
538
+ content = "a [[b]] c"
539
+ output = %(<p class="title">a <a class="internal absent" href="/b">b</a> c</p>)
540
+ compare(content, output, 'org')
541
+ end
542
+
543
+ test "double linked pipe" do
544
+ content = "a [[|]] b"
545
+ output = %(<p class="title">a <a class="internal absent" href="/"></a> b</p>)
546
+ compare(content, output, 'org')
547
+ end
548
+
549
+ # test "id with prefix ok" do
550
+ # content = "h2(example#wiki-foo). xxxx"
551
+ # output = %(<h2 class="example" id="wiki-foo">xxxx</h2>)
552
+ # compare(content, output, :textile)
553
+ # end
554
+
555
+ # test "id prefix added" do
556
+ # content = "h2(#foo). xxxx[1]\n\nfn1.footnote"
557
+ # output = "<h2 id=\"wiki-foo\">xxxx" +
558
+ # "<sup class=\"footnote\" id=\"wiki-fnr1\"><a href=\"#wiki-fn1\">1</a></sup></h2>" +
559
+ # "\n<p class=\"footnote\" id=\"wiki-fn1\"><a href=\"#wiki-fnr1\"><sup>1</sup></a> footnote</p>"
560
+ # compare(content, output, :textile)
561
+ # end
562
+
563
+ # test "name prefix added" do
564
+ # content = "abc\n\n__TOC__\n\n==Header==\n\nblah"
565
+ # compare content, '', :mediawiki, [
566
+ # /id="wiki-toc"/,
567
+ # /href="#wiki-Header"/,
568
+ # /id="wiki-Header"/,
569
+ # /name="wiki-Header"/
570
+ # ]
571
+ # end
572
+
573
+ #########################################################################
574
+ #
575
+ # TeX
576
+ #
577
+ #########################################################################
578
+
579
+ test "TeX block syntax" do
580
+ content = 'a \[ a^2 \] b'
581
+ output = "<p>a<imgsrc=\"/_tex.png?type=block&data=YV4y\"alt=\"a^2\">b</p>"
582
+ compare(content, output, 'md')
583
+ end
584
+
585
+ test "TeX inline syntax" do
586
+ content = 'a \( a^2 \) b'
587
+ output = "<p>a<imgsrc=\"/_tex.png?type=inline&data=YV4y\"alt=\"a^2\">b</p>"
588
+ compare(content, output, 'md')
589
+ end
590
+
591
+ #########################################################################
592
+ #
593
+ # Helpers
594
+ #
595
+ #########################################################################
596
+
597
+ def render_page(content, ext = "md")
598
+ index = @wiki.repo.index
599
+ index.add("Bilbo-Baggins.#{ext}", content)
600
+ index.commit("Add baggins")
601
+
602
+ page = @wiki.page("Bilbo Baggins")
603
+ [page, Gollum::Markup.new(page).render]
604
+ end
605
+
606
+ def compare(content, output, ext = "md", regexes = [])
607
+ page, rendered = render_page(content, ext)
608
+
609
+ if regexes.empty?
610
+ assert_equal normal(output), normal(rendered)
611
+ else
612
+ output = page.formatted_data
613
+ regexes.each { |r| assert_match r, output }
614
+ end
615
+ end
616
+
617
+ def relative_image(content, output)
618
+ index = @wiki.repo.index
619
+ index.add("greek/alpha.jpg", "hi")
620
+ index.add("greek/Bilbo-Baggins.md", content)
621
+ index.commit("Add alpha.jpg")
622
+
623
+ @wiki.clear_cache
624
+ page = @wiki.page("Bilbo Baggins")
625
+ rendered = Gollum::Markup.new(page).render
626
+ assert_equal normal(output), normal(rendered)
627
+ end
628
+ end