ruby-bbcode 1.0.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.textile +22 -3
- data/lib/ruby-bbcode.rb +48 -27
- data/lib/ruby-bbcode/bbtree.rb +24 -45
- data/lib/ruby-bbcode/tag_collection.rb +32 -82
- data/lib/ruby-bbcode/tag_info.rb +76 -79
- data/lib/ruby-bbcode/tag_node.rb +25 -31
- data/lib/ruby-bbcode/tag_sifter.rb +214 -184
- data/lib/ruby-bbcode/templates/bbcode_errors_template.rb +68 -0
- data/lib/ruby-bbcode/templates/html_template.rb +55 -0
- data/lib/ruby-bbcode/version.rb +1 -1
- data/lib/tags/tags.rb +33 -23
- data/test/ruby_bbcode_bbcode_test.rb +189 -0
- data/test/{ruby_bbcode_test.rb → ruby_bbcode_html_test.rb} +98 -120
- data/test/ruby_bbcode_validity_test.rb +119 -0
- data/test/test_helper.rb +5 -2
- data/test/unit/tag_sifter_test.rb +22 -32
- data/test/unit/tags_test.rb +17 -0
- metadata +42 -12
- data/test/current_test.rb +0 -8
- data/test/debugging.rb +0 -93
- data/test/unit/debugging_test.rb +0 -48
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module RubyBBCode::Templates
|
4
|
+
# This class is designed to help us build up the (original) BBCode annotated with the error information.
|
5
|
+
# It starts out as a template such as...
|
6
|
+
# @opening_part = '[url=%param%]
|
7
|
+
# @closing_part = '[/url]'
|
8
|
+
# and then slowly turns into...
|
9
|
+
# @opening_part = '[url=http://www.blah.com"]cool beans'
|
10
|
+
# @closing_part = '[/url]'
|
11
|
+
class BBCodeErrorsTemplate
|
12
|
+
attr_accessor :opening_part
|
13
|
+
|
14
|
+
def initialize(node)
|
15
|
+
@node = node
|
16
|
+
@tag_definition = node.definition # tag_definition
|
17
|
+
@opening_part = "[#{node[:tag]}#{node.allow_params? ? '%param%' : ''}]"
|
18
|
+
unless @node[:errors].empty?
|
19
|
+
@opening_part = "<span class='bbcode_error' #{BBCodeErrorsTemplate.error_attribute(@node[:errors])}>#{@opening_part}</span>"
|
20
|
+
end
|
21
|
+
@closing_part = "[/#{node[:tag]}]"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.convert_text(node)
|
25
|
+
# Keep the text as it was
|
26
|
+
return "<span class='bbcode_error' #{error_attribute(node[:errors])}>#{node[:text]}</span>" unless node[:errors].empty?
|
27
|
+
node[:text]
|
28
|
+
end
|
29
|
+
|
30
|
+
def inlay_between_text!
|
31
|
+
# Set the between text between the tags again, if required to do so...
|
32
|
+
@opening_part << get_between
|
33
|
+
end
|
34
|
+
|
35
|
+
def inlay_params!
|
36
|
+
# Iterate over known tokens and fill in their values, if provided
|
37
|
+
@tag_definition[:param_tokens].each do |token|
|
38
|
+
# Use %param% to insert the parameters and their values (and re-add %param%)
|
39
|
+
param_value = @node[:params][token[:token]]
|
40
|
+
@opening_part.gsub!('%param%', " #{token[:token]}=#{param_value}%param%") unless param_value.nil?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def inlay_closing_part!
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_unused_tokens!
|
48
|
+
@opening_part.gsub!('%param%', '')
|
49
|
+
end
|
50
|
+
|
51
|
+
def closing_part
|
52
|
+
@node[:closed] == false ? '' : @closing_part
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def get_between
|
58
|
+
return @node[:between] if @tag_definition[:require_between] and @node[:between]
|
59
|
+
''
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.error_attribute(errors)
|
63
|
+
# Escape (double) quotes so the JSON can be generated properly (and parsed properly by JavaScript)
|
64
|
+
escapedErrors = errors.map { |error| error.gsub("\"",""").gsub("'", "'")}
|
65
|
+
"data-bbcode-errors='#{JSON.fast_generate(escapedErrors)}'"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module RubyBBCode::Templates
|
2
|
+
# This class is designed to help us build up the HTML data. It starts out as a template such as...
|
3
|
+
# @opening_part = '<a href="%url%">%between%'
|
4
|
+
# @closing_part = '</a>'
|
5
|
+
# and then slowly turns into...
|
6
|
+
# @opening_part = '<a href="http://www.blah.com">cool beans'
|
7
|
+
# @closing_part = '</a>'
|
8
|
+
class HtmlTemplate
|
9
|
+
attr_accessor :opening_part, :closing_part
|
10
|
+
|
11
|
+
def initialize(node)
|
12
|
+
@node = node
|
13
|
+
@tag_definition = node.definition # tag_definition
|
14
|
+
@opening_part = node.definition[:html_open].dup
|
15
|
+
@closing_part = node.definition[:html_close].dup
|
16
|
+
end
|
17
|
+
|
18
|
+
# Newlines are converted to html <br /> syntax before being returned.
|
19
|
+
def self.convert_text(node)
|
20
|
+
return '' if node[:text].nil?
|
21
|
+
# convert_newlines_to_br
|
22
|
+
node[:text].gsub("\r\n", "\n").gsub("\n", "<br />\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
def inlay_between_text!
|
26
|
+
@opening_part.gsub!('%between%', @node[:between]) if between_text_as_param?
|
27
|
+
end
|
28
|
+
|
29
|
+
def inlay_params!
|
30
|
+
# Iterate over known tokens and fill in their values, if provided
|
31
|
+
@tag_definition[:param_tokens].each do |token|
|
32
|
+
param_value = @node[:params][token[:token]] || token[:default]
|
33
|
+
param_value = CGI.escape(param_value) if token[:uri_escape]
|
34
|
+
@opening_part.gsub!("%#{token[:token].to_s}%", "#{token[:prefix]}#{param_value}#{token[:postfix]}") unless param_value.nil?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def inlay_closing_part!
|
39
|
+
@closing_part.gsub!('%between%', @node[:between]) if between_text_as_param?
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove_unused_tokens!
|
43
|
+
@tag_definition[:param_tokens].each do |token|
|
44
|
+
@opening_part.gsub!("%#{token[:token]}%", '')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Return true if the between text is needed as param
|
51
|
+
def between_text_as_param?
|
52
|
+
@tag_definition[:require_between]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/ruby-bbcode/version.rb
CHANGED
data/lib/tags/tags.rb
CHANGED
@@ -61,59 +61,69 @@ module RubyBBCode
|
|
61
61
|
:example => '[img]http://www.google.com/intl/en_ALL/images/logo.gif[/img].',
|
62
62
|
:only_allow => [],
|
63
63
|
:require_between => true,
|
64
|
-
:
|
65
|
-
:
|
66
|
-
:
|
67
|
-
{ :token => :height, :prefix => 'height="', :postfix => '" ' } ],
|
68
|
-
:
|
64
|
+
:allow_quick_param => true, :allow_between_as_param => false,
|
65
|
+
:quick_param_format => /^(\d+)x(\d+)$/,
|
66
|
+
:param_tokens => [{:token => :width, :prefix => 'width="', :postfix => '" ', :optional => true },
|
67
|
+
{ :token => :height, :prefix => 'height="', :postfix => '" ', :optional => true } ],
|
68
|
+
:quick_param_format_description => 'The image parameters \'%param%\' are incorrect, \'<width>x<height>\' excepted'},
|
69
69
|
:url => {
|
70
70
|
:html_open => '<a href="%url%">%between%', :html_close => '</a>',
|
71
71
|
:description => 'Link to another page',
|
72
72
|
:example => '[url]http://www.google.com/[/url].',
|
73
73
|
:only_allow => [],
|
74
74
|
:require_between => true,
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
75
|
+
:allow_quick_param => true, :allow_between_as_param => true,
|
76
|
+
:quick_param_format => /^((((http|https|ftp):\/\/)|\/).+)$/,
|
77
|
+
:quick_param_format_description => 'The URL should start with http:// https://, ftp:// or /, instead of \'%param%\'',
|
78
|
+
:param_tokens => [{ :token => :url }]},
|
78
79
|
:quote => {
|
79
80
|
:html_open => '<div class="quote">%author%', :html_close => '</div>',
|
80
81
|
:description => 'Quote another person',
|
81
82
|
:example => '[quote]BBCode is great[/quote]',
|
82
|
-
:
|
83
|
-
:
|
84
|
-
:
|
83
|
+
:allow_quick_param => true, :allow_between_as_param => false,
|
84
|
+
:quick_param_format => /(.*)/,
|
85
|
+
:param_tokens => [{:token => :author, :prefix => '<strong>', :postfix => ' wrote:</strong>', :optional => true}]},
|
85
86
|
:size => {
|
86
87
|
:html_open => '<span style="font-size: %size%px;">', :html_close => '</span>',
|
87
88
|
:description => 'Change the size of the text',
|
88
89
|
:example => '[size=32]This is 32px[/size]',
|
89
|
-
:
|
90
|
-
:
|
91
|
-
:
|
90
|
+
:allow_quick_param => true, :allow_between_as_param => false,
|
91
|
+
:quick_param_format => /(\d+)/,
|
92
|
+
:quick_param_format_description => 'The size parameter \'%param%\' is incorrect, a number is expected',
|
93
|
+
:param_tokens => [{:token => :size}]},
|
92
94
|
:color => {
|
93
95
|
:html_open => '<span style="color: %color%;">', :html_close => '</span>',
|
94
96
|
:description => 'Change the color of the text',
|
95
97
|
:example => '[color=red]This is red[/color]',
|
96
|
-
:
|
97
|
-
:
|
98
|
-
:
|
98
|
+
:allow_quick_param => true, :allow_between_as_param => false,
|
99
|
+
:quick_param_format => /(([a-z]+)|(#[0-9a-f]{6}))/i,
|
100
|
+
:param_tokens => [{:token => :color}]},
|
99
101
|
:youtube => {
|
100
|
-
:html_open => '<
|
101
|
-
:description => '
|
102
|
+
:html_open => '<iframe id="player" type="text/html" width="%width%" height="%height%" src="http://www.youtube.com/embed/%between%?enablejsapi=1" frameborder="0"></iframe>', :html_close => '',
|
103
|
+
:description => 'YouTube video',
|
102
104
|
:example => '[youtube]E4Fbk52Mk1w[/youtube]',
|
103
105
|
:only_allow => [],
|
104
|
-
:url_varients => ["youtube.com", "youtu.be", "y2u.be"], # NOT USED
|
105
106
|
:url_matches => [/youtube\.com.*[v]=([^&]*)/, /youtu\.be\/([^&]*)/, /y2u\.be\/([^&]*)/],
|
106
|
-
:require_between => true
|
107
|
+
:require_between => true,
|
108
|
+
:param_tokens => [
|
109
|
+
{ :token => :width, :optional => true, :default => 400 },
|
110
|
+
{ :token => :height, :optional => true, :default => 320 }
|
111
|
+
]},
|
107
112
|
:vimeo => {
|
108
|
-
:html_open => '<iframe src="http://player.vimeo.com/video/%between%?badge=0" width="
|
113
|
+
:html_open => '<iframe src="http://player.vimeo.com/video/%between%?badge=0" width="%width%" height="%height%" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>',
|
109
114
|
:html_close => '',
|
110
115
|
:description => 'Vimeo video',
|
111
116
|
:example => '[vimeo]http://vimeo.com/46141955[/vimeo]',
|
112
117
|
:only_allow => [],
|
113
118
|
:url_matches => [/vimeo\.com\/([^&]*)/],
|
114
|
-
:require_between => true
|
119
|
+
:require_between => true,
|
120
|
+
:param_tokens => [
|
121
|
+
{ :token => :width, :optional => true, :default => 400 },
|
122
|
+
{ :token => :height, :optional => true, :default => 320 }
|
123
|
+
]},
|
115
124
|
:media => {
|
116
125
|
:multi_tag => true,
|
126
|
+
:require_between => true,
|
117
127
|
:supported_tags => [
|
118
128
|
:youtube,
|
119
129
|
:vimeo
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class RubyBbcodeBbcodeTest < Minitest::Test
|
4
|
+
|
5
|
+
def test_multiline
|
6
|
+
assert_equal "line1\nline2", "line1\nline2".bbcode_show_errors
|
7
|
+
assert_equal "line1\r\nline2", "line1\r\nline2".bbcode_show_errors
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_strong
|
11
|
+
assert_equal '[b]simple[/b]', '[b]simple[/b]'.bbcode_show_errors
|
12
|
+
assert_equal "[b]line 1\nline 2[/b]", "[b]line 1\nline 2[/b]".bbcode_show_errors
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_em
|
16
|
+
assert_equal '[i]simple[/i]', '[i]simple[/i]'.bbcode_show_errors
|
17
|
+
assert_equal "[i]line 1\nline 2[/i]", "[i]line 1\nline 2[/i]".bbcode_show_errors
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_u
|
21
|
+
assert_equal '[u]simple[/u]', '[u]simple[/u]'.bbcode_show_errors
|
22
|
+
assert_equal "[u]line 1\nline 2[/u]", "[u]line 1\nline 2[/u]".bbcode_show_errors
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_code
|
26
|
+
assert_equal '[code]simple[/code]', '[code]simple[/code]'.bbcode_show_errors
|
27
|
+
assert_equal "[code]line 1\nline 2[/code]", "[code]line 1\nline 2[/code]".bbcode_show_errors
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_strikethrough
|
31
|
+
assert_equal '[s]simple[/s]', '[s]simple[/s]'.bbcode_show_errors
|
32
|
+
assert_equal "[s]line 1\nline 2[/s]", "[s]line 1\nline 2[/s]".bbcode_show_errors
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_size
|
36
|
+
assert_equal '[size size=32]32px Text[/size]', '[size=32]32px Text[/size]'.bbcode_show_errors
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_color
|
40
|
+
assert_equal '[color color=red]Red Text[/color]', '[color=red]Red Text[/color]'.bbcode_show_errors
|
41
|
+
assert_equal '[color color=#ff0023]Hex Color Text[/color]', '[color color=#ff0023]Hex Color Text[/color]'.bbcode_show_errors
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_center
|
45
|
+
assert_equal '[center]centered[/center]', '[center]centered[/center]'.bbcode_show_errors
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_ordered_list
|
49
|
+
assert_equal '[ol][li]item 1[/li][li]item 2[/li][/ol]', '[ol][li]item 1[/li][li]item 2[/li][/ol]'.bbcode_show_errors
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_unordered_list
|
53
|
+
assert_equal '[ul][li]item 1[/li][li]item 2[/li][/ul]', '[ul][li]item 1[/li][li]item 2[/li][/ul]'.bbcode_show_errors
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_list_common_syntax
|
57
|
+
assert_equal '[list][*]item 1[/*][*]item 2[/*][/list]', '[list][*]item 1[*]item 2[/list]'.bbcode_show_errors
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_list_common_syntax_explicit_closing
|
61
|
+
assert_equal '[list][*]item 1[/*][*]item 2[/*][/list]', '[list][*]item 1[/*][*]item 2[/*][/list]'.bbcode_show_errors
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_two_lists
|
65
|
+
assert_equal '[ul][li]item1[/li][li]item2[/li][/ul][ul][li]item1[/li][li]item2[/li][/ul]',
|
66
|
+
'[ul][li]item1[/li][li]item2[/li][/ul][ul][li]item1[/li][li]item2[/li][/ul]'.bbcode_show_errors
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_whitespace_in_only_allowed_tags
|
70
|
+
assert_equal "[ol]\n[li]item 1[/li]\n[li]item 2[/li]\n[/ol]",
|
71
|
+
"[ol]\n[li]item 1[/li]\n[li]item 2[/li]\n[/ol]".bbcode_show_errors
|
72
|
+
assert_equal "[ol] [li]item 1[/li] [li]item 2[/li]\t[/ol]",
|
73
|
+
"[ol] [li]item 1[/li] [li]item 2[/li]\t[/ol]".bbcode_show_errors
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_quote
|
77
|
+
assert_equal '[quote]quoting[/quote]', '[quote]quoting[/quote]'.bbcode_show_errors
|
78
|
+
assert_equal '[quote author=someone]quoting[/quote]', '[quote=someone]quoting[/quote]'.bbcode_show_errors
|
79
|
+
assert_equal '[quote author=Kitten][quote author=creatiu]f1[/quote]f2[/quote]',
|
80
|
+
'[quote author=Kitten][quote=creatiu]f1[/quote]f2[/quote]'.bbcode_show_errors
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_link
|
84
|
+
assert_equal '[url url=http://www.google.com]http://www.google.com[/url]', '[url]http://www.google.com[/url]'.bbcode_show_errors
|
85
|
+
assert_equal '[url url=http://google.com]Google[/url]', '[url=http://google.com]Google[/url]'.bbcode_show_errors
|
86
|
+
assert_equal '[url url=/index.html]Home[/url]', '[url=/index.html]Home[/url]'.bbcode_show_errors
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_image
|
90
|
+
assert_equal '[img]http://www.ruby-lang.org/images/logo.gif[/img]',
|
91
|
+
'[img]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_show_errors
|
92
|
+
assert_equal '[img width=95 height=96]http://www.ruby-lang.org/images/logo.gif[/img]',
|
93
|
+
'[img=95x96]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_show_errors
|
94
|
+
assert_equal '[img width=123 height=456]http://www.ruby-lang.org/images/logo.gif[/img]',
|
95
|
+
'[img width=123 height=456]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_show_errors
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_youtube
|
99
|
+
assert_equal '[youtube]E4Fbk52Mk1w[/youtube]',
|
100
|
+
'[youtube]E4Fbk52Mk1w[/youtube]'.bbcode_show_errors
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_youtube_with_full_url
|
104
|
+
assert_equal '[youtube]E4Fbk52Mk1w[/youtube]',
|
105
|
+
'[youtube]http://www.youtube.com/watch?feature=player_embedded&v=E4Fbk52Mk1w[/youtube]'.bbcode_show_errors
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_youtube_with_url_shortener
|
109
|
+
assert_equal '[youtube]cSohjlYQI2A[/youtube]',
|
110
|
+
'[youtube]http://www.youtu.be/cSohjlYQI2A[/youtube]'.bbcode_show_errors
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_disable_tags
|
114
|
+
assert_equal '[b]foobar[/b]', '[b]foobar[/b]'.bbcode_show_errors({}, :disable, :b)
|
115
|
+
assert_equal '[b][i]foobar[/i][/b]', '[b][i]foobar[/i][/b]'.bbcode_show_errors({}, :disable, :b)
|
116
|
+
assert_equal '[b][i]foobar[/i][/b]', '[b][i]foobar[/i][/b]'.bbcode_show_errors({}, :disable, :b, :i)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_enable_tags
|
120
|
+
assert_equal '[b]foobar[/b]' , '[b]foobar[/b]'.bbcode_show_errors({}, :enable, :b)
|
121
|
+
assert_equal '[b][i]foobar[/i][/b]', '[b][i]foobar[/i][/b]'.bbcode_show_errors({}, :enable, :b)
|
122
|
+
assert_equal '[b][i]foobar[/i][/b]', '[b][i]foobar[/i][/b]'.bbcode_show_errors({}, :enable, :b, :i)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_addition_of_tags
|
126
|
+
mydef = {
|
127
|
+
:test => {
|
128
|
+
:html_open => '<test>', :html_close => '</test>',
|
129
|
+
:description => 'This is a test',
|
130
|
+
:example => '[test]Test here[/test]'}
|
131
|
+
}
|
132
|
+
assert_equal 'pre [test]Test here[/test] post', 'pre [test]Test here[/test] post'.bbcode_show_errors(mydef)
|
133
|
+
assert_equal 'pre [b][test]Test here[/test][/b] post', 'pre [b][test]Test here[/test][/b] post'.bbcode_show_errors(mydef)
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_multiple_tag_test
|
137
|
+
assert_equal '[b]bold[/b][i]italic[/i][u]underline[/u][quote]quote[/quote][url url=https://test.com]link[/url]',
|
138
|
+
'[b]bold[/b][i]italic[/i][u]underline[/u][quote]quote[/quote][url=https://test.com]link[/url]'.bbcode_show_errors
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_no_xss_hax
|
142
|
+
expected = "[url url=http://www.google.com' onclick='javascript:alert]google[/url]"
|
143
|
+
assert_equal expected, "[url=http://www.google.com' onclick='javascript:alert]google[/url]".bbcode_show_errors
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_media_tag
|
147
|
+
assert_equal '[youtube]cSohjlYQI2A[/youtube]', '[media]http://www.youtube.com/watch?v=cSohjlYQI2A[/media]'.bbcode_show_errors
|
148
|
+
assert_equal '[vimeo]46141955[/vimeo]', '[media]http://vimeo.com/46141955[/media]'.bbcode_show_errors
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_vimeo_tag
|
152
|
+
input = '[vimeo]http://vimeo.com/46141955[/vimeo]'
|
153
|
+
input2 = '[vimeo]46141955[/vimeo]'
|
154
|
+
|
155
|
+
assert_equal '[vimeo]46141955[/vimeo]', input.bbcode_show_errors
|
156
|
+
assert_equal '[vimeo]46141955[/vimeo]', input2.bbcode_show_errors
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_failing_media_tag
|
160
|
+
assert_equal '<span class=\'bbcode_error\' data-bbcode-errors=\'["Unknown multi-tag type for [media]"]\'>[media]</span>http://www.youtoob.com/watch?v=cSohjlYQI2A[/media]', '[media]http://www.youtoob.com/watch?v=cSohjlYQI2A[/media]'.bbcode_show_errors
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_wrong_tags
|
164
|
+
assert_equal '<span class=\'bbcode_error\' data-bbcode-errors=\'["[b] not closed"]\'>[b]</span>Not closed', '[b]Not closed'.bbcode_show_errors
|
165
|
+
assert_equal '<span class=\'bbcode_error\' data-bbcode-errors=\'["[b] not closed"]\'>[b]</span>2 not <span class=\'bbcode_error\' data-bbcode-errors=\'["[i] not closed"]\'>[i]</span>closed', '[b]2 not [i]closed'.bbcode_show_errors
|
166
|
+
|
167
|
+
assert_equal 'Closing tag not matching<span class=\'bbcode_error\' data-bbcode-errors=\'["Closing tag [/b] doesn't match an opening tag"]\'>[/b]</span>', 'Closing tag not matching[/b]'.bbcode_show_errors
|
168
|
+
|
169
|
+
assert_equal '<span class=\'bbcode_error\' data-bbcode-errors=\'["[b] not closed"]\'>[b]</span>Other closing tag<span class=\'bbcode_error\' data-bbcode-errors=\'["Closing tag [/i] doesn't match [b]"]\'>[/i]</span>', '[b]Other closing tag[/i]'.bbcode_show_errors
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_failing_quick_param
|
173
|
+
assert_equal '<span class=\'bbcode_error\' data-bbcode-errors=\'["The image parameters 'illegal' are incorrect, '<width>x<height>' excepted"]\'>[img]</span>image[/img]', '[img=illegal]image[/img]'.bbcode_show_errors
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_failing_between_texts
|
177
|
+
assert_equal '<span class=\'bbcode_error\' data-bbcode-errors=\'["No text between [img] and [/img] tags."]\'>[img]</span>[/img]', '[img][/img]'.bbcode_show_errors
|
178
|
+
assert_equal '[url]<span class=\'bbcode_error\' data-bbcode-errors=\'["The URL should start with http:// https://, ftp:// or /, instead of 'illegal url'"]\'>illegal url</span>[/url]', '[url]illegal url[/url]'.bbcode_show_errors
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_missing_parent_tags
|
182
|
+
assert_equal '<span class=\'bbcode_error\' data-bbcode-errors=\'["[li] can only be used in [ul] and [ol]"]\'>[li]</span>[/li]', '[li][/li]'.bbcode_show_errors
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_illegal_unallowed_childs
|
186
|
+
assert_equal '[ul]<span class=\'bbcode_error\' data-bbcode-errors=\'["[ul] can only contain [li] and [*] tags, so "Illegal text" is not allowed"]\'>Illegal text</span>[/ul]', '[ul]Illegal text[/ul]'.bbcode_show_errors
|
187
|
+
assert_equal '[ul]<span class=\'bbcode_error\' data-bbcode-errors=\'["[ul] can only contain [li] and [*] tags, so [b] is not allowed"]\'>[b]</span>Illegal tag[/b][/ul]', '[ul][b]Illegal tag[/b][/ul]'.bbcode_show_errors
|
188
|
+
end
|
189
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class RubyBbcodeHtmlTest < Minitest::Test
|
4
4
|
|
5
5
|
def test_multiline
|
6
6
|
assert_equal "line1<br />\nline2", "line1\nline2".bbcode_to_html
|
@@ -53,12 +53,6 @@ class RubyBbcodeTest < Test::Unit::TestCase
|
|
53
53
|
assert_equal '<ul><li>item 1</li><li>item 2</li></ul>', '[ul][li]item 1[/li][li]item 2[/li][/ul]'.bbcode_to_html
|
54
54
|
end
|
55
55
|
|
56
|
-
def test_unordered_list_omit_closing
|
57
|
-
assert_raise RuntimeError do
|
58
|
-
assert_equal '<ul><li>item 1</li><li>item 2</li></ul>', '[ul][li]item 1[li]item 2[/ul]'.bbcode_to_html
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
56
|
def test_list_common_syntax
|
63
57
|
assert_equal '<ul><li>item 1</li><li>item 2</li></ul>', '[list][*]item 1[*]item 2[/list]'.bbcode_to_html
|
64
58
|
end
|
@@ -75,53 +69,12 @@ class RubyBbcodeTest < Test::Unit::TestCase
|
|
75
69
|
def test_whitespace_in_only_allowed_tags
|
76
70
|
assert_equal "<ol><br />\n<li>item 1</li><br />\n<li>item 2</li><br />\n</ol>",
|
77
71
|
"[ol]\n[li]item 1[/li]\n[li]item 2[/li]\n[/ol]".bbcode_to_html
|
78
|
-
|
79
|
-
"[ol] [li]item 1[/li] [li]item 2[/li]
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_illegal_items
|
84
|
-
assert_raise RuntimeError do
|
85
|
-
'[li]Illegal item[/li]'.bbcode_to_html
|
86
|
-
end
|
87
|
-
assert_equal ['[li] can only be used in [ul] and [ol]'],
|
88
|
-
'[li]Illegal item[/li]'.bbcode_check_validity
|
89
|
-
assert_raise RuntimeError do
|
90
|
-
'[b][li]Illegal item[/li][/b]'.bbcode_to_html
|
91
|
-
end
|
92
|
-
|
93
|
-
assert_equal ['[li] can only be used in [ul] and [ol], so using it in a [b] tag is not allowed'],
|
94
|
-
'[b][li]Illegal item[/li][/b]'.bbcode_check_validity
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_illegal_list_contents
|
98
|
-
assert_raise RuntimeError do
|
99
|
-
'[ul]Illegal list[/ul]'.bbcode_to_html
|
100
|
-
end
|
101
|
-
assert_equal ['[ul] can only contain [li] and [*] tags, so "Illegal list" is not allowed'],
|
102
|
-
'[ul]Illegal list[/ul]'.bbcode_check_validity
|
103
|
-
assert_raise RuntimeError do
|
104
|
-
'[ul][b]Illegal list[/b][/ul]'.bbcode_to_html
|
105
|
-
end
|
106
|
-
assert_equal ['[ul] can only contain [li] and [*] tags, so [b] is not allowed'],
|
107
|
-
'[ul][b]Illegal list[/b][/ul][/b]'.bbcode_check_validity
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_illegal_list_contents_text_between_list_items
|
111
|
-
assert_raise RuntimeError do
|
112
|
-
'[ul][li]item[/li]Illegal list[/ul]'.bbcode_to_html
|
113
|
-
end
|
114
|
-
assert_equal ['[ul] can only contain [li] and [*] tags, so "Illegal text" is not allowed'],
|
115
|
-
'[ul][li]item[/li]Illegal text[/ul]'.bbcode_check_validity
|
116
|
-
assert_raise RuntimeError do
|
117
|
-
'[ul][li]item[/li]Illegal list[li]item[/li][/ul]'.bbcode_to_html
|
118
|
-
end
|
119
|
-
assert_equal ['[ul] can only contain [li] and [*] tags, so "Illegal text" is not allowed'],
|
120
|
-
'[ul][li]item[/li]Illegal text[li]item[/li][/ul]'.bbcode_check_validity
|
72
|
+
assert_equal "<ol> <li>item 1</li> <li>item 2</li>\t</ol>",
|
73
|
+
"[ol] [li]item 1[/li] [li]item 2[/li]\t[/ol]".bbcode_to_html
|
121
74
|
end
|
122
75
|
|
123
76
|
def test_quote
|
124
|
-
assert_equal '<div class="quote">quoting</div>',
|
77
|
+
assert_equal '<div class="quote">quoting</div>', '[quote]quoting[/quote]'.bbcode_to_html
|
125
78
|
assert_equal '<div class="quote"><strong>someone wrote:</strong>quoting</div>', '[quote=someone]quoting[/quote]'.bbcode_to_html
|
126
79
|
assert_equal '<div class="quote"><strong>Kitten wrote:</strong><div class="quote"><strong>creatiu wrote:</strong>f1</div>f2</div>',
|
127
80
|
'[quote=Kitten][quote=creatiu]f1[/quote]f2[/quote]'.bbcode_to_html
|
@@ -133,45 +86,34 @@ class RubyBbcodeTest < Test::Unit::TestCase
|
|
133
86
|
assert_equal '<a href="/index.html">Home</a>', '[url=/index.html]Home[/url]'.bbcode_to_html
|
134
87
|
end
|
135
88
|
|
136
|
-
def test_illegal_link
|
137
|
-
assert_raise RuntimeError do
|
138
|
-
# Link within same domain must start with a /
|
139
|
-
'[url=index.html]Home[/url]'.bbcode_to_html
|
140
|
-
end
|
141
|
-
assert_raise RuntimeError do
|
142
|
-
# Link within same domain must start with a / and a link to another domain with http://, https:// or ftp://
|
143
|
-
'[url=www.google.com]Google[/url]'.bbcode_to_html
|
144
|
-
end
|
145
|
-
assert_raise RuntimeError do
|
146
|
-
'[url]htfp://www.google.com[/url]'.bbcode_to_html
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
89
|
def test_image
|
151
90
|
assert_equal '<img src="http://www.ruby-lang.org/images/logo.gif" alt="" />',
|
152
91
|
'[img]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_to_html
|
153
92
|
assert_equal '<img src="http://www.ruby-lang.org/images/logo.gif" width="95" height="96" alt="" />',
|
154
93
|
'[img=95x96]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_to_html
|
94
|
+
assert_equal '<img src="http://www.ruby-lang.org/images/logo.gif" width="123" height="456" alt="" />',
|
95
|
+
'[img width=123 height=456]http://www.ruby-lang.org/images/logo.gif[/img]'.bbcode_to_html
|
155
96
|
end
|
156
97
|
|
157
98
|
def test_youtube
|
158
|
-
assert_equal '<
|
99
|
+
assert_equal '<iframe id="player" type="text/html" width="400" height="320" src="http://www.youtube.com/embed/E4Fbk52Mk1w?enablejsapi=1" frameborder="0"></iframe>',
|
159
100
|
'[youtube]E4Fbk52Mk1w[/youtube]'.bbcode_to_html
|
101
|
+
assert_equal '<iframe id="player" type="text/html" width="640" height="480" src="http://www.youtube.com/embed/E4Fbk52Mk1w?enablejsapi=1" frameborder="0"></iframe>',
|
102
|
+
'[youtube width=640 height=480]E4Fbk52Mk1w[/youtube]'.bbcode_to_html
|
160
103
|
end
|
161
104
|
|
162
105
|
def test_youtube_with_full_url
|
163
106
|
full_url = "http://www.youtube.com/watch?feature=player_embedded&v=E4Fbk52Mk1w"
|
164
|
-
assert_equal '<
|
107
|
+
assert_equal '<iframe id="player" type="text/html" width="400" height="320" src="http://www.youtube.com/embed/E4Fbk52Mk1w?enablejsapi=1" frameborder="0"></iframe>',
|
165
108
|
"[youtube]#{full_url}[/youtube]".bbcode_to_html
|
166
109
|
end
|
167
|
-
|
110
|
+
|
168
111
|
def test_youtube_with_url_shortener
|
169
112
|
full_url = "http://www.youtu.be/cSohjlYQI2A"
|
170
|
-
assert_equal '<
|
113
|
+
assert_equal '<iframe id="player" type="text/html" width="400" height="320" src="http://www.youtube.com/embed/cSohjlYQI2A?enablejsapi=1" frameborder="0"></iframe>',
|
171
114
|
"[youtube]#{full_url}[/youtube]".bbcode_to_html
|
172
115
|
end
|
173
116
|
|
174
|
-
|
175
117
|
def test_html_escaping
|
176
118
|
assert_equal '<strong><i>foobar</i></strong>', '[b]<i>foobar</i>[/b]'.bbcode_to_html
|
177
119
|
assert_equal '<strong><i>foobar</i></strong>', '[b]<i>foobar</i>[/b]'.bbcode_to_html(false)
|
@@ -181,6 +123,20 @@ class RubyBbcodeTest < Test::Unit::TestCase
|
|
181
123
|
assert_equal '2 is > 1', '2 is > 1'.bbcode_to_html(false)
|
182
124
|
end
|
183
125
|
|
126
|
+
def test_uri_escaping
|
127
|
+
# There is no tag available, so create our own to test URI escaping
|
128
|
+
escape_param_def = {
|
129
|
+
:escapequery => {
|
130
|
+
:html_open => '<a href="%query%">%between%', :html_close => '</a>',
|
131
|
+
:require_between => true, :allow_quick_param => false, :allow_between_as_param => true,
|
132
|
+
:param_tokens => [{:token => :query, :uri_escape => true}]}
|
133
|
+
}
|
134
|
+
assert_equal '<a href="Escaped+string+%28to+be+used+as+URL+%26+more%29">Escaped string (to be used as URL & more)</a>',
|
135
|
+
'[escapequery]Escaped string (to be used as URL & more)[/escapequery]'.bbcode_to_html(true, escape_param_def)
|
136
|
+
assert_equal '<a href="http%3A%3A%2Fwww.text.com%2Fpage.php%3Fparam1%3D1%26param2%3D2">http::/www.text.com/page.php?param1=1¶m2=2</a>',
|
137
|
+
'[escapequery]http::/www.text.com/page.php?param1=1¶m2=2[/escapequery]'.bbcode_to_html(true, escape_param_def)
|
138
|
+
end
|
139
|
+
|
184
140
|
def test_disable_tags
|
185
141
|
assert_equal "[b]foobar[/b]", "[b]foobar[/b]".bbcode_to_html(true, {}, :disable, :b)
|
186
142
|
assert_equal "[b]<em>foobar</em>[/b]", "[b][i]foobar[/i][/b]".bbcode_to_html(true, {}, :disable, :b)
|
@@ -199,11 +155,6 @@ class RubyBbcodeTest < Test::Unit::TestCase
|
|
199
155
|
assert_equal "<strong>foobar</strong>", foo
|
200
156
|
end
|
201
157
|
|
202
|
-
# commented this out, it kinda just gets in the way of development atm
|
203
|
-
#def test_self_tag_list
|
204
|
-
# assert_equal 16, RubyBBCode::Tags.tag_list.size
|
205
|
-
#end
|
206
|
-
|
207
158
|
def test_addition_of_tags
|
208
159
|
mydef = {
|
209
160
|
:test => {
|
@@ -220,66 +171,93 @@ class RubyBbcodeTest < Test::Unit::TestCase
|
|
220
171
|
"[b]bold[/b][i]italic[/i][u]underline[/u][quote]quote[/quote][url=https://test.com]link[/url]".bbcode_to_html
|
221
172
|
end
|
222
173
|
|
223
|
-
def test_no_ending_tag
|
224
|
-
assert_raise RuntimeError do
|
225
|
-
"this [b]should not be bold".bbcode_to_html
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def test_no_start_tag
|
230
|
-
assert_raise RuntimeError do
|
231
|
-
"this should not be bold[/b]".bbcode_to_html
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
def test_different_start_and_ending_tags
|
236
|
-
assert_raise RuntimeError do
|
237
|
-
"this [b]should not do formatting[/i]".bbcode_to_html
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
174
|
def test_no_xss_hax
|
242
175
|
expected = "<a href=\"http://www.google.com" onclick=\"javascript:alert\">google</a>"
|
243
176
|
assert_equal expected, '[url=http://www.google.com" onclick="javascript:alert]google[/url]'.bbcode_to_html
|
244
177
|
end
|
245
|
-
|
246
|
-
|
247
|
-
#def test_stack_level_too_deep
|
248
|
-
# num = 2300 # increase this number if the test starts failing. It's very near the tipping point
|
249
|
-
# openers = "[s]hi i'm" * num
|
250
|
-
# closers = "[/s]" * num
|
251
|
-
# assert_raise( SystemStackError ) do
|
252
|
-
# (openers+closers).bbcode_to_html
|
253
|
-
# end
|
254
|
-
#end
|
255
|
-
|
256
|
-
def test_mulit_tag
|
178
|
+
|
179
|
+
def test_media_tag
|
257
180
|
input1 = "[media]http://www.youtube.com/watch?v=cSohjlYQI2A[/media]"
|
258
181
|
input2 = "[media]http://vimeo.com/46141955[/media]"
|
259
|
-
|
260
|
-
output1 =
|
261
|
-
output2 = '<iframe src="http://player.vimeo.com/video/46141955?badge=0" width="
|
262
|
-
|
263
|
-
|
182
|
+
|
183
|
+
output1 = '<iframe id="player" type="text/html" width="400" height="320" src="http://www.youtube.com/embed/cSohjlYQI2A?enablejsapi=1" frameborder="0"></iframe>'
|
184
|
+
output2 = '<iframe src="http://player.vimeo.com/video/46141955?badge=0" width="400" height="320" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
|
185
|
+
|
264
186
|
assert_equal output1, input1.bbcode_to_html
|
265
187
|
assert_equal output2, input2.bbcode_to_html
|
266
188
|
end
|
267
|
-
|
189
|
+
|
268
190
|
def test_vimeo_tag
|
269
191
|
input = "[vimeo]http://vimeo.com/46141955[/vimeo]"
|
270
192
|
input2 = "[vimeo]46141955[/vimeo]"
|
271
|
-
output = '<iframe src="http://player.vimeo.com/video/46141955?badge=0" width="
|
272
|
-
|
193
|
+
output = '<iframe src="http://player.vimeo.com/video/46141955?badge=0" width="400" height="320" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
|
194
|
+
|
273
195
|
assert_equal output, input.bbcode_to_html
|
274
196
|
assert_equal output, input2.bbcode_to_html
|
197
|
+
|
198
|
+
assert_equal '<iframe src="http://player.vimeo.com/video/46141955?badge=0" width="640" height="480" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>',
|
199
|
+
'[vimeo width=640 height=480]46141955[/vimeo]'.bbcode_to_html
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_raised_exceptions
|
203
|
+
# Test whether exceptions are raised when the BBCode contains errors
|
204
|
+
assert_raises RuntimeError do
|
205
|
+
'this [b]should raise an exception'.bbcode_to_html
|
206
|
+
end
|
207
|
+
assert_raises RuntimeError do
|
208
|
+
'[ul][li]item 1[li]item 2[/ul]'.bbcode_to_html
|
209
|
+
end
|
275
210
|
end
|
276
|
-
|
277
|
-
def
|
278
|
-
|
279
|
-
|
280
|
-
assert_equal input1, input1.bbcode_to_html
|
211
|
+
|
212
|
+
def test_uppercase
|
213
|
+
assert_equal '<strong>simple</strong>', '[B]simple[/B]'.bbcode_to_html
|
214
|
+
assert_equal "<strong>line 1<br />\nline 2</strong>", "[B]line 1\nline 2[/B]".bbcode_to_html
|
281
215
|
end
|
282
|
-
|
283
|
-
|
284
216
|
|
217
|
+
def test_uppercase_with_params
|
218
|
+
assert_equal '<span style="font-size: 4px;">simple</span>', '[SIZE=4]simple[/SIZE]'.bbcode_to_html
|
219
|
+
assert_equal "<span style=\"font-size: 4px;\">line 1<br />\nline 2</span>", "[SIZE=4]line 1\nline 2[/SIZE]".bbcode_to_html
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_uppercase_at_tag_open
|
223
|
+
assert_equal '<strong>simple</strong>', '[B]simple[/b]'.bbcode_to_html
|
224
|
+
assert_equal "<strong>line 1<br />\nline 2</strong>", "[B]line 1\nline 2[/b]".bbcode_to_html
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_uppercase_at_tag_close
|
228
|
+
assert_equal '<strong>simple</strong>', '[b]simple[/B]'.bbcode_to_html
|
229
|
+
assert_equal "<strong>line 1<br />\nline 2</strong>", "[b]line 1\nline 2[/B]".bbcode_to_html
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_nested_uppercase_tags
|
233
|
+
assert_equal '<ul><li>item 1</li><li>item 2</li></ul>', '[UL][LI]item 1[/LI][LI]item 2[/LI][/UL]'.bbcode_to_html
|
234
|
+
assert_equal "<ul><li>line 1<br />\nline 2</li><li>line 1<br />\nline 2</li></ul>", "[UL][LI]line 1\nline 2[/LI][LI]line 1\nline 2[/LI][/UL]".bbcode_to_html
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_parent_uppercase_in_nested_tags
|
238
|
+
assert_equal '<ul><li>item 1</li><li>item 2</li></ul>', '[UL][li]item 1[/li][li]item 2[/li][/UL]'.bbcode_to_html
|
239
|
+
assert_equal "<ul><li>line 1<br />\nline 2</li><li>line 1<br />\nline 2</li></ul>", "[UL][li]line 1\nline 2[/li][li]line 1\nline 2[/li][/UL]".bbcode_to_html
|
240
|
+
end
|
241
|
+
|
242
|
+
# Checking the HTML output is the only way to see whether a tag is recognized
|
243
|
+
# The BBCode validity test ignores unknown tags (and treats them as text)
|
244
|
+
def test_modified_taglist
|
245
|
+
assert_equal '<strong>simple</strong>', '[b]simple[/b]'.bbcode_to_html
|
246
|
+
|
247
|
+
tags = RubyBBCode::Tags.tag_list
|
248
|
+
b_tag = tags.delete :b
|
249
|
+
begin
|
250
|
+
# Make sure we captured the contents of the b-tag
|
251
|
+
assert b_tag.instance_of? Hash
|
252
|
+
|
253
|
+
# Now no HTML is generated, as the tag is removed
|
254
|
+
assert_equal '[b]simple[/b]', '[b]simple[/b]'.bbcode_to_html
|
255
|
+
ensure
|
256
|
+
# Always restore as this change is permanent (and messes with other tests)
|
257
|
+
tags[:b] = b_tag
|
258
|
+
end
|
259
|
+
|
260
|
+
# Restored to the original/correct situation
|
261
|
+
assert_equal '<strong>simple</strong>', '[b]simple[/b]'.bbcode_to_html
|
262
|
+
end
|
285
263
|
end
|