PageRenderTime 68ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/integration-tests/apps/rails2/frozen/vendor/rails/actionpack/test/controller/selector_test.rb

https://gitlab.com/meetly/torquebox
Ruby | 628 lines | 472 code | 72 blank | 84 comment | 0 complexity | 6c0f36d039d87206e4f11a03253bef90 MD5 | raw file
  1. #--
  2. # Copyright (c) 2006 Assaf Arkin (http://labnotes.org)
  3. # Under MIT and/or CC By license.
  4. #++
  5. require 'abstract_unit'
  6. require 'controller/fake_controllers'
  7. class SelectorTest < Test::Unit::TestCase
  8. #
  9. # Basic selector: element, id, class, attributes.
  10. #
  11. def test_element
  12. parse(%Q{<div id="1"></div><p></p><div id="2"></div>})
  13. # Match element by name.
  14. select("div")
  15. assert_equal 2, @matches.size
  16. assert_equal "1", @matches[0].attributes["id"]
  17. assert_equal "2", @matches[1].attributes["id"]
  18. # Not case sensitive.
  19. select("DIV")
  20. assert_equal 2, @matches.size
  21. assert_equal "1", @matches[0].attributes["id"]
  22. assert_equal "2", @matches[1].attributes["id"]
  23. # Universal match (all elements).
  24. select("*")
  25. assert_equal 3, @matches.size
  26. assert_equal "1", @matches[0].attributes["id"]
  27. assert_equal nil, @matches[1].attributes["id"]
  28. assert_equal "2", @matches[2].attributes["id"]
  29. end
  30. def test_identifier
  31. parse(%Q{<div id="1"></div><p></p><div id="2"></div>})
  32. # Match element by ID.
  33. select("div#1")
  34. assert_equal 1, @matches.size
  35. assert_equal "1", @matches[0].attributes["id"]
  36. # Match element by ID, substitute value.
  37. select("div#?", 2)
  38. assert_equal 1, @matches.size
  39. assert_equal "2", @matches[0].attributes["id"]
  40. # Element name does not match ID.
  41. select("p#?", 2)
  42. assert_equal 0, @matches.size
  43. # Use regular expression.
  44. select("#?", /\d/)
  45. assert_equal 2, @matches.size
  46. end
  47. def test_class_name
  48. parse(%Q{<div id="1" class=" foo "></div><p id="2" class=" foo bar "></p><div id="3" class="bar"></div>})
  49. # Match element with specified class.
  50. select("div.foo")
  51. assert_equal 1, @matches.size
  52. assert_equal "1", @matches[0].attributes["id"]
  53. # Match any element with specified class.
  54. select("*.foo")
  55. assert_equal 2, @matches.size
  56. assert_equal "1", @matches[0].attributes["id"]
  57. assert_equal "2", @matches[1].attributes["id"]
  58. # Match elements with other class.
  59. select("*.bar")
  60. assert_equal 2, @matches.size
  61. assert_equal "2", @matches[0].attributes["id"]
  62. assert_equal "3", @matches[1].attributes["id"]
  63. # Match only element with both class names.
  64. select("*.bar.foo")
  65. assert_equal 1, @matches.size
  66. assert_equal "2", @matches[0].attributes["id"]
  67. end
  68. def test_attribute
  69. parse(%Q{<div id="1"></div><p id="2" title="" bar="foo"></p><div id="3" title="foo"></div>})
  70. # Match element with attribute.
  71. select("div[title]")
  72. assert_equal 1, @matches.size
  73. assert_equal "3", @matches[0].attributes["id"]
  74. # Match any element with attribute.
  75. select("*[title]")
  76. assert_equal 2, @matches.size
  77. assert_equal "2", @matches[0].attributes["id"]
  78. assert_equal "3", @matches[1].attributes["id"]
  79. # Match element with attribute value.
  80. select("*[title=foo]")
  81. assert_equal 1, @matches.size
  82. assert_equal "3", @matches[0].attributes["id"]
  83. # Match element with attribute and attribute value.
  84. select("[bar=foo][title]")
  85. assert_equal 1, @matches.size
  86. assert_equal "2", @matches[0].attributes["id"]
  87. # Not case sensitive.
  88. select("[BAR=foo][TiTle]")
  89. assert_equal 1, @matches.size
  90. assert_equal "2", @matches[0].attributes["id"]
  91. end
  92. def test_attribute_quoted
  93. parse(%Q{<div id="1" title="foo"></div><div id="2" title="bar"></div><div id="3" title=" bar "></div>})
  94. # Match without quotes.
  95. select("[title = bar]")
  96. assert_equal 1, @matches.size
  97. assert_equal "2", @matches[0].attributes["id"]
  98. # Match with single quotes.
  99. select("[title = 'bar' ]")
  100. assert_equal 1, @matches.size
  101. assert_equal "2", @matches[0].attributes["id"]
  102. # Match with double quotes.
  103. select("[title = \"bar\" ]")
  104. assert_equal 1, @matches.size
  105. assert_equal "2", @matches[0].attributes["id"]
  106. # Match with spaces.
  107. select("[title = \" bar \" ]")
  108. assert_equal 1, @matches.size
  109. assert_equal "3", @matches[0].attributes["id"]
  110. end
  111. def test_attribute_equality
  112. parse(%Q{<div id="1" title="foo bar"></div><div id="2" title="barbaz"></div>})
  113. # Match (fail) complete value.
  114. select("[title=bar]")
  115. assert_equal 0, @matches.size
  116. # Match space-separate word.
  117. select("[title~=foo]")
  118. assert_equal 1, @matches.size
  119. assert_equal "1", @matches[0].attributes["id"]
  120. select("[title~=bar]")
  121. assert_equal 1, @matches.size
  122. assert_equal "1", @matches[0].attributes["id"]
  123. # Match beginning of value.
  124. select("[title^=ba]")
  125. assert_equal 1, @matches.size
  126. assert_equal "2", @matches[0].attributes["id"]
  127. # Match end of value.
  128. select("[title$=ar]")
  129. assert_equal 1, @matches.size
  130. assert_equal "1", @matches[0].attributes["id"]
  131. # Match text in value.
  132. select("[title*=bar]")
  133. assert_equal 2, @matches.size
  134. assert_equal "1", @matches[0].attributes["id"]
  135. assert_equal "2", @matches[1].attributes["id"]
  136. # Match first space separated word.
  137. select("[title|=foo]")
  138. assert_equal 1, @matches.size
  139. assert_equal "1", @matches[0].attributes["id"]
  140. select("[title|=bar]")
  141. assert_equal 0, @matches.size
  142. end
  143. #
  144. # Selector composition: groups, sibling, children
  145. #
  146. def test_selector_group
  147. parse(%Q{<h1 id="1"></h1><h2 id="2"></h2><h3 id="3"></h3>})
  148. # Simple group selector.
  149. select("h1,h3")
  150. assert_equal 2, @matches.size
  151. assert_equal "1", @matches[0].attributes["id"]
  152. assert_equal "3", @matches[1].attributes["id"]
  153. select("h1 , h3")
  154. assert_equal 2, @matches.size
  155. assert_equal "1", @matches[0].attributes["id"]
  156. assert_equal "3", @matches[1].attributes["id"]
  157. # Complex group selector.
  158. parse(%Q{<h1 id="1"><a href="foo"></a></h1><h2 id="2"><a href="bar"></a></h2><h3 id="2"><a href="baz"></a></h3>})
  159. select("h1 a, h3 a")
  160. assert_equal 2, @matches.size
  161. assert_equal "foo", @matches[0].attributes["href"]
  162. assert_equal "baz", @matches[1].attributes["href"]
  163. # And now for the three selector challenge.
  164. parse(%Q{<h1 id="1"><a href="foo"></a></h1><h2 id="2"><a href="bar"></a></h2><h3 id="2"><a href="baz"></a></h3>})
  165. select("h1 a, h2 a, h3 a")
  166. assert_equal 3, @matches.size
  167. assert_equal "foo", @matches[0].attributes["href"]
  168. assert_equal "bar", @matches[1].attributes["href"]
  169. assert_equal "baz", @matches[2].attributes["href"]
  170. end
  171. def test_sibling_selector
  172. parse(%Q{<h1 id="1"></h1><h2 id="2"></h2><h3 id="3"></h3>})
  173. # Test next sibling.
  174. select("h1+*")
  175. assert_equal 1, @matches.size
  176. assert_equal "2", @matches[0].attributes["id"]
  177. select("h1+h2")
  178. assert_equal 1, @matches.size
  179. assert_equal "2", @matches[0].attributes["id"]
  180. select("h1+h3")
  181. assert_equal 0, @matches.size
  182. select("*+h3")
  183. assert_equal 1, @matches.size
  184. assert_equal "3", @matches[0].attributes["id"]
  185. # Test any sibling.
  186. select("h1~*")
  187. assert_equal 2, @matches.size
  188. assert_equal "2", @matches[0].attributes["id"]
  189. assert_equal "3", @matches[1].attributes["id"]
  190. select("h2~*")
  191. assert_equal 1, @matches.size
  192. assert_equal "3", @matches[0].attributes["id"]
  193. end
  194. def test_children_selector
  195. parse(%Q{<div><p id="1"><span id="2"></span></p></div><div><p id="3"><span id="4" class="foo"></span></p></div>})
  196. # Test child selector.
  197. select("div>p")
  198. assert_equal 2, @matches.size
  199. assert_equal "1", @matches[0].attributes["id"]
  200. assert_equal "3", @matches[1].attributes["id"]
  201. select("div>span")
  202. assert_equal 0, @matches.size
  203. select("div>p#3")
  204. assert_equal 1, @matches.size
  205. assert_equal "3", @matches[0].attributes["id"]
  206. select("div>p>span")
  207. assert_equal 2, @matches.size
  208. assert_equal "2", @matches[0].attributes["id"]
  209. assert_equal "4", @matches[1].attributes["id"]
  210. # Test descendant selector.
  211. select("div p")
  212. assert_equal 2, @matches.size
  213. assert_equal "1", @matches[0].attributes["id"]
  214. assert_equal "3", @matches[1].attributes["id"]
  215. select("div span")
  216. assert_equal 2, @matches.size
  217. assert_equal "2", @matches[0].attributes["id"]
  218. assert_equal "4", @matches[1].attributes["id"]
  219. select("div *#3")
  220. assert_equal 1, @matches.size
  221. assert_equal "3", @matches[0].attributes["id"]
  222. select("div *#4")
  223. assert_equal 1, @matches.size
  224. assert_equal "4", @matches[0].attributes["id"]
  225. # This is here because it failed before when whitespaces
  226. # were not properly stripped.
  227. select("div .foo")
  228. assert_equal 1, @matches.size
  229. assert_equal "4", @matches[0].attributes["id"]
  230. end
  231. #
  232. # Pseudo selectors: root, nth-child, empty, content, etc
  233. #
  234. def test_root_selector
  235. parse(%Q{<div id="1"><div id="2"></div></div>})
  236. # Can only find element if it's root.
  237. select(":root")
  238. assert_equal 1, @matches.size
  239. assert_equal "1", @matches[0].attributes["id"]
  240. select("#1:root")
  241. assert_equal 1, @matches.size
  242. assert_equal "1", @matches[0].attributes["id"]
  243. select("#2:root")
  244. assert_equal 0, @matches.size
  245. # Opposite for nth-child.
  246. select("#1:nth-child(1)")
  247. assert_equal 0, @matches.size
  248. end
  249. def test_nth_child_odd_even
  250. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  251. # Test odd nth children.
  252. select("tr:nth-child(odd)")
  253. assert_equal 2, @matches.size
  254. assert_equal "1", @matches[0].attributes["id"]
  255. assert_equal "3", @matches[1].attributes["id"]
  256. # Test even nth children.
  257. select("tr:nth-child(even)")
  258. assert_equal 2, @matches.size
  259. assert_equal "2", @matches[0].attributes["id"]
  260. assert_equal "4", @matches[1].attributes["id"]
  261. end
  262. def test_nth_child_a_is_zero
  263. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  264. # Test the third child.
  265. select("tr:nth-child(0n+3)")
  266. assert_equal 1, @matches.size
  267. assert_equal "3", @matches[0].attributes["id"]
  268. # Same but an can be omitted when zero.
  269. select("tr:nth-child(3)")
  270. assert_equal 1, @matches.size
  271. assert_equal "3", @matches[0].attributes["id"]
  272. # Second element (but not every second element).
  273. select("tr:nth-child(0n+2)")
  274. assert_equal 1, @matches.size
  275. assert_equal "2", @matches[0].attributes["id"]
  276. # Before first and past last returns nothing.:
  277. assert_raise(ArgumentError) { select("tr:nth-child(-1)") }
  278. select("tr:nth-child(0)")
  279. assert_equal 0, @matches.size
  280. select("tr:nth-child(5)")
  281. assert_equal 0, @matches.size
  282. end
  283. def test_nth_child_a_is_one
  284. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  285. # a is group of one, pick every element in group.
  286. select("tr:nth-child(1n+0)")
  287. assert_equal 4, @matches.size
  288. # Same but a can be omitted when one.
  289. select("tr:nth-child(n+0)")
  290. assert_equal 4, @matches.size
  291. # Same but b can be omitted when zero.
  292. select("tr:nth-child(n)")
  293. assert_equal 4, @matches.size
  294. end
  295. def test_nth_child_b_is_zero
  296. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  297. # If b is zero, pick the n-th element (here each one).
  298. select("tr:nth-child(n+0)")
  299. assert_equal 4, @matches.size
  300. # If b is zero, pick the n-th element (here every second).
  301. select("tr:nth-child(2n+0)")
  302. assert_equal 2, @matches.size
  303. assert_equal "1", @matches[0].attributes["id"]
  304. assert_equal "3", @matches[1].attributes["id"]
  305. # If a and b are both zero, no element selected.
  306. select("tr:nth-child(0n+0)")
  307. assert_equal 0, @matches.size
  308. select("tr:nth-child(0)")
  309. assert_equal 0, @matches.size
  310. end
  311. def test_nth_child_a_is_negative
  312. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  313. # Since a is -1, picks the first three elements.
  314. select("tr:nth-child(-n+3)")
  315. assert_equal 3, @matches.size
  316. assert_equal "1", @matches[0].attributes["id"]
  317. assert_equal "2", @matches[1].attributes["id"]
  318. assert_equal "3", @matches[2].attributes["id"]
  319. # Since a is -2, picks the first in every second of first four elements.
  320. select("tr:nth-child(-2n+3)")
  321. assert_equal 2, @matches.size
  322. assert_equal "1", @matches[0].attributes["id"]
  323. assert_equal "3", @matches[1].attributes["id"]
  324. # Since a is -2, picks the first in every second of first three elements.
  325. select("tr:nth-child(-2n+2)")
  326. assert_equal 1, @matches.size
  327. assert_equal "1", @matches[0].attributes["id"]
  328. end
  329. def test_nth_child_b_is_negative
  330. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  331. # Select last of four.
  332. select("tr:nth-child(4n-1)")
  333. assert_equal 1, @matches.size
  334. assert_equal "4", @matches[0].attributes["id"]
  335. # Select first of four.
  336. select("tr:nth-child(4n-4)")
  337. assert_equal 1, @matches.size
  338. assert_equal "1", @matches[0].attributes["id"]
  339. # Select last of every second.
  340. select("tr:nth-child(2n-1)")
  341. assert_equal 2, @matches.size
  342. assert_equal "2", @matches[0].attributes["id"]
  343. assert_equal "4", @matches[1].attributes["id"]
  344. # Select nothing since an+b always < 0
  345. select("tr:nth-child(-1n-1)")
  346. assert_equal 0, @matches.size
  347. end
  348. def test_nth_child_substitution_values
  349. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  350. # Test with ?n?.
  351. select("tr:nth-child(?n?)", 2, 1)
  352. assert_equal 2, @matches.size
  353. assert_equal "1", @matches[0].attributes["id"]
  354. assert_equal "3", @matches[1].attributes["id"]
  355. select("tr:nth-child(?n?)", 2, 2)
  356. assert_equal 2, @matches.size
  357. assert_equal "2", @matches[0].attributes["id"]
  358. assert_equal "4", @matches[1].attributes["id"]
  359. select("tr:nth-child(?n?)", 4, 2)
  360. assert_equal 1, @matches.size
  361. assert_equal "2", @matches[0].attributes["id"]
  362. # Test with ? (b only).
  363. select("tr:nth-child(?)", 3)
  364. assert_equal 1, @matches.size
  365. assert_equal "3", @matches[0].attributes["id"]
  366. select("tr:nth-child(?)", 5)
  367. assert_equal 0, @matches.size
  368. end
  369. def test_nth_last_child
  370. parse(%Q{<table><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  371. # Last two elements.
  372. select("tr:nth-last-child(-n+2)")
  373. assert_equal 2, @matches.size
  374. assert_equal "3", @matches[0].attributes["id"]
  375. assert_equal "4", @matches[1].attributes["id"]
  376. # All old elements counting from last one.
  377. select("tr:nth-last-child(odd)")
  378. assert_equal 2, @matches.size
  379. assert_equal "2", @matches[0].attributes["id"]
  380. assert_equal "4", @matches[1].attributes["id"]
  381. end
  382. def test_nth_of_type
  383. parse(%Q{<table><thead></thead><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  384. # First two elements.
  385. select("tr:nth-of-type(-n+2)")
  386. assert_equal 2, @matches.size
  387. assert_equal "1", @matches[0].attributes["id"]
  388. assert_equal "2", @matches[1].attributes["id"]
  389. # All old elements counting from last one.
  390. select("tr:nth-last-of-type(odd)")
  391. assert_equal 2, @matches.size
  392. assert_equal "2", @matches[0].attributes["id"]
  393. assert_equal "4", @matches[1].attributes["id"]
  394. end
  395. def test_first_and_last
  396. parse(%Q{<table><thead></thead><tr id="1"></tr><tr id="2"></tr><tr id="3"></tr><tr id="4"></tr></table>})
  397. # First child.
  398. select("tr:first-child")
  399. assert_equal 0, @matches.size
  400. select(":first-child")
  401. assert_equal 1, @matches.size
  402. assert_equal "thead", @matches[0].name
  403. # First of type.
  404. select("tr:first-of-type")
  405. assert_equal 1, @matches.size
  406. assert_equal "1", @matches[0].attributes["id"]
  407. select("thead:first-of-type")
  408. assert_equal 1, @matches.size
  409. assert_equal "thead", @matches[0].name
  410. select("div:first-of-type")
  411. assert_equal 0, @matches.size
  412. # Last child.
  413. select("tr:last-child")
  414. assert_equal 1, @matches.size
  415. assert_equal "4", @matches[0].attributes["id"]
  416. # Last of type.
  417. select("tr:last-of-type")
  418. assert_equal 1, @matches.size
  419. assert_equal "4", @matches[0].attributes["id"]
  420. select("thead:last-of-type")
  421. assert_equal 1, @matches.size
  422. assert_equal "thead", @matches[0].name
  423. select("div:last-of-type")
  424. assert_equal 0, @matches.size
  425. end
  426. def test_first_and_last
  427. # Only child.
  428. parse(%Q{<table><tr></tr></table>})
  429. select("table:only-child")
  430. assert_equal 0, @matches.size
  431. select("tr:only-child")
  432. assert_equal 1, @matches.size
  433. assert_equal "tr", @matches[0].name
  434. parse(%Q{<table><tr></tr><tr></tr></table>})
  435. select("tr:only-child")
  436. assert_equal 0, @matches.size
  437. # Only of type.
  438. parse(%Q{<table><thead></thead><tr></tr><tr></tr></table>})
  439. select("thead:only-of-type")
  440. assert_equal 1, @matches.size
  441. assert_equal "thead", @matches[0].name
  442. select("td:only-of-type")
  443. assert_equal 0, @matches.size
  444. end
  445. def test_empty
  446. parse(%Q{<table><tr></tr></table>})
  447. select("table:empty")
  448. assert_equal 0, @matches.size
  449. select("tr:empty")
  450. assert_equal 1, @matches.size
  451. parse(%Q{<div> </div>})
  452. select("div:empty")
  453. assert_equal 1, @matches.size
  454. end
  455. def test_content
  456. parse(%Q{<div> </div>})
  457. select("div:content()")
  458. assert_equal 1, @matches.size
  459. parse(%Q{<div>something </div>})
  460. select("div:content()")
  461. assert_equal 0, @matches.size
  462. select("div:content(something)")
  463. assert_equal 1, @matches.size
  464. select("div:content( 'something' )")
  465. assert_equal 1, @matches.size
  466. select("div:content( \"something\" )")
  467. assert_equal 1, @matches.size
  468. select("div:content(?)", "something")
  469. assert_equal 1, @matches.size
  470. select("div:content(?)", /something/)
  471. assert_equal 1, @matches.size
  472. end
  473. #
  474. # Test negation.
  475. #
  476. def test_element_negation
  477. parse(%Q{<p></p><div></div>})
  478. select("*")
  479. assert_equal 2, @matches.size
  480. select("*:not(p)")
  481. assert_equal 1, @matches.size
  482. assert_equal "div", @matches[0].name
  483. select("*:not(div)")
  484. assert_equal 1, @matches.size
  485. assert_equal "p", @matches[0].name
  486. select("*:not(span)")
  487. assert_equal 2, @matches.size
  488. end
  489. def test_id_negation
  490. parse(%Q{<p id="1"></p><p id="2"></p>})
  491. select("p")
  492. assert_equal 2, @matches.size
  493. select(":not(#1)")
  494. assert_equal 1, @matches.size
  495. assert_equal "2", @matches[0].attributes["id"]
  496. select(":not(#2)")
  497. assert_equal 1, @matches.size
  498. assert_equal "1", @matches[0].attributes["id"]
  499. end
  500. def test_class_name_negation
  501. parse(%Q{<p class="foo"></p><p class="bar"></p>})
  502. select("p")
  503. assert_equal 2, @matches.size
  504. select(":not(.foo)")
  505. assert_equal 1, @matches.size
  506. assert_equal "bar", @matches[0].attributes["class"]
  507. select(":not(.bar)")
  508. assert_equal 1, @matches.size
  509. assert_equal "foo", @matches[0].attributes["class"]
  510. end
  511. def test_attribute_negation
  512. parse(%Q{<p title="foo"></p><p title="bar"></p>})
  513. select("p")
  514. assert_equal 2, @matches.size
  515. select(":not([title=foo])")
  516. assert_equal 1, @matches.size
  517. assert_equal "bar", @matches[0].attributes["title"]
  518. select(":not([title=bar])")
  519. assert_equal 1, @matches.size
  520. assert_equal "foo", @matches[0].attributes["title"]
  521. end
  522. def test_pseudo_class_negation
  523. parse(%Q{<div><p id="1"></p><p id="2"></p></div>})
  524. select("p")
  525. assert_equal 2, @matches.size
  526. select("p:not(:first-child)")
  527. assert_equal 1, @matches.size
  528. assert_equal "2", @matches[0].attributes["id"]
  529. select("p:not(:nth-child(2))")
  530. assert_equal 1, @matches.size
  531. assert_equal "1", @matches[0].attributes["id"]
  532. end
  533. def test_negation_details
  534. parse(%Q{<p id="1"></p><p id="2"></p><p id="3"></p>})
  535. assert_raise(ArgumentError) { select(":not(") }
  536. assert_raise(ArgumentError) { select(":not(:not())") }
  537. select("p:not(#1):not(#3)")
  538. assert_equal 1, @matches.size
  539. assert_equal "2", @matches[0].attributes["id"]
  540. end
  541. def test_select_from_element
  542. parse(%Q{<div><p id="1"></p><p id="2"></p></div>})
  543. select("div")
  544. @matches = @matches[0].select("p")
  545. assert_equal 2, @matches.size
  546. assert_equal "1", @matches[0].attributes["id"]
  547. assert_equal "2", @matches[1].attributes["id"]
  548. end
  549. protected
  550. def parse(html)
  551. @html = HTML::Document.new(html).root
  552. end
  553. def select(*selector)
  554. @matches = HTML.selector(*selector).select(@html)
  555. end
  556. end