use blitz_dom::{Document, DocumentConfig};
use blitz_script::ScriptDocument;
fn doc_from_html(html: &str) -> ScriptDocument {
let mut doc = ScriptDocument::from_html(
html,
DocumentConfig {
viewport: Some(blitz_traits::shell::Viewport::new(
800,
600,
1.0,
blitz_traits::shell::ColorScheme::Light,
)),
..Default::default()
},
);
doc.inner_mut().resolve(0.0);
doc.execute_scripts();
doc
}
fn text_of(doc: &ScriptDocument, selector: &str) -> String {
let inner = doc.inner();
let node_id = inner
.query_selector(selector)
.unwrap()
.unwrap_or_else(|| panic!("no node matching {selector}"));
inner.get_node(node_id).unwrap().text_content()
}
const PICKER: &str = r#"
<select id="country">
<option value="us">United States</option>
<option value="fr" selected>France</option>
<option value="jp">Japan</option>
</select>
<div id="out"></div>
"#;
fn run(script: &str) -> String {
let doc = doc_from_html(&format!(
"<html><body>{PICKER}<script>const out = document.getElementById(\"out\");{script}</script></body></html>"
));
text_of(&doc, "#out")
}
#[test]
fn a_select_reports_the_selected_options_value() {
assert_eq!(
run(r#"out.textContent = document.getElementById("country").value;"#),
"fr"
);
}
#[test]
fn a_select_reports_its_selected_index() {
assert_eq!(
run(r#"out.textContent = String(document.getElementById("country").selectedIndex);"#),
"1"
);
}
#[test]
fn setting_value_moves_the_selection() {
assert_eq!(
run(r#"
const select = document.getElementById("country");
select.value = "jp";
out.textContent = select.value + ":" + select.selectedIndex;
"#),
"jp:2"
);
}
#[test]
fn setting_a_value_no_option_carries_clears_the_selection() {
assert_eq!(
run(r#"
const select = document.getElementById("country");
select.value = "nowhere";
out.textContent = "[" + select.value + "]:" + select.selectedIndex;
"#),
"[]:-1",
"a value no option carries deselects everything, and selectedIndex is then -1"
);
}
#[test]
fn setting_selected_index_moves_the_selection() {
assert_eq!(
run(r#"
const select = document.getElementById("country");
select.selectedIndex = 0;
out.textContent = select.value;
"#),
"us"
);
}
#[test]
fn options_lists_every_option_in_order() {
assert_eq!(
run(r#"
const select = document.getElementById("country");
out.textContent = select.options.map((o) => o.value).join(",");
"#),
"us,fr,jp"
);
}
#[test]
fn an_options_selected_property_reads_the_live_state() {
assert_eq!(
run(r#"
const select = document.getElementById("country");
out.textContent = select.options.map((o) => o.selected).join(",");
"#),
"false,true,false"
);
}
#[test]
fn setting_an_options_selected_property_moves_the_selection() {
assert_eq!(
run(r#"
const select = document.getElementById("country");
select.options[2].selected = true;
out.textContent = select.value + ":" + select.options.map((o) => o.selected).join(",");
"#),
"jp:false,false,true",
"selecting one option on a single select must clear the others"
);
}