Files
hemx/slhx-js/tests/runtime.rs
T
slhx agent 2db7ed7a3c feat(runtime): make techdemo interactions declarative
req: examples/005

req: htmx_equivalents/002

req: dx/008

req: form/002
2026-05-11 08:11:06 +02:00

106 lines
3.9 KiB
Rust

#[test]
fn runtime_posts_urlencoded_forms_by_default() {
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("new URLSearchParams()"));
assert!(source.contains("multipart/form-data"));
assert!(source.contains("const body = method === \"GET\" || method === \"HEAD\" ? undefined : requestBody(data, multipart)"));
assert!(source.contains("application/x-www-form-urlencoded;charset=UTF-8"));
}
#[test]
fn runtime_handles_get_forms_without_request_body() {
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("function requestUrl(form, data, method)"));
assert!(source.contains("method === \"GET\" || method === \"HEAD\" ? undefined : requestBody"));
assert!(source.contains("if (method === \"GET\") url.search = urlEncoded(data).toString()"));
}
#[test]
fn runtime_clicking_submitter_schedules_form_submit() {
// req: convention/004
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("const direct = closestInRoot(event.target, root, `[${HID}]`)"));
assert!(source.contains("button[type=submit], input[type=submit], button:not([type])"));
assert!(source.contains("form.reportValidity && !form.reportValidity()"));
assert!(source.contains("schedule(form, \"submit\")"));
}
#[test]
fn runtime_supports_drag_drop_params_without_user_js() {
// req: htmx_equivalents/002, req: dx/008
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("const dragKeys = new WeakMap()"));
assert!(source.contains("dragstart"));
assert!(source.contains("dragover"));
assert!(source.contains("eventName === \"drop\""));
assert!(source.contains("data.set(\"work_id\", dragKey)"));
}
#[test]
fn runtime_supports_queued_request_policy() {
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("const queues = new WeakMap()"));
assert!(source.contains("policy === \"queue\""));
assert!(source.contains("const base = queues.get(target) || active.done"));
}
#[test]
fn runtime_exposes_page_swap_hooks() {
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("data-slhx-nav"));
assert!(source.contains("data-slhx-boost"));
assert!(source.contains("history.pushState"));
assert!(source.contains("popstate"));
assert!(source.contains("x-slhx-title"));
assert!(source.contains("x-slhx-fingerprint"));
assert!(source.contains("slhx:missing-content-slot"));
assert!(source.contains("location.href = href"));
}
#[test]
fn runtime_page_swaps_lowered_slot_ids() {
// req: wire/001
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("function replaceLoweredSlots(scope, doc)"));
assert!(source.contains("doc.querySelectorAll(\"[data-sid], [data-slot-id]\")"));
assert!(source.contains("target.innerHTML = source.innerHTML"));
}
#[test]
fn runtime_keeps_form_field_targets_separate_from_error_targets() {
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("function fieldTarget(scope, id, field)"));
assert!(source.contains("[data-fid=\"${id}\"] [name=\"${escapedField}\"]"));
assert!(source.contains("function formErrorTarget(scope, id, field)"));
assert!(source.contains("[data-slhx-error-for=\"${escapedField}\"]"));
}
#[test]
fn runtime_preflights_batches_before_applying_ops() {
let source = slhx_js::RUNTIME_JS;
assert!(source.contains("const missingTarget = batch.ops.map((op) => canApplyOp(scope, op)).find(Boolean)"));
assert!(source.contains("function canApplyOp(scope, op)"));
assert!(source.contains("for (const op of batch.ops) applyOp(scope, op)"));
}
#[test]
fn runtime_ships_typescript_definitions() {
let source = slhx_js::RUNTIME_D_TS;
assert!(source.contains("req: ts/001"));
assert!(source.contains("export interface EffectBatch"));
assert!(source.contains("fingerprint: bigint"));
assert!(source.contains("export type Effect ="));
assert!(source.contains("decodeBatch(buffer: ArrayBuffer): EffectBatch"));
assert!(source.contains("interface Window"));
}