fdlint 0.1.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 (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