watir 6.13.0 → 6.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +141 -0
  3. data/.travis.yml +6 -0
  4. data/CHANGES.md +12 -0
  5. data/Gemfile +4 -10
  6. data/README.md +64 -49
  7. data/Rakefile +28 -16
  8. data/lib/watir.rb +13 -15
  9. data/lib/watir/adjacent.rb +15 -13
  10. data/lib/watir/after_hooks.rb +8 -10
  11. data/lib/watir/alert.rb +7 -8
  12. data/lib/watir/aliases.rb +2 -2
  13. data/lib/watir/attribute_helper.rb +18 -20
  14. data/lib/watir/browser.rb +42 -75
  15. data/lib/watir/capabilities.rb +19 -10
  16. data/lib/watir/cell_container.rb +0 -2
  17. data/lib/watir/container.rb +4 -4
  18. data/lib/watir/cookies.rb +7 -8
  19. data/lib/watir/element_collection.rb +37 -22
  20. data/lib/watir/elements/area.rb +0 -2
  21. data/lib/watir/elements/button.rb +1 -3
  22. data/lib/watir/elements/cell.rb +0 -1
  23. data/lib/watir/elements/checkbox.rb +5 -7
  24. data/lib/watir/elements/date_field.rb +5 -9
  25. data/lib/watir/elements/date_time_field.rb +6 -10
  26. data/lib/watir/elements/dlist.rb +2 -4
  27. data/lib/watir/elements/element.rb +201 -99
  28. data/lib/watir/elements/file_field.rb +3 -4
  29. data/lib/watir/elements/font.rb +2 -4
  30. data/lib/watir/elements/form.rb +0 -2
  31. data/lib/watir/elements/hidden.rb +3 -4
  32. data/lib/watir/elements/html_elements.rb +24 -76
  33. data/lib/watir/elements/iframe.rb +57 -71
  34. data/lib/watir/elements/image.rb +3 -4
  35. data/lib/watir/elements/input.rb +0 -2
  36. data/lib/watir/elements/link.rb +2 -5
  37. data/lib/watir/elements/list.rb +4 -4
  38. data/lib/watir/elements/option.rb +3 -6
  39. data/lib/watir/elements/radio.rb +4 -6
  40. data/lib/watir/elements/row.rb +0 -1
  41. data/lib/watir/elements/select.rb +41 -43
  42. data/lib/watir/elements/svg_elements.rb +0 -116
  43. data/lib/watir/elements/table.rb +1 -2
  44. data/lib/watir/elements/table_cell.rb +2 -3
  45. data/lib/watir/elements/text_field.rb +4 -6
  46. data/lib/watir/exception.rb +0 -1
  47. data/lib/watir/extensions/nokogiri.rb +2 -4
  48. data/lib/watir/generator.rb +3 -3
  49. data/lib/watir/generator/base.rb +10 -10
  50. data/lib/watir/generator/base/generator.rb +26 -29
  51. data/lib/watir/generator/base/idl_sorter.rb +34 -32
  52. data/lib/watir/generator/base/spec_extractor.rb +132 -114
  53. data/lib/watir/generator/base/util.rb +1 -3
  54. data/lib/watir/generator/base/visitor.rb +140 -140
  55. data/lib/watir/generator/html.rb +4 -4
  56. data/lib/watir/generator/html/generator.rb +2 -4
  57. data/lib/watir/generator/html/spec_extractor.rb +33 -33
  58. data/lib/watir/generator/html/visitor.rb +14 -14
  59. data/lib/watir/generator/svg.rb +3 -3
  60. data/lib/watir/generator/svg/generator.rb +1 -3
  61. data/lib/watir/generator/svg/spec_extractor.rb +35 -35
  62. data/lib/watir/generator/svg/visitor.rb +14 -14
  63. data/lib/watir/has_window.rb +2 -4
  64. data/lib/watir/js_execution.rb +7 -9
  65. data/lib/watir/js_snippets.rb +3 -3
  66. data/lib/watir/js_snippets/attributeValues.js +11 -0
  67. data/lib/watir/legacy_wait.rb +7 -12
  68. data/lib/watir/locators.rb +9 -11
  69. data/lib/watir/locators/button/locator.rb +2 -3
  70. data/lib/watir/locators/button/selector_builder.rb +9 -9
  71. data/lib/watir/locators/button/selector_builder/xpath.rb +1 -1
  72. data/lib/watir/locators/button/validator.rb +2 -2
  73. data/lib/watir/locators/cell/locator.rb +0 -2
  74. data/lib/watir/locators/cell/selector_builder.rb +3 -5
  75. data/lib/watir/locators/element/locator.rb +85 -64
  76. data/lib/watir/locators/element/selector_builder.rb +40 -38
  77. data/lib/watir/locators/element/selector_builder/xpath.rb +20 -18
  78. data/lib/watir/locators/element/validator.rb +1 -1
  79. data/lib/watir/locators/row/locator.rb +0 -2
  80. data/lib/watir/locators/row/selector_builder.rb +6 -9
  81. data/lib/watir/locators/text_area/selector_builder.rb +1 -1
  82. data/lib/watir/locators/text_field/locator.rb +1 -3
  83. data/lib/watir/locators/text_field/selector_builder.rb +5 -5
  84. data/lib/watir/locators/text_field/selector_builder/xpath.rb +1 -1
  85. data/lib/watir/locators/text_field/validator.rb +3 -2
  86. data/lib/watir/logger.rb +11 -21
  87. data/lib/watir/navigation.rb +49 -0
  88. data/lib/watir/radio_set.rb +17 -18
  89. data/lib/watir/row_container.rb +3 -5
  90. data/lib/watir/screenshot.rb +2 -4
  91. data/lib/watir/user_editable.rb +13 -8
  92. data/lib/watir/version.rb +3 -0
  93. data/lib/watir/wait.rb +56 -55
  94. data/lib/watir/wait/timer.rb +1 -3
  95. data/lib/watir/window.rb +36 -45
  96. data/lib/watir/xpath_support.rb +1 -3
  97. data/lib/watirspec.rb +11 -11
  98. data/lib/watirspec/guards.rb +10 -7
  99. data/lib/watirspec/implementation.rb +3 -4
  100. data/lib/watirspec/rake_tasks.rb +30 -29
  101. data/lib/watirspec/remote_server.rb +3 -3
  102. data/lib/watirspec/runner.rb +1 -2
  103. data/lib/watirspec/server.rb +3 -0
  104. data/lib/watirspec/server/app.rb +14 -6
  105. data/spec/implementation_spec.rb +9 -9
  106. data/spec/locator_spec_helper.rb +3 -4
  107. data/spec/spec_helper.rb +3 -7
  108. data/spec/unit/container_spec.rb +9 -10
  109. data/spec/unit/element_locator_spec.rb +224 -219
  110. data/spec/unit/logger_spec.rb +4 -4
  111. data/spec/unit/unit_helper.rb +0 -2
  112. data/spec/unit/wait_spec.rb +26 -28
  113. data/spec/watirspec/adjacent_spec.rb +130 -130
  114. data/spec/watirspec/after_hooks_spec.rb +63 -63
  115. data/spec/watirspec/alert_spec.rb +6 -6
  116. data/spec/watirspec/attributes_spec.rb +6 -6
  117. data/spec/watirspec/browser_spec.rb +161 -162
  118. data/spec/watirspec/click_spec.rb +9 -9
  119. data/spec/watirspec/cookies_spec.rb +15 -14
  120. data/spec/watirspec/drag_and_drop_spec.rb +15 -16
  121. data/spec/watirspec/element_hidden_spec.rb +19 -21
  122. data/spec/watirspec/elements/area_spec.rb +18 -21
  123. data/spec/watirspec/elements/areas_spec.rb +13 -15
  124. data/spec/watirspec/elements/button_spec.rb +96 -99
  125. data/spec/watirspec/elements/buttons_spec.rb +17 -19
  126. data/spec/watirspec/elements/checkbox_spec.rb +102 -100
  127. data/spec/watirspec/elements/checkboxes_spec.rb +13 -15
  128. data/spec/watirspec/elements/collections_spec.rb +35 -37
  129. data/spec/watirspec/elements/date_field_spec.rb +46 -47
  130. data/spec/watirspec/elements/date_fields_spec.rb +13 -15
  131. data/spec/watirspec/elements/date_time_field_spec.rb +62 -57
  132. data/spec/watirspec/elements/date_time_fields_spec.rb +14 -15
  133. data/spec/watirspec/elements/dd_spec.rb +46 -48
  134. data/spec/watirspec/elements/dds_spec.rb +13 -15
  135. data/spec/watirspec/elements/del_spec.rb +27 -28
  136. data/spec/watirspec/elements/dels_spec.rb +13 -15
  137. data/spec/watirspec/elements/div_spec.rb +89 -91
  138. data/spec/watirspec/elements/divs_spec.rb +17 -19
  139. data/spec/watirspec/elements/dl_spec.rb +52 -54
  140. data/spec/watirspec/elements/dls_spec.rb +13 -15
  141. data/spec/watirspec/elements/dt_spec.rb +46 -48
  142. data/spec/watirspec/elements/dts_spec.rb +13 -15
  143. data/spec/watirspec/elements/element_spec.rb +240 -189
  144. data/spec/watirspec/elements/elements_spec.rb +16 -16
  145. data/spec/watirspec/elements/em_spec.rb +38 -40
  146. data/spec/watirspec/elements/ems_spec.rb +13 -15
  147. data/spec/watirspec/elements/filefield_spec.rb +45 -46
  148. data/spec/watirspec/elements/filefields_spec.rb +13 -15
  149. data/spec/watirspec/elements/font_spec.rb +11 -13
  150. data/spec/watirspec/elements/form_spec.rb +13 -15
  151. data/spec/watirspec/elements/forms_spec.rb +13 -15
  152. data/spec/watirspec/elements/frame_spec.rb +48 -50
  153. data/spec/watirspec/elements/frames_spec.rb +13 -15
  154. data/spec/watirspec/elements/hidden_spec.rb +23 -25
  155. data/spec/watirspec/elements/hiddens_spec.rb +13 -15
  156. data/spec/watirspec/elements/hn_spec.rb +22 -24
  157. data/spec/watirspec/elements/hns_spec.rb +13 -13
  158. data/spec/watirspec/elements/iframe_spec.rb +106 -74
  159. data/spec/watirspec/elements/iframes_spec.rb +16 -18
  160. data/spec/watirspec/elements/image_spec.rb +30 -32
  161. data/spec/watirspec/elements/images_spec.rb +13 -15
  162. data/spec/watirspec/elements/input_spec.rb +4 -5
  163. data/spec/watirspec/elements/ins_spec.rb +27 -29
  164. data/spec/watirspec/elements/inses_spec.rb +13 -15
  165. data/spec/watirspec/elements/label_spec.rb +17 -19
  166. data/spec/watirspec/elements/labels_spec.rb +13 -15
  167. data/spec/watirspec/elements/li_spec.rb +23 -25
  168. data/spec/watirspec/elements/link_spec.rb +45 -48
  169. data/spec/watirspec/elements/links_spec.rb +14 -16
  170. data/spec/watirspec/elements/lis_spec.rb +13 -15
  171. data/spec/watirspec/elements/list_spec.rb +14 -15
  172. data/spec/watirspec/elements/map_spec.rb +19 -20
  173. data/spec/watirspec/elements/maps_spec.rb +13 -15
  174. data/spec/watirspec/elements/meta_spec.rb +10 -10
  175. data/spec/watirspec/elements/metas_spec.rb +13 -15
  176. data/spec/watirspec/elements/ol_spec.rb +20 -21
  177. data/spec/watirspec/elements/ols_spec.rb +13 -15
  178. data/spec/watirspec/elements/option_spec.rb +63 -63
  179. data/spec/watirspec/elements/p_spec.rb +27 -26
  180. data/spec/watirspec/elements/pre_spec.rb +24 -25
  181. data/spec/watirspec/elements/pres_spec.rb +13 -15
  182. data/spec/watirspec/elements/ps_spec.rb +13 -15
  183. data/spec/watirspec/elements/radio_spec.rb +96 -97
  184. data/spec/watirspec/elements/radios_spec.rb +13 -15
  185. data/spec/watirspec/elements/select_list_spec.rb +244 -237
  186. data/spec/watirspec/elements/select_lists_spec.rb +15 -16
  187. data/spec/watirspec/elements/span_spec.rb +32 -31
  188. data/spec/watirspec/elements/spans_spec.rb +13 -15
  189. data/spec/watirspec/elements/strong_spec.rb +23 -24
  190. data/spec/watirspec/elements/strongs_spec.rb +13 -15
  191. data/spec/watirspec/elements/table_nesting_spec.rb +15 -14
  192. data/spec/watirspec/elements/table_spec.rb +61 -62
  193. data/spec/watirspec/elements/tables_spec.rb +15 -17
  194. data/spec/watirspec/elements/tbody_spec.rb +25 -26
  195. data/spec/watirspec/elements/tbodys_spec.rb +17 -19
  196. data/spec/watirspec/elements/td_spec.rb +20 -22
  197. data/spec/watirspec/elements/tds_spec.rb +9 -11
  198. data/spec/watirspec/elements/text_field_spec.rb +55 -56
  199. data/spec/watirspec/elements/text_fields_spec.rb +15 -16
  200. data/spec/watirspec/elements/textarea_spec.rb +2 -2
  201. data/spec/watirspec/elements/textareas_spec.rb +1 -1
  202. data/spec/watirspec/elements/tfoot_spec.rb +22 -23
  203. data/spec/watirspec/elements/tfoots_spec.rb +19 -19
  204. data/spec/watirspec/elements/thead_spec.rb +21 -23
  205. data/spec/watirspec/elements/theads_spec.rb +19 -19
  206. data/spec/watirspec/elements/tr_spec.rb +20 -22
  207. data/spec/watirspec/elements/trs_spec.rb +17 -19
  208. data/spec/watirspec/elements/ul_spec.rb +17 -19
  209. data/spec/watirspec/elements/uls_spec.rb +13 -14
  210. data/spec/watirspec/html/data_attributes.html +1 -0
  211. data/spec/watirspec/radio_set_spec.rb +100 -99
  212. data/spec/watirspec/relaxed_locate_spec.rb +19 -43
  213. data/spec/watirspec/screenshot_spec.rb +4 -4
  214. data/spec/watirspec/special_chars_spec.rb +2 -4
  215. data/spec/watirspec/support/rspec_matchers.rb +85 -22
  216. data/spec/watirspec/user_editable_spec.rb +84 -85
  217. data/spec/watirspec/wait_spec.rb +74 -95
  218. data/spec/watirspec/window_switching_spec.rb +131 -132
  219. data/spec/watirspec_helper.rb +12 -9
  220. data/support/travis.sh +4 -0
  221. data/support/version_differ.rb +12 -13
  222. data/watir.gemspec +29 -22
  223. metadata +76 -50
@@ -27,7 +27,7 @@ module Watir
27
27
 
28
28
  def hashes
29
29
  all_rows = rows.locate
30
- header_row = all_rows.first || raise(Exception::Error, "no rows in table")
30
+ header_row = all_rows.first || raise(Exception::Error, 'no rows in table')
31
31
 
32
32
  all_rows.entries[1..-1].map do |row|
33
33
  cell_size_check(header_row, row)
@@ -71,6 +71,5 @@ module Watir
71
71
  row_id = index ? "row at index #{index - 1}" : 'designated row'
72
72
  raise Exception::Error, "#{row_id} has #{row_size} cells, while header row has #{header_size}"
73
73
  end
74
-
75
74
  end # Table
76
75
  end # Watir
@@ -1,6 +1,5 @@
1
1
  module Watir
2
2
  class TableCell < HTMLElement
3
-
4
3
  def column_header
5
4
  current_row = parent(tag_name: 'tr')
6
5
  header_row(current_row, index: previous_siblings.size).text
@@ -17,13 +16,13 @@ module Watir
17
16
  private
18
17
 
19
18
  def header_row(current_row, opt)
20
- table = self.parent(tag_name: 'table')
19
+ table = parent(tag_name: 'table')
21
20
  header_row = table.tr
22
21
 
23
22
  table.cell_size_check(header_row, current_row)
24
23
 
25
24
  header_type = table.th.exist? ? 'th' : 'tr'
26
- opt.merge!(tag_name: header_type)
25
+ opt[:tag_name] = header_type
27
26
 
28
27
  Watir.tag_to_class[header_type.to_sym].new(header_row, opt)
29
28
  end
@@ -2,14 +2,12 @@ module Watir
2
2
  class TextField < Input
3
3
  include UserEditable
4
4
 
5
- NON_TEXT_TYPES = %w[file radio checkbox submit reset image button hidden range color date datetime-local]
6
-
7
- protected
5
+ NON_TEXT_TYPES = %w[file radio checkbox submit reset image button hidden range color date datetime-local].freeze
8
6
 
9
7
  def selector_string
10
8
  selector = @selector.dup
11
9
  selector[:type] = '(any text type)'
12
- selector[:tag_name] = "input"
10
+ selector[:tag_name] = 'input'
13
11
 
14
12
  if @query_scope.is_a?(Browser) || @query_scope.is_a?(IFrame)
15
13
  super
@@ -21,11 +19,11 @@ module Watir
21
19
 
22
20
  module Container
23
21
  def text_field(*args)
24
- TextField.new(self, extract_selector(args).merge(tag_name: "input"))
22
+ TextField.new(self, extract_selector(args).merge(tag_name: 'input'))
25
23
  end
26
24
 
27
25
  def text_fields(*args)
28
- TextFieldCollection.new(self, extract_selector(args).merge(tag_name: "input"))
26
+ TextFieldCollection.new(self, extract_selector(args).merge(tag_name: 'input'))
29
27
  end
30
28
  end # Container
31
29
 
@@ -11,6 +11,5 @@ module Watir
11
11
  class NoMatchingWindowFoundException < Error; end
12
12
  class UnknownFrameException < Error; end
13
13
  class UnknownRowException < Error; end
14
-
15
14
  end # Exception
16
15
  end # Watir
@@ -1,14 +1,12 @@
1
- require "nokogiri"
1
+ require 'nokogiri'
2
2
 
3
3
  module Watir
4
4
  class Browser
5
-
6
5
  def text
7
6
  doc = Nokogiri::HTML(body(index: 0).html)
8
- doc.css("script").remove # encoding bug in older libxml?
7
+ doc.css('script').remove # encoding bug in older libxml?
9
8
 
10
9
  doc.inner_text
11
10
  end
12
-
13
11
  end # Browser
14
12
  end # Watir
@@ -1,3 +1,3 @@
1
- require "watir/generator/base"
2
- require "watir/generator/html"
3
- require "watir/generator/svg"
1
+ require 'watir/generator/base'
2
+ require 'watir/generator/html'
3
+ require 'watir/generator/svg'
@@ -1,11 +1,11 @@
1
- require "nokogiri"
2
- require "open-uri"
3
- require "pp"
4
- require "webidl"
5
- require "active_support/inflector"
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+ require 'pp'
4
+ require 'webidl'
5
+ require 'active_support/inflector'
6
6
 
7
- require "watir/generator/base/generator"
8
- require "watir/generator/base/idl_sorter"
9
- require "watir/generator/base/spec_extractor"
10
- require "watir/generator/base/util"
11
- require "watir/generator/base/visitor"
7
+ require 'watir/generator/base/generator'
8
+ require 'watir/generator/base/idl_sorter'
9
+ require 'watir/generator/base/spec_extractor'
10
+ require 'watir/generator/base/util'
11
+ require 'watir/generator/base/visitor'
@@ -1,9 +1,9 @@
1
1
  module Watir
2
2
  module Generator
3
3
  class Base
4
-
5
4
  def generate(spec_url, io = StringIO.new)
6
- @spec_url, @io = spec_url, io
5
+ @spec_url = spec_url
6
+ @io = io
7
7
 
8
8
  extract_spec
9
9
  cleanup_spec
@@ -34,9 +34,7 @@ module Watir
34
34
  @tag2interfaces = extractor.process
35
35
  @sorted_interfaces = extractor.sorted_interfaces
36
36
 
37
- if extractor.errors.any?
38
- raise "error extracting spec: #{extractor.errors.join("\n")}"
39
- end
37
+ raise "error extracting spec: #{extractor.errors.join("\n")}" if extractor.errors.any?
40
38
  end
41
39
 
42
40
  def cleanup_spec
@@ -55,23 +53,23 @@ module Watir
55
53
 
56
54
  def write_header
57
55
  @io.puts "# Autogenerated from #{generator_implementation} specification. Edits may be lost."
58
- @io.puts "module Watir"
56
+ @io.puts 'module Watir'
59
57
  end
60
58
 
61
59
  def write_class_defs
62
60
  @sorted_interfaces.each do |interface|
63
61
  interface = generator.generate(interface)
64
- unless interface.empty?
65
- interface.gsub!(/^\s+\n/, '') # remove empty lines
66
- @io.puts indent(interface)
67
- @io.puts "\n"
68
- end
62
+ next if interface.empty?
63
+
64
+ interface.gsub!(/^\s+\n/, '') # remove empty lines
65
+ @io.puts indent(interface)
66
+ @io.puts "\n"
69
67
  end
70
68
  end
71
69
 
72
70
  def write_container_methods
73
71
  @io.puts "\n"
74
- @io.puts indent("module Container")
72
+ @io.puts indent('module Container')
75
73
 
76
74
  @tag2interfaces.sort.each do |tag, interfaces|
77
75
  raise "multiple interfaces for tag #{tag.inspect}" if interfaces.map(&:name).uniq.size != 1
@@ -83,33 +81,32 @@ module Watir
83
81
  collection_class = "#{element_class}Collection"
84
82
 
85
83
  # visitor.visit_tag(tag, interfaces.first.name) !?
86
- @io.puts indent(<<-CODE, 2)
87
-
88
- # @return [#{element_class}]
89
- def #{singular}(*args)
90
- #{element_class}.new(self, extract_selector(args).merge(tag_name: #{tag_string}))
91
- end
92
- # @return [#{collection_class}]
93
- def #{plural}(*args)
94
- #{collection_class}.new(self, extract_selector(args).merge(tag_name: #{tag_string}))
95
- end
96
- Watir.tag_to_class[#{tag.to_sym.inspect}] = #{element_class}
97
-
98
- CODE
84
+ @io.puts indent(<<~CODE, 2)
85
+
86
+ # @return [#{element_class}]
87
+ def #{singular}(*args)
88
+ #{element_class}.new(self, extract_selector(args).merge(tag_name: #{tag_string}))
89
+ end
90
+ # @return [#{collection_class}]
91
+ def #{plural}(*args)
92
+ #{collection_class}.new(self, extract_selector(args).merge(tag_name: #{tag_string}))
93
+ end
94
+ Watir.tag_to_class[#{tag.to_sym.inspect}] = #{element_class}
95
+
96
+ CODE
99
97
  end
100
98
 
101
- @io.puts indent("end # Container")
99
+ @io.puts indent('end # Container')
102
100
  end
103
101
 
104
102
  def write_footer
105
- @io.puts "end # Watir"
103
+ @io.puts 'end # Watir'
106
104
  end
107
105
 
108
106
  def indent(code, indent = 1)
109
- indent_string = " " * indent
107
+ indent_string = ' ' * indent
110
108
  code.split("\n").map { |line| line.empty? ? line : indent_string + line }.join("\n")
111
109
  end
112
-
113
110
  end # Base
114
111
  end # Generator
115
112
  end # Watir
@@ -2,46 +2,48 @@ require 'tsort'
2
2
 
3
3
  module Watir
4
4
  module Generator
5
- class Base::IDLSorter
6
- include TSort
7
-
8
- def initialize(interfaces)
9
- @interfaces = {}
10
-
11
- interfaces.each do |interface|
12
- @interfaces[interface.name] ||= []
13
- interface.inherits.each do |inherit|
14
- (@interfaces[inherit.name] ||= []) << interface.name
5
+ module Base
6
+ class IDLSorter
7
+ include TSort
8
+
9
+ def initialize(interfaces)
10
+ @interfaces = {}
11
+
12
+ interfaces.each do |interface|
13
+ @interfaces[interface.name] ||= []
14
+ interface.inherits.each do |inherit|
15
+ (@interfaces[inherit.name] ||= []) << interface.name
16
+ end
15
17
  end
16
18
  end
17
- end
18
19
 
19
- def print
20
- @visited = []
21
- sort.each { |node| print_node(node) }
22
- end
20
+ def print
21
+ @visited = []
22
+ sort.each { |node| print_node(node) }
23
+ end
23
24
 
24
- def sort
25
- tsort.reverse
26
- end
25
+ def sort
26
+ tsort.reverse
27
+ end
27
28
 
28
- def tsort_each_node(&blk)
29
- @interfaces.each_key(&blk)
30
- end
29
+ def tsort_each_node(&blk)
30
+ @interfaces.each_key(&blk)
31
+ end
31
32
 
32
- def tsort_each_child(node, &blk)
33
- @interfaces[node].each(&blk)
34
- end
33
+ def tsort_each_child(node, &blk)
34
+ @interfaces[node].each(&blk)
35
+ end
35
36
 
36
- private
37
+ private
37
38
 
38
- def print_node(node, indent = 0)
39
- return if @visited.include?(node)
40
- @visited << node
41
- puts " " * indent + node
42
- tsort_each_child(node) { |child| print_node(child, indent + 2)}
43
- end
39
+ def print_node(node, indent = 0)
40
+ return if @visited.include?(node)
44
41
 
45
- end # IDLSorter
42
+ @visited << node
43
+ puts ' ' * indent + node
44
+ tsort_each_child(node) { |child| print_node(child, indent + 2) }
45
+ end
46
+ end # IDLSorter
47
+ end # Base
46
48
  end # Generator
47
49
  end # Watir
@@ -1,138 +1,156 @@
1
1
  module Watir
2
2
  module Generator
3
- class Base::SpecExtractor
4
-
5
- IDL_SELECTOR = "//pre[contains(@class, 'idl')]".freeze
6
-
7
- class InterfaceNotFound < StandardError; end
8
-
9
- def initialize(uri)
10
- @uri = uri
11
- end
12
-
13
- def process
14
- download_and_parse
15
- extract_idl_parts
16
- extract_interface_map
17
- drop_issued_interfaces
18
- build_result
19
- rescue
20
- p errors
21
- raise
22
- end
23
-
24
- def errors
25
- @errors ||= []
26
- end
27
-
28
- #
29
- # returns a topoligically sorted array of WebIDL::Ast::Interface objects
30
- #
31
-
32
- def sorted_interfaces
33
- process if @interfaces.nil?
34
-
35
- sorter.sort.map { |name|
36
- @interfaces.find { |i| i.name == name } or puts "ignoring interface: #{name}"
37
- }.compact
38
- end
39
-
40
- def print_hierarchy
41
- process if @interfaces.nil?
42
- sorter.print
43
- end
44
-
45
- def fetch_interface(interface)
46
- @interfaces_by_name[interface] or raise InterfaceNotFound, "#{interface} not found in IDL"
47
- end
48
-
49
- private
50
-
51
- def download_and_parse
52
- open(@uri) { |io| @doc = Nokogiri.HTML(io) }
53
- end
54
-
55
- def extract_idl_parts
56
- parsed = @doc.search(IDL_SELECTOR).map { |e| parse_idl(e.inner_text) }.compact
57
-
58
- implements = []
59
- @interfaces = []
60
-
61
- parsed.flatten.each do |element|
62
- case element
63
- when WebIDL::Ast::Interface
64
- @interfaces << element
65
- when WebIDL::Ast::ImplementsStatement
66
- implements << element
67
- end
3
+ module Base
4
+ class SpecExtractor
5
+ IDL_SELECTOR = "//pre[contains(@class, 'idl')]".freeze
6
+
7
+ class InterfaceNotFound < StandardError; end
8
+
9
+ def initialize(uri)
10
+ @uri = uri
11
+ end
12
+
13
+ def process
14
+ download_and_parse
15
+ extract_idl_parts
16
+ extract_interface_map
17
+ drop_issued_interfaces
18
+ build_result
19
+ rescue StandardError
20
+ p errors
21
+ raise
22
+ end
23
+
24
+ def errors
25
+ @errors ||= []
68
26
  end
69
27
 
70
- @interfaces_by_name = @interfaces.group_by(&:name)
71
- apply_implements(implements)
72
- merge_interfaces
73
- end
28
+ #
29
+ # returns a topoligically sorted array of WebIDL::Ast::Interface objects
30
+ #
74
31
 
75
- def extract_interface_map
76
- raise NotImplementedError
77
- end
32
+ def sorted_interfaces
33
+ process if @interfaces.nil?
78
34
 
79
- def drop_issued_interfaces
80
- @interface_map.delete_if do |_, interface|
81
- issued_interfaces.include?(interface)
35
+ idl_sorter.sort.map { |name|
36
+ @interfaces.find { |i| i.name == name } || puts("ignoring interface: #{name}")
37
+ }.compact
82
38
  end
83
- end
84
39
 
85
- def build_result
86
- raise NotImplementedError
87
- end
40
+ def print_hierarchy
41
+ process if @interfaces.nil?
42
+ idl_sorter.print
43
+ end
88
44
 
89
- def parse_idl(str)
90
- result = idl_parser.parse(str)
45
+ def fetch_interface(interface)
46
+ @interfaces_by_name[interface] || raise(InterfaceNotFound, "#{interface} not found in IDL")
47
+ end
48
+
49
+ private
91
50
 
92
- if result
93
- result.build
94
- else
95
- errors << idl_parser.failure_reason
96
- nil
51
+ def download_and_parse
52
+ URI.open(@uri) { |io| @doc = Nokogiri.HTML(io) }
97
53
  end
98
- end
99
54
 
100
- def apply_implements(implements)
101
- implements.each do |is|
102
- implementor_name = is.implementor.gsub(/^::/, '')
103
- implementee_name = is.implementee.gsub(/^::/, '')
55
+ def extract_idl_parts
56
+ parsed = @doc.search(IDL_SELECTOR).map { |e| parse_idl(e.inner_text) }.compact
57
+
58
+ implements = []
59
+ includes = []
60
+ @interfaces = []
61
+
62
+ parsed.flatten.each do |element|
63
+ case element
64
+ when WebIDL::Ast::Interface
65
+ @interfaces << element
66
+ when WebIDL::Ast::ImplementsStatement
67
+ implements << element
68
+ when WebIDL::Ast::IncludesStatement
69
+ includes << element
70
+ end
71
+ end
72
+
73
+ @interfaces_by_name = @interfaces.group_by(&:name)
74
+ apply_implements(implements)
75
+ apply_includes(includes)
76
+ merge_interfaces
77
+ end
78
+
79
+ def extract_interface_map
80
+ raise NotImplementedError
81
+ end
104
82
 
105
- begin
106
- intf = fetch_interface(implementor_name).first
107
- intf.implements << fetch_interface(implementee_name).first
108
- rescue InterfaceNotFound => ex
109
- puts ex.message
83
+ def drop_issued_interfaces
84
+ @interface_map.delete_if do |_, interface|
85
+ issued_interfaces.include?(interface)
110
86
  end
111
87
  end
112
- end
113
88
 
114
- def merge_interfaces
115
- non_duplicates = @interfaces.uniq(&:name)
116
- duplicates = @interfaces - non_duplicates
89
+ def build_result
90
+ raise NotImplementedError
91
+ end
92
+
93
+ def parse_idl(str)
94
+ result = idl_parser.parse(str)
95
+
96
+ if result
97
+ result.build
98
+ else
99
+ errors << idl_parser.failure_reason
100
+ nil
101
+ end
102
+ end
103
+
104
+ def apply_implements(implements)
105
+ implements.each do |is|
106
+ implementor_name = is.implementor.gsub(/^::/, '')
107
+ implementee_name = is.implementee.gsub(/^::/, '')
108
+
109
+ begin
110
+ intf = fetch_interface(implementor_name).first
111
+ intf.implements << fetch_interface(implementee_name).first
112
+ rescue InterfaceNotFound => ex
113
+ puts ex.message
114
+ end
115
+ end
116
+ end
117
117
 
118
- duplicates.each do |intf|
119
- final = non_duplicates.find { |i| i.name == intf.name }
120
- final.inherits += intf.inherits
121
- final.members += intf.members
122
- final.extended_attributes += intf.extended_attributes
118
+ def apply_includes(includes)
119
+ includes.each do |is|
120
+ includer_name = is.includer.gsub(/^::/, '')
121
+ includee_name = is.includee.gsub(/^::/, '')
122
+
123
+ begin
124
+ intf = fetch_interface(includer_name).first
125
+ intf.includes << fetch_interface(includee_name).first
126
+ rescue InterfaceNotFound => ex
127
+ puts ex.message
128
+ end
129
+ end
123
130
  end
124
131
 
125
- @interfaces = non_duplicates
126
- end
132
+ def merge_interfaces
133
+ non_duplicates = @interfaces.uniq(&:name)
134
+ duplicates = @interfaces - non_duplicates
127
135
 
128
- def idl_parser
129
- @idl_parser ||= WebIDL::Parser::IDLParser.new
130
- end
136
+ duplicates.each do |intf|
137
+ final = non_duplicates.find { |i| i.name == intf.name }
138
+ final.inherits += intf.inherits
139
+ final.members += intf.members
140
+ final.extended_attributes += intf.extended_attributes
141
+ end
131
142
 
132
- def sorter
133
- @idl_sorter ||= Base::IDLSorter.new(@interfaces)
134
- end
143
+ @interfaces = non_duplicates
144
+ end
135
145
 
136
- end # SpecExtractor
146
+ def idl_parser
147
+ @idl_parser ||= WebIDL::Parser::IDLParser.new
148
+ end
149
+
150
+ def idl_sorter
151
+ @idl_sorter ||= Base::IDLSorter.new(@interfaces)
152
+ end
153
+ end # SpecExtractor
154
+ end # Base
137
155
  end # Generator
138
156
  end # Watir