fdlint 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +14 -0
  3. data/README.md +68 -0
  4. data/Rakefile +92 -0
  5. data/bin/fdlint +17 -0
  6. data/lib/base_parser.rb +143 -0
  7. data/lib/cmd_runner.rb +145 -0
  8. data/lib/context.rb +31 -0
  9. data/lib/css/parser.rb +186 -0
  10. data/lib/css/reader.rb +30 -0
  11. data/lib/css/rule/check_compression_rule.rb +48 -0
  12. data/lib/css/rule/checklist.rb +45 -0
  13. data/lib/css/struct.rb +111 -0
  14. data/lib/encoding_error.rb +6 -0
  15. data/lib/file_validator.rb +38 -0
  16. data/lib/helper/code_type.rb +50 -0
  17. data/lib/helper/color_string.rb +44 -0
  18. data/lib/helper/file_reader.rb +22 -0
  19. data/lib/helper/strenc.rb +65 -0
  20. data/lib/html/parser.rb +212 -0
  21. data/lib/html/query.rb +96 -0
  22. data/lib/html/rule/check_tag_rule.rb +80 -0
  23. data/lib/html/struct.rb +291 -0
  24. data/lib/js/expr/expr.rb +66 -0
  25. data/lib/js/expr/left_hand.rb +63 -0
  26. data/lib/js/expr/operate.rb +92 -0
  27. data/lib/js/expr/primary.rb +166 -0
  28. data/lib/js/parser.rb +116 -0
  29. data/lib/js/rule/all.rb +35 -0
  30. data/lib/js/rule/checklist.rb +41 -0
  31. data/lib/js/rule/file_checker.rb +42 -0
  32. data/lib/js/rule/helper.rb +96 -0
  33. data/lib/js/rule/no_global.rb +87 -0
  34. data/lib/js/stat/if.rb +25 -0
  35. data/lib/js/stat/iter.rb +85 -0
  36. data/lib/js/stat/stat.rb +117 -0
  37. data/lib/js/stat/switch.rb +65 -0
  38. data/lib/js/stat/try.rb +28 -0
  39. data/lib/js/stat/var.rb +40 -0
  40. data/lib/js/struct.rb +248 -0
  41. data/lib/log_entry.rb +49 -0
  42. data/lib/node.rb +28 -0
  43. data/lib/parse_error.rb +13 -0
  44. data/lib/parser_visitable.rb +138 -0
  45. data/lib/position_info.rb +46 -0
  46. data/lib/printer/base_printer.rb +24 -0
  47. data/lib/printer/console_printer.rb +66 -0
  48. data/lib/printer/nocolor_printer.rb +27 -0
  49. data/lib/printer/vim_printer.rb +19 -0
  50. data/lib/rule.rb +241 -0
  51. data/lib/rule_helper.rb +14 -0
  52. data/lib/runner.rb +225 -0
  53. data/rules.d/css.rule +127 -0
  54. data/rules.d/html.dtd.rule +22 -0
  55. data/rules.d/html.prop.rule +51 -0
  56. data/rules.d/html.tag.rule +136 -0
  57. data/rules.d/js.file.rule +13 -0
  58. data/rules.d/js.jquery.rule +56 -0
  59. data/rules.d/js.mergefile.rule +71 -0
  60. data/rules.d/js.rule +84 -0
  61. data/test/all_tests.rb +84 -0
  62. data/test/cli/cli_test.rb +70 -0
  63. data/test/cli/log_level_test.rb +51 -0
  64. data/test/cli/output_format_test.rb +47 -0
  65. data/test/cli/type_test.rb +77 -0
  66. data/test/css/mac_line_end_support_test.rb +38 -0
  67. data/test/css/parser_test.rb +276 -0
  68. data/test/css/rule/check_encoding_test.rb +66 -0
  69. data/test/css/rule/check_list_rule_test.rb +167 -0
  70. data/test/css/rule/compression_test.rb +53 -0
  71. data/test/css/rule/file_name_test.rb +76 -0
  72. data/test/fixtures/css/broken.css +4 -0
  73. data/test/fixtures/css/cbu/36.css +52 -0
  74. data/test/fixtures/css/cbu/china_top.css +324 -0
  75. data/test/fixtures/css/cbu/default-merge.css +3 -0
  76. data/test/fixtures/css/cbu/default.css +13 -0
  77. data/test/fixtures/css/cbu/diy-merge.css +25 -0
  78. data/test/fixtures/css/cbu/fns-v1.css +27 -0
  79. data/test/fixtures/css/cbu/index_v0.1.css +12 -0
  80. data/test/fixtures/css/cbu/merge.css +11 -0
  81. data/test/fixtures/css/cbu/min.css +2 -0
  82. data/test/fixtures/css/cbu/my_home_admin.css +126 -0
  83. data/test/fixtures/css/cbu/nav.css +95 -0
  84. data/test/fixtures/css/cbu/pic_list.css +386 -0
  85. data/test/fixtures/css/cbu/quote-edit.css +18 -0
  86. data/test/fixtures/css/cbu/selloffer.shopwindow.css +1 -0
  87. data/test/fixtures/css/cbu/v1.css +9 -0
  88. data/test/fixtures/css/css3.css +30 -0
  89. data/test/fixtures/css/empty-min.css +0 -0
  90. data/test/fixtures/css/empty.css +0 -0
  91. data/test/fixtures/css/font-family.css +4 -0
  92. data/test/fixtures/css/gb-good.css +14 -0
  93. data/test/fixtures/css/gb_using_star.css +4 -0
  94. data/test/fixtures/css/import.css +18 -0
  95. data/test/fixtures/css/mac-line-sep-err-min.css +1 -0
  96. data/test/fixtures/css/mac-line-sep-err.css +1 -0
  97. data/test/fixtures/css/mac-line-sep-good-min.css +1 -0
  98. data/test/fixtures/css/mac-line-sep-good.css +1 -0
  99. data/test/fixtures/css/multi-encoding-in-a-file.css +0 -0
  100. data/test/fixtures/css/simple.css +1 -0
  101. data/test/fixtures/css/using_expr.css +8 -0
  102. data/test/fixtures/css/using_hack.css +21 -0
  103. data/test/fixtures/css/using_id.css +1 -0
  104. data/test/fixtures/css/using_star.css +4 -0
  105. data/test/fixtures/css/utf8_good.css +6 -0
  106. data/test/fixtures/css/utf8_good_declaring_charset.css +7 -0
  107. data/test/fixtures/css/utf8_using_star.css +5 -0
  108. data/test/fixtures/html/1-1.html +120 -0
  109. data/test/fixtures/html/1-2.html +120 -0
  110. data/test/fixtures/html/cms.html +373 -0
  111. data/test/fixtures/html/css_out_of_head.html +9 -0
  112. data/test/fixtures/html/fdev-template.html +22 -0
  113. data/test/fixtures/html/google.com.html +33 -0
  114. data/test/fixtures/html/mixed_log_levels.html +4 -0
  115. data/test/fixtures/html/mixed_types.html +13 -0
  116. data/test/fixtures/html/no_dtd.html +6 -0
  117. data/test/fixtures/html/readme.html +94 -0
  118. data/test/fixtures/html/review.board.html +163 -0
  119. data/test/fixtures/html/syntax_err.html +3 -0
  120. data/test/fixtures/html/train/detail/345/233/276/346/226/207/347/273/223/345/220/210.html +208 -0
  121. data/test/fixtures/html/train/detail/347/232/204Flash.html +212 -0
  122. data/test/fixtures/html/train/detail/347/232/204Vedio.html +212 -0
  123. data/test/fixtures/html/train/index.html +37 -0
  124. data/test/fixtures/html/train/test.html +1 -0
  125. data/test/fixtures/html/train//344/277/256/346/224/271/344/270/200/347/272/247/345/210/206/347/261/273.html +112 -0
  126. data/test/fixtures/html/train//344/277/256/346/224/271/345/255/220/345/210/206/347/261/273.html +108 -0
  127. data/test/fixtures/html/train//344/277/256/346/224/271/350/257/276/347/250/213.html +195 -0
  128. data/test/fixtures/html/train//345/215/232/345/256/242/350/256/276/347/275/256.html +142 -0
  129. data/test/fixtures/html/train//346/265/217/350/247/210/350/256/260/345/275/225.html +191 -0
  130. data/test/fixtures/html/train//346/267/273/345/212/240/344/270/200/347/272/247/345/210/206/347/261/273.html +113 -0
  131. data/test/fixtures/html/train//346/267/273/345/212/240/345/255/220/345/210/206/347/261/273.html +112 -0
  132. data/test/fixtures/html/train//346/267/273/345/212/240/350/257/276/347/250/213.html +195 -0
  133. data/test/fixtures/html/train//347/231/273/345/275/225.html +20 -0
  134. data/test/fixtures/html/train//347/256/241/347/220/206/345/210/206/347/261/273.html +210 -0
  135. data/test/fixtures/html/train//347/256/241/347/220/206/345/217/215/351/246/210.html +222 -0
  136. data/test/fixtures/html/train//347/256/241/347/220/206/350/257/276/347/250/213.html +284 -0
  137. data/test/fixtures/html/train//347/256/241/347/220/206/350/264/246/346/210/267.html +107 -0
  138. data/test/fixtures/html/train//347/275/221/344/270/212/345/237/271/350/256/255home/351/241/265.html +354 -0
  139. data/test/fixtures/html/train//347/275/221/345/225/206/345/237/271/350/256/255list/351/241/265.html +255 -0
  140. data/test/fixtures/html/train//350/256/276/347/275/256/351/246/226/351/241/265/346/216/250/350/215/220.html +168 -0
  141. data/test/fixtures/html/train//350/257/264/346/230/216.txt +3 -0
  142. data/test/fixtures/html/train//351/246/226/351/241/265/345/271/277/345/221/212/350/256/276/347/275/256.html +297 -0
  143. data/test/fixtures/html/unescaped.html +2 -0
  144. data/test/fixtures/html/view.vm +916 -0
  145. data/test/fixtures/js/jquery-1.7.js +9300 -0
  146. data/test/fixtures/js/scope-test.js +22 -0
  147. data/test/helper.rb +41 -0
  148. data/test/html/mixed_type_test.rb +35 -0
  149. data/test/html/parser/parse_comment_test.rb +47 -0
  150. data/test/html/parser/parse_dtd_test.rb +46 -0
  151. data/test/html/parser/parse_script_tag_test.rb +55 -0
  152. data/test/html/parser/parse_with_auto_close_tag_test.rb +41 -0
  153. data/test/html/parser/parse_with_diff_case_test.rb +38 -0
  154. data/test/html/parser/parse_with_emtpy_test.rb +22 -0
  155. data/test/html/parser/parse_with_multi_children_test.rb +27 -0
  156. data/test/html/parser/parse_with_multi_line_test.rb +41 -0
  157. data/test/html/parser/parse_with_prop_test.rb +88 -0
  158. data/test/html/parser/parse_with_script_tag_test.rb +26 -0
  159. data/test/html/parser/parse_with_selfclosing_test.rb +39 -0
  160. data/test/html/parser/parse_with_simple_tag_test.rb +44 -0
  161. data/test/html/parser/parse_with_simple_tree_test.rb +40 -0
  162. data/test/html/parser/parse_with_style_tag_test.rb +22 -0
  163. data/test/html/parser/parse_with_text_test.rb +45 -0
  164. data/test/html/parser_test.rb +52 -0
  165. data/test/html/query_test.rb +52 -0
  166. data/test/html/rule/check_block_level_element_test.rb +52 -0
  167. data/test/html/rule/check_button_test.rb +45 -0
  168. data/test/html/rule/check_class_count_test.rb +36 -0
  169. data/test/html/rule/check_css_in_head_test.rb +53 -0
  170. data/test/html/rule/check_dtd_test.rb +46 -0
  171. data/test/html/rule/check_form_element_name_test.rb +49 -0
  172. data/test/html/rule/check_head_contain_meta_and_title_test.rb +52 -0
  173. data/test/html/rule/check_html_template_test.rb +103 -0
  174. data/test/html/rule/check_hyperlink_with_target_test.rb +40 -0
  175. data/test/html/rule/check_hyperlink_with_title_test.rb +43 -0
  176. data/test/html/rule/check_id_n_class_downcase_test.rb +40 -0
  177. data/test/html/rule/check_img_with_alt_prop_test.rb +33 -0
  178. data/test/html/rule/check_no_import_css_test.rb +36 -0
  179. data/test/html/rule/check_prop_have_value_test.rb +32 -0
  180. data/test/html/rule/check_prop_seperator_test.rb +32 -0
  181. data/test/html/rule/check_style_prop_test.rb +30 -0
  182. data/test/html/rule/check_tag_closed_test.rb +59 -0
  183. data/test/html/rule/check_tag_downcase_test.rb +51 -0
  184. data/test/html/rule/check_unescape_char_test.rb +35 -0
  185. data/test/html/rule/check_unique_import_test.rb +56 -0
  186. data/test/html/rule_test.rb +62 -0
  187. data/test/js/expr/expr.rb +57 -0
  188. data/test/js/expr/left_hand.rb +25 -0
  189. data/test/js/expr/operate.rb +145 -0
  190. data/test/js/expr/primary.rb +89 -0
  191. data/test/js/parser_test.rb +98 -0
  192. data/test/js/rule/alert_check_test.rb +37 -0
  193. data/test/js/rule/all_test.rb +23 -0
  194. data/test/js/rule/base_test.rb +34 -0
  195. data/test/js/rule/file_checker_test.rb +131 -0
  196. data/test/js/rule/jq_check_test.rb +90 -0
  197. data/test/js/rule/nest_try_catch_test.rb +71 -0
  198. data/test/js/rule/new_object_and_new_array_test.rb +38 -0
  199. data/test/js/rule/no_eval_test.rb +34 -0
  200. data/test/js/rule/no_global_test.rb +88 -0
  201. data/test/js/rule/private_method_check_test.rb +58 -0
  202. data/test/js/rule/semicolon_test.rb +63 -0
  203. data/test/js/rule/stat_if_with_brace_test.rb +68 -0
  204. data/test/js/rule/stat_if_with_muti_else_test.rb +68 -0
  205. data/test/js/rule/use_strict_equal_test.rb +44 -0
  206. data/test/js/rule_test.rb +47 -0
  207. data/test/js/stat/if.rb +26 -0
  208. data/test/js/stat/iter.rb +115 -0
  209. data/test/js/stat/stat.rb +91 -0
  210. data/test/js/stat/switch.rb +37 -0
  211. data/test/js/stat/try.rb +32 -0
  212. data/test/js/stat/var.rb +38 -0
  213. data/test/parser_visitable_test.rb +102 -0
  214. data/test/position_info_test.rb +66 -0
  215. data/test/rule_dsl/dsl_basic_test.rb +91 -0
  216. data/test/rule_dsl/importing_test.rb +48 -0
  217. data/test/runner/log_level_test.rb +58 -0
  218. metadata +317 -0
@@ -0,0 +1,22 @@
1
+ /**
2
+ * scope test fixture
3
+ */
4
+ (function($){
5
+ function test(){
6
+ var temp;
7
+ }
8
+
9
+ var _createSeperator = function(){
10
+ var _self = this,
11
+ menuEl = _self.get('menuEl');
12
+ //TempӦ��Ҫ����ȷ�ؼ��Ϊȫ�ֱ���
13
+ temp = [a,b,c];
14
+ return new Node(temp).appendTo(menuEl);
15
+
16
+ test = 123;
17
+
18
+ //var temp2;
19
+ temp2 = 234;
20
+ };
21
+
22
+ })(jQuery);
data/test/helper.rb ADDED
@@ -0,0 +1,41 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.expand_path(path.to_str, File.dirname(caller[0]))
5
+ end
6
+ end
7
+ end
8
+
9
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '../lib')
10
+
11
+ require 'test/unit'
12
+ require 'node'
13
+ require 'log_entry.rb'
14
+ require 'runner'
15
+ require 'pathname'
16
+ require 'logger'
17
+
18
+ FIXTURE_ABS_PATH = File.expand_path(File.join( File.dirname(__FILE__) , '/fixtures' ))
19
+ FIXTURE_REL_PATH = Pathname.new(FIXTURE_ABS_PATH).relative_path_from(Pathname.new(File.expand_path '.'))
20
+ FIXTURE_PATH = FIXTURE_REL_PATH
21
+
22
+ XRay::Rule.import_all
23
+
24
+ module XRayTest
25
+ class Logger < ::Logger
26
+ def initialize
27
+ super(STDOUT)
28
+ debug = ARGV.include? '-d'
29
+ self.level = debug ? Logger::INFO : Logger::WARN
30
+ end
31
+ end
32
+ end
33
+
34
+ def has_ruby?(ver)
35
+ not `which ruby#{ver}`.empty?
36
+ end
37
+
38
+ def fixture(path)
39
+ IO.read File.join( FIXTURE_PATH, path )
40
+ end
41
+
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require_relative '../helper'
3
+ require 'html/parser'
4
+ require 'html/query'
5
+
6
+ module XRayTest
7
+ module HTML
8
+
9
+ class MixedTypeTest < Test::Unit::TestCase
10
+
11
+ def setup
12
+ @runner = ::XRay::Runner.new
13
+ end
14
+
15
+ def test_check_html_script_and_style
16
+ html = %Q{<div class="mod">
17
+ <script> var a=1; </script>
18
+ <style>.mod {_font:arial;}</style>
19
+ </div>}
20
+
21
+ results = @runner.check_html( html )
22
+ assert results.any? {|ret| ret.message == '必须存在文档类型声明' }
23
+ assert results.any? {|ret| ret.message == '不允许使用全局变量' && ret.row ==2 && ret.column == 10 }
24
+ assert results.any? {|ret| ret.message == '合理使用hack' && ret.row == 3 && ret.column == 14 }
25
+ end
26
+
27
+ private
28
+ def parse(html)
29
+ ::XRay::HTML::Parser.parse html
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseCommentTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def test_simple_comment
12
+ parse('<!--content-->') do |e|
13
+ assert_equal CommentElement.new('content'), e
14
+ end
15
+ end
16
+
17
+ def test_double_close
18
+ parse('<!--content-->-->') do |e|
19
+ assert_equal Document.new([CommentElement.new('content'), TextElement.new('-->')]), e
20
+ end
21
+ end
22
+
23
+ def test_double_start_and_close
24
+ parse(' <--<!--content-->-->') do |e|
25
+ assert_equal Document.new([
26
+ TextElement.new(' <--'),
27
+ CommentElement.new('content'),
28
+ TextElement.new('-->')
29
+ ]), e
30
+ end
31
+ end
32
+
33
+ def test_multiline
34
+ parse("<!--content\nnewline-->") do |e|
35
+ assert_equal CommentElement.new("content\nnewline"), e
36
+ end
37
+ end
38
+
39
+ def parse(src, &block)
40
+ XRay::HTML::Parser.parse(src, &block)
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseDTDTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def test_parse_html5_dtd
12
+ parse('<!DOCTYPE html>') do |e|
13
+ assert_equal DTDElement.new('html'), e
14
+ end
15
+ end
16
+
17
+ def test_parse_xhtml1
18
+ src = %q(<!DOCTYPE html
19
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
20
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">)
21
+
22
+ parse(src) do |e|
23
+ assert_equal DTDElement.new(%q(html
24
+ PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
25
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd")), e
26
+ end
27
+ end
28
+
29
+ def test_parse_double_dtd
30
+ parse('<!DOCTYPE html><!DOCTYPE html>') do |e|
31
+ assert_equal e, [
32
+ DTDElement.new('html'),
33
+ TextElement.new('<!DOCTYPE html>')
34
+ ]
35
+ end
36
+ end
37
+
38
+ def parse(src, &block)
39
+ XRay::HTML::Parser.parse(src, &block)
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,55 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseScriptTagTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def test_simple_script
12
+ parse('<script>alert("hello");</script>') do |element|
13
+ assert_equal Element.new('script', nil, [
14
+ TextElement.new('alert("hello");')
15
+ ]), element
16
+ end
17
+ end
18
+
19
+ def test_tag_in_script
20
+ script = %q(if(typeof isCoaseLoad=='undefined'){
21
+ document.write("<div></div><script type=\"text/javascript\" src=\"http://style.china.alibaba.com/js/coase/coase.js\"></scr"+"ipt>");
22
+ var isCoaseLoad = true;
23
+ })
24
+ src = %Q(<script type="text/javascript">#{script}</script>)
25
+
26
+ parse(src) do |e|
27
+ assert_equal Element.new('script', {:type=>"text/javascript"}, [ TextElement.new(script) ]), e
28
+ end
29
+ end
30
+
31
+ def test_script_in_head
32
+ script = %q(if(typeof isCoaseLoad=='undefined'){
33
+ document.write("<div></div><script type=\"text/javascript\" src=\"http://style.china.alibaba.com/js/coase/coase.js\"></scr"+"ipt>");
34
+ var isCoaseLoad = true;
35
+ })
36
+ src = %Q(<head><script type="text/javascript">#{script}</script> </head>)
37
+
38
+ parse(src) do |e|
39
+ assert_equal Element.new('head', nil, [
40
+ Element.new('script', {:type=>"text/javascript"}, [ TextElement.new(script) ]),
41
+ TextElement.new(' ')
42
+ ]), e
43
+ end
44
+ end
45
+
46
+ protected
47
+ def parse(src, &block)
48
+ XRay::HTML::Parser.parse(src, &block)
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithAutoCloseTagTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ %w(area base basefont br col frame hr img input link meta param).each do |tag|
12
+ define_method("test_#{tag}_tag") { check_tag tag }
13
+ define_method("test_#{tag.upcase}_tag") { check_tag tag.upcase }
14
+ end
15
+
16
+ def test_manual_close
17
+ src = %q(<div class="main"><input type="hidden" name="next_page" value="/dashboard/" ></input></div>)
18
+ XRay::HTML::Parser.parse(src) do |e|
19
+ assert_equal Element.new('div', {:class => 'main'}, [
20
+ Element.new('input', [
21
+ Property.new(:type, 'hidden'),
22
+ Property.new(:name, 'next_page'),
23
+ Property.new(:value, '/dashboard/')
24
+ ])
25
+ ]), e
26
+ end
27
+ end
28
+
29
+ def check_tag( name )
30
+ assert_equal Document.new([
31
+ Element.new( name, {:name => 'test'}),
32
+ TextElement.new(' text' )
33
+ ]), XRay::HTML::Parser.parse("<#{name} name=\"test\"> text"),
34
+ "TAG: #{name} will auto close and have no children"
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,38 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithDiffCaseTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def setup
12
+ @parser = XRay::HTML::Parser.new('<div class="info">information</DIV>')
13
+ @element = @parser.parse
14
+ end
15
+
16
+ def test_is_a_div_element
17
+ assert @element.is_a?(Element)
18
+ assert_equal @element.tag_name, 'div'
19
+ end
20
+
21
+ def test_have_one_child
22
+ assert_equal [TextElement.new('information')], @element.children
23
+ end
24
+
25
+ def test_has_text
26
+ assert_equal @element.inner_text, 'information'
27
+ end
28
+
29
+ def test_has_html_text
30
+ assert_equal @element.inner_html, 'information'
31
+ assert_equal @element.outer_html, '<div class="info">information</DIV>'
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithEmptyTest < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @parser = XRay::HTML::Parser.new('')
11
+ @element = @parser.parse
12
+ end
13
+
14
+ def test_type_is_nil
15
+ assert_equal @element, nil
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithMultiChildrenTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def setup
12
+ @parser = XRay::HTML::Parser.new('<em>important</em> information!! Attention please!')
13
+ @element = @parser.parse
14
+ end
15
+
16
+ def test_content_must_be_right
17
+ assert_equal Document.new([
18
+ Element.new('em', nil, [TextElement.new('important')]),
19
+ TextElement.new(' information!! Attention please!')
20
+ ]),@element, 'must contain two children'
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,41 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithMultiLineTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def setup
12
+ src = %q(<div
13
+ class="info"
14
+ >information</div>)
15
+ @parser = XRay::HTML::Parser.new(src)
16
+ @element = @parser.parse
17
+ end
18
+
19
+ def test_is_a_div_element
20
+ assert @element.is_a?(Element)
21
+ assert_equal @element.tag_name, 'div'
22
+ end
23
+
24
+ def test_have_one_child
25
+ assert_equal [TextElement.new('information')], @element.children
26
+ end
27
+
28
+ def test_has_text
29
+ assert_equal @element.inner_text, 'information'
30
+ end
31
+
32
+ def _test_has_html_text
33
+ assert_equal @element.inner_html, 'information'
34
+ assert_equal @element.outer_html, '<div class="info">information</div>'
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,88 @@
1
+ require File.expand_path('../../helper', File.dirname(__FILE__))
2
+ require_relative '../../helper'
3
+
4
+ module XRayTest
5
+ module HTML
6
+ module Parser
7
+
8
+ class ParsePropertyTest < Test::Unit::TestCase
9
+
10
+ include XRay::HTML
11
+
12
+ def test_data_prop
13
+ parse('<div class="info" data-creater="vim">information</div>') do |element|
14
+ assert_equal Element.new('div', [
15
+ Property.new(:class, 'info'),
16
+ Property.new('data-creater', 'vim')
17
+ ], [
18
+ TextElement.new('information')
19
+ ]), element
20
+ end
21
+ end
22
+
23
+ def test_more_prop
24
+ parse(%q(<body bgcolor=#ffffff text=#000000 link=#0000cc vlink=#551a8b alink=#ff0000 onload="try{!google.j.b&&document.f.q.focus()}catch(e){};if(document.images)new Image().src='/images/experiments/nav_logo78.png'" ></body>)) do |e|
25
+ props = [
26
+ Property.new('bgcolor', '#ffffff', ''),
27
+ Property.new('text', '#000000', ''),
28
+ Property.new('link', '#0000cc', ''),
29
+ Property.new('vlink', '#551a8b', ''),
30
+ Property.new('alink', '#ff0000', ''),
31
+ Property.new('onload', %q(try{!google.j.b&&document.f.q.focus()}catch(e){};if(document.images)new Image().src='/images/experiments/nav_logo78.png'), '"')
32
+ ]
33
+ assert_equal Element.new('body', props), e
34
+ end
35
+ end
36
+
37
+ def test_prop_without_value
38
+ parse('<input type="checkbox" name="agreement" checked />') do |e|
39
+ assert_equal Element.new('input', [
40
+ Property.new(:type, 'checkbox'),
41
+ Property.new(:name, 'agreement'),
42
+ Property.new(:checked, nil)
43
+ ]), e
44
+ end
45
+ end
46
+
47
+ def test_prop_without_value_2
48
+ # Notice: a space less than last test
49
+ parse('<input type="checkbox" name="agreement" checked/>') do |e|
50
+ assert_equal Element.new('input', [
51
+ Property.new(:type, 'checkbox'),
52
+ Property.new(:name, 'agreement'),
53
+ Property.new(:checked, nil)
54
+ ]), e
55
+ end
56
+ end
57
+
58
+ def test_parse_style
59
+ text = %q(<style id=gstyle>body{margin:0;overflow-y:scroll}#gog{padding:3px 8px 0}td{line-height:.8em}.gac_m td{line-height:17px}form{margin-top:10px;margin-bottom:20px}body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}em{color:#c03;font-style:normal;font-weight:normal}a em{text-decoration:underline}.lst{height:25px;width:496px}#lst-ib:hover{border-color:#a0a0a0 #b9b9b9 #b9b9b9 #b9b9b9!important;}#lst-ib.lst-d-f,#lst-ib:hover.lst-d-f{border-color:#4d90fe!important;}.gsfi,.lst{font:18px arial,sans-serif}.gsfs{font:17px arial,sans-serif}.ds{display:-moz-inline-box;display:inline-block;margin:3px 0 4px;margin-left:4px}.jhp input[type="submit"],.gssb_c input,.gac_bt input{background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#f1f1f1));background-image:-webkit-linear-gradient(top,#f5f5f5,#f1f1f1);-webkit-border-radius:2px;-webkit-user-select:none;background-color:#f5f5f5;background-image:linear-gradient(top,#f5f5f5,#f1f1f1);background-image:-o-linear-gradient(top,#f5f5f5,#f1f1f1);border:1px solid #dcdcdc;border:1px solid rgba(0, 0, 0, 0.1);border-radius:2px;color:#666;cursor:pointer;font-size:11px;font-weight:bold;height:29px;line-height:27px;margin:11px 6px;min-width:54px;padding:0 8px;text-align:center}.jhp input[type="submit"]:hover,.gssb_c input:hover,.gac_bt input:hover{background-image:-webkit-gradient(linear,left top,left bottom,from(#f8f8f8),to(#f1f1f1));background-image:-webkit-linear-gradient(top,#f8f8f8,#f1f1f1);-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);background-color:#f8f8f8;background-image:linear-gradient(top,#f8f8f8,#f1f1f1);background-image:-o-linear-gradient(top,#f8f8f8,#f1f1f1);border:1px solid #c6c6c6;box-shadow:0 1px 1px rgba(0,0,0,0.1);color:#333}.jhp input[type="submit"]:focus,.gssb_c input:focus,.gac_bt input:focus{border:1px solid #4d90fe;outline:none}.gssb_c input,.gac_bt input{margin:6px;}input{font-family:inherit}.lsb:active,.gac_sb:active{background:-webkit-gradient(linear,left top,left bottom,from(#ccc),to(#ddd))}a.gb1,a.gb2,a.gb3,a.gb4{color:#11c !important}#gog{background:#fff}#gbar,#guser{font-size:13px;padding-top:1px !important}#gbar{float:left;height:22px}#guser{padding-bottom:7px !important;text-align:right}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbs,.gbm{background:#fff;left:0;position:absolute;text-align:left;visibility:hidden;z-index:1000}.gbm{border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;z-index:1001}.gb1{margin-right:.5em}.gb1,.gb3{zoom:1}.gb2{display:block;padding:.2em .5em}.gb2,.gb3{text-decoration:none !important;border-bottom:none}a.gb1,a.gb4{text-decoration:underline !important}a.gb1,a.gb2,a.gb3,a.gb4{color:#00c !important}a.gb2:hover{background:#36c;color:#fff !important}#gbar .gbz0l{color:#000 !important;cursor:default;font-weight:bold;text-decoration:none !important}body{background:#fff;color:black}input{-moz-box-sizing:content-box}a{color:#11c;text-decoration:none}a:hover,a:active{text-decoration:underline}.fl a{color:#36c}a:visited{color:#551a8b}a.gb1,a.gb4{text-decoration:underline}a.gb3:hover{text-decoration:none}#ghead a.gb2:hover{color:#fff!important}.sblc{padding-top:5px}.sblc a{display:block;margin:2px 0;margin-left:13px;font-size:11px;}.lsbb{height:30px;display:block}.ftl,#footer a{color:#2200c1;}#fll a, .ftl{margin: 0 8px;}#fll{display:inline}.lsb{border:none;color:#000;cursor:pointer;height:30px;margin:0;outline:0;font:15px arial,sans-serif;vertical-align:top}.lsb:active{background:#ccc}.lst:focus{outline:none}#addlang a{padding:0 3px}.gac_v div{display:none}.gac_v .gac_v2,.gac_bt{display:block!important}#footer{color:#666;font-size:10pt;min-height:49px;min-width:780px;position:relative}#footer #cp-sol{margin-right:52px;}</style>)
60
+ parse(text) do |e|
61
+ assert_equal text, e.outer_html
62
+ end
63
+ end
64
+
65
+ def test_parse_prop_name_with_colon
66
+ parse('<input ns:name="checkbox" name="agreement" checked/>') do |e|
67
+ assert_equal Element.new('input', [
68
+ Property.new('ns:name', 'checkbox'),
69
+ Property.new(:name, 'agreement'),
70
+ Property.new(:checked, nil)
71
+ ]), e
72
+ end
73
+ end
74
+
75
+ def test_parse_invalid_prop_syntax
76
+ assert_raise(XRay::ParseError) do
77
+ parse %Q(<a href="#"title="title\n">link test</a>)
78
+ end
79
+ end
80
+
81
+ def parse(src, &block)
82
+ XRay::HTML::Parser.parse(src, &block)
83
+ end
84
+ end
85
+
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithScriptTagTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def test_parse_script
12
+ text = %q(<script>(function(){
13
+ var b,d,e,f;function g(a,c){if(a.removeEventListener){a.removeEventListener("load",c,false);a.removeEventListener("error",c,false)}else{a.detachEvent("onload",c);a.detachEvent("onerror",c)}}function h(a){f=(new Date).getTime();++d;a=a||window.event;var c=a.target||a.srcElement;g(c,h)}var i=document.getElementsByTagName("img");b=i.length;d=0;for(var j=0,k;j<b;++j){k=i[j];if(k.complete||typeof k.src!="string"||!k.src)++d;else if(k.addEventListener){k.addEventListener("load",h,false);k.addEventListener("error",
14
+ h,false)}else{k.attachEvent("onload",h);k.attachEvent("onerror",h)}}e=b-d;function l(){if(!google.timers.load.t)return;google.timers.load.t.ol=(new Date).getTime();google.timers.load.t.iml=f;google.kCSI.imc=d;google.kCSI.imn=b;google.kCSI.imp=e;google.timers.load.t.xjs&&google.report&&google.report(google.timers.load,google.kCSI)}if(window.addEventListener)window.addEventListener("load",l,false);else if(window.attachEvent)window.attachEvent("onload",l);google.timers.load.t.prt=(f=(new Date).getTime());
15
+ })();
16
+ </script>)
17
+ XRay::HTML::Parser.parse(text) do |e|
18
+ assert_equal text, e.outer_html
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithSelfClosingTagTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def test_self_close
12
+ XRay::HTML::Parser.parse('<div class="info" />') do |e|
13
+ assert_equal Element.new('div', {:class=>"info"}), e
14
+ end
15
+ end
16
+
17
+ def test_br_tag_closed_without_space
18
+ XRay::HTML::Parser.parse('<br/>') do |e|
19
+ assert_equal Element.new('br'), e
20
+ end
21
+ end
22
+
23
+ def test_close_outside
24
+ XRay::HTML::Parser.parse('<div class="info" ></div>') do |e|
25
+ assert_equal Element.new('div', {:class=>"info"}), e
26
+ end
27
+ end
28
+
29
+ def test_center_tag
30
+ XRay::HTML::Parser.parse('<center></center>') do |e|
31
+ assert_equal Element.new('center'), e
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,44 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithSimpleTagTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def setup
12
+ @parser = XRay::HTML::Parser.new('<div class="info">information</div>')
13
+ @element = @parser.parse
14
+ end
15
+
16
+ def test_is_a_div_element
17
+ assert @element.is_a?(Element)
18
+ assert_equal @element.tag_name, 'div'
19
+ end
20
+
21
+ def test_have_one_child
22
+ assert_equal [TextElement.new('information')], @element.children
23
+ end
24
+
25
+ def test_has_text
26
+ assert_equal @element.inner_text, 'information'
27
+ end
28
+
29
+ def test_has_html_text
30
+ assert_equal @element.inner_html, 'information'
31
+ assert_equal @element.outer_html, '<div class="info">information</div>'
32
+ end
33
+
34
+ def test_raise_error_on_invalid_tag_name
35
+ assert_raise(XRay::ParseError) do
36
+ XRay::HTML::Parser.new('<tag(name) />').parse
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,40 @@
1
+ require_relative '../../helper'
2
+
3
+ module XRayTest
4
+ module HTML
5
+ module Parser
6
+
7
+ class ParseWithSimpleTreeTest < Test::Unit::TestCase
8
+
9
+ include XRay::HTML
10
+
11
+ def test_simple_tree
12
+ parse('<div><em>important</em> information!! Attention please!</div>') do |element|
13
+ assert_equal Element.new('div', nil, [
14
+ Element.new('em', nil, [TextElement.new('important')]),
15
+ TextElement.new(' information!! Attention please!')
16
+ ]), element, 'must contain two children'
17
+ end
18
+ end
19
+
20
+ def test_more_deeper
21
+ parse('<div class="info"><span style="color:red"><em>important</em> information!! Attention please!</span></div>') do |element|
22
+ assert_equal Element.new('div', {:class => 'info'}, [
23
+ Element.new('span', {:style => 'color:red'}, [
24
+ Element.new('em', nil, [TextElement.new('important')]),
25
+ TextElement.new(' information!! Attention please!')
26
+ ])
27
+ ]), element, 'must contain two children'
28
+ end
29
+ end
30
+
31
+ protected
32
+ def parse(src, &block)
33
+ XRay::HTML::Parser.parse(src, &block)
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
40
+ end