use skyscraper::html::{self, grammar::document_builder::DocumentBuilder};
use crate::test_framework;
#[test]
fn select_basic_options() {
let text =
r#"<html><head></head><body><select><option>A</option><option>B</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select
.add_element("option", |opt| opt.add_text("A"))
.add_element("option", |opt| opt.add_text("B"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_optgroup_with_options() {
let text = r#"<html><head></head><body><select><optgroup label="fruits"><option>Apple</option><option>Banana</option></optgroup></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("optgroup", |og| {
og.add_attribute_str("label", "fruits")
.add_element("option", |opt| opt.add_text("Apple"))
.add_element("option", |opt| opt.add_text("Banana"))
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_multiple_optgroups() {
let text = r#"<html><head></head><body><select><optgroup label="a"><option>1</option></optgroup><optgroup label="b"><option>2</option></optgroup></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select
.add_element("optgroup", |og| {
og.add_attribute_str("label", "a")
.add_element("option", |opt| opt.add_text("1"))
})
.add_element("optgroup", |og| {
og.add_attribute_str("label", "b")
.add_element("option", |opt| opt.add_text("2"))
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_option_closes_previous_option() {
let text = r#"<html><head></head><body><select><option>A<option>B</select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select
.add_element("option", |opt| opt.add_text("A"))
.add_element("option", |opt| opt.add_text("B"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_optgroup_closes_option_and_optgroup() {
let text = r#"<html><head></head><body><select><optgroup><option>A<optgroup><option>B</optgroup></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select
.add_element("optgroup", |og| {
og.add_element("option", |opt| opt.add_text("A"))
})
.add_element("optgroup", |og| {
og.add_element("option", |opt| opt.add_text("B"))
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_end_optgroup_pops_option_then_optgroup() {
let text = r#"<html><head></head><body><select><optgroup><option>A</optgroup></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("optgroup", |og| {
og.add_element("option", |opt| opt.add_text("A"))
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_nested_select_closes_first() {
let text = r#"<html><head></head><body><select><option>A</option><select><option>B</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
.add_element("option", |opt| opt.add_text("B"))
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_text_content() {
let text = r#"<html><head></head><body><select>some text</select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| select.add_text("some text"))
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_comment() {
let text =
r#"<html><head></head><body><select><!-- comment --></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| select.add_comment(" comment "))
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_input_closes_select() {
let text = r#"<html><head></head><body><select><option>A</option><input type="text"></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
.add_element("input", |input| input.add_attribute_str("type", "text"))
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_empty() {
let text = r#"<html><head></head><body><select></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| body.add_element("select", |select| select))
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_hr_element() {
let text = r#"<html><head></head><body><select><option>A</option><hr><option>B</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select
.add_element("option", |opt| opt.add_text("A"))
.add_element("hr", |hr| hr)
.add_element("option", |opt| opt.add_text("B"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_eof() {
let text = r#"<html><head></head><body><select><option>A"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_textarea_closes_select() {
let text = r#"<html><head></head><body><select><option>A</option><textarea>text</textarea></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
.add_element("textarea", |ta| ta.add_text("text"))
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_in_table_cell() {
let text = r#"<html><head></head><body><table><tr><td><select><option>A</option></select></td></tr></table></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("table", |table| {
table.add_element("tbody", |tbody| {
tbody.add_element("tr", |tr| {
tr.add_element("td", |td| {
td.add_element("select", |select| {
select
.add_element("option", |opt| opt.add_text("A"))
})
})
})
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_in_table_table_start_closes_select() {
let text = r#"<html><head></head><body><table><tr><td><select><option>A</option><table></table></select></td></tr></table></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("table", |table| {
table.add_element("tbody", |tbody| {
tbody.add_element("tr", |tr| {
tr.add_element("td", |td| {
td.add_element("select", |select| {
select
.add_element("option", |opt| opt.add_text("A"))
})
.add_element("table", |t| t)
})
})
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_with_attributes() {
let text = r#"<html><head></head><body><select name="color" id="sel"><option value="r">Red</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select
.add_attribute_str("name", "color")
.add_attribute_str("id", "sel")
.add_element("option", |opt| {
opt.add_attribute_str("value", "r").add_text("Red")
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_ignores_unexpected_tags() {
let text = r#"<html><head></head><body><select><div>text</div><option>A</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select
.add_text("text")
.add_element("option", |opt| opt.add_text("A"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn option_in_body_outside_select() {
let text = r#"<html><head></head><body><option>A</option><option>B</option></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("option", |opt| opt.add_text("A"))
.add_element("option", |opt| opt.add_text("B"))
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_end_optgroup_parse_error_when_not_optgroup() {
let text = r#"<html><head></head><body><select></optgroup><option>A</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_end_option_parse_error_when_not_option() {
let text = r#"<html><head></head><body><select></option><option>A</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_null_character_ignored() {
let text = "<html><head></head><body><select>\0<option>A</option></select></body></html>";
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_doctype_ignored() {
let text =
r#"<html><head></head><body><select><!DOCTYPE html><option>A</option></select></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("select", |select| {
select.add_element("option", |opt| opt.add_text("A"))
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}
#[test]
fn select_in_table_end_tag_not_in_scope_ignored() {
let text = r#"<html><head></head><body><table><tr><td><select></caption><option>A</option></select></td></tr></table></body></html>"#;
let document = html::parse(text).unwrap();
let expected = DocumentBuilder::new()
.add_element("html", |html| {
html.add_element("head", |head| head)
.add_element("body", |body| {
body.add_element("table", |table| {
table.add_element("tbody", |tbody| {
tbody.add_element("tr", |tr| {
tr.add_element("td", |td| {
td.add_element("select", |select| {
select
.add_element("option", |opt| opt.add_text("A"))
})
})
})
})
})
})
})
.build()
.unwrap();
assert!(test_framework::compare_documents(expected, document, true));
}