Skip to content

Commit

Permalink
Fix the usage of type selector in :has() (#57)
Browse files Browse the repository at this point in the history
The descendants function also includes text nodes,
which causes name node calls to fail down the line,
because it only expects an `Element of n, not
`Text of string, which a text node is.

In any case, :has() doesn't select text nodes. So,
excluding them beforehand is the way to go.
  • Loading branch information
jbhoot committed Aug 21, 2024
1 parent e3d6cbb commit 6c05f4d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/soup.ml
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ struct
| Content s -> texts node |> String.concat "" |> has_substring s
| Has selector ->
descendants node
|> filter (fun descendant -> not (is_text descendant))
|> filter (fun descendant -> matches_simple_selector descendant selector)
|> count
|> fun count -> count > 0
Expand Down
27 changes: 17 additions & 10 deletions test/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let suites = [
("parse-select-list" >:: fun _ ->
let soup = page "list" |> parse in
let test selector expected_count =
assert_equal ~msg:selector
assert_equal ~msg:selector ~printer:string_of_int
(soup |> select selector |> count) expected_count
in

Expand Down Expand Up @@ -122,11 +122,14 @@ let suites = [
test "p:empty" 1;
test "ul li:not(:nth-child(1))" 2;
test ":not(ul) > li" 2;
test ":has([id=one])" 3;
test ":has(#one)" 3;
test "ul:has([id=one])" 1;
test "ol:has([id=one])" 0;
test "ol:has(#one)" 0;
test "li:has([id=one])" 0;
test ":has(.odd)" 4;
test "ul:has(.even)" 1;
test ":has(ul)" 2;
test ":has(caption)" 0;
test
("html:root > body.lists[class~=lists] > ul > li#one:nth-child(1) " ^
"+ li#two")
Expand All @@ -135,7 +138,7 @@ let suites = [
("parse-select-quoted" >:: fun _ ->
let soup = page "quoted" |> parse in
let test selector expected_count =
assert_equal ~msg:selector
assert_equal ~msg:selector ~printer:string_of_int
(soup |> select selector |> count) expected_count
in

Expand Down Expand Up @@ -182,7 +185,7 @@ let suites = [
("parse-select-escaped" >:: fun _ ->
let soup = page "quoted" |> parse in
let test selector expected_count =
assert_equal ~msg:selector
assert_equal ~msg:selector ~printer:string_of_int
(soup |> select selector |> count) expected_count
in

Expand All @@ -203,7 +206,8 @@ let suites = [
("parse-select-html5" >:: fun _ ->
let soup = page "html5" |> parse in
let test selector expected_count =
assert_equal ~msg:selector (soup $$ selector |> count) expected_count
assert_equal ~msg:selector ~printer:string_of_int
(soup $$ selector |> count) expected_count
in

test "nav" 1;
Expand All @@ -215,7 +219,8 @@ let suites = [
test "footer" 1);

("parse-select-google" >:: fun _ ->
assert_equal (page "google" |> parse $$ "form[action]" |> count) 1);
assert_equal ~printer:string_of_int
(page "google" |> parse $$ "form[action]" |> count) 1);

("parse-error" >:: fun _ ->
let soup = parse "<p></p>" in
Expand Down Expand Up @@ -285,7 +290,7 @@ let suites = [
("generalized-select" >:: fun _ ->
let soup = page "list" |> parse in
let test root selector expected_count =
assert_equal ~msg:selector
assert_equal ~msg:selector ~printer:string_of_int
(root |> select selector |> count) expected_count
in

Expand All @@ -298,7 +303,8 @@ let suites = [

("select-attribute-operators" >:: fun _ ->
let soup = "<form action=\"/continue\"></form>" |> parse in
assert_equal (soup $$ "form[action=/continue]" |> count) 1);
assert_equal ~printer:string_of_int
(soup $$ "form[action=/continue]" |> count) 1);

("select_one" >:: fun _ ->
let soup = page "list" |> parse in
Expand Down Expand Up @@ -378,7 +384,8 @@ let suites = [
("matches-selector" >:: fun _ ->
let soup = parse "<div> <p id='foo'>bar</p> </div>" in
let elem = select_one "div p#foo" soup |> unwrap_option in
assert_bool "element matches selector" (matches_selector soup "div p#foo" elem)
assert_bool "element matches selector"
(matches_selector soup "div p#foo" elem)
);

("fold_attributes" >:: fun _ ->
Expand Down

0 comments on commit 6c05f4d

Please sign in to comment.