104 lines
5.0 KiB
Rust
104 lines
5.0 KiB
Rust
mod support;
|
|
use support::{checked, rejected, sources, stdout};
|
|
|
|
const ROUTE: &str = r#"
|
|
route(request: dever.http.Request, reply: dever.system.HttpReply) () recover("connection policy") {
|
|
dever.sse.start(reply, [])
|
|
dever.sse.send(reply, dever.sse.Event { event = "tick"
|
|
data = "hello"
|
|
id = "1"
|
|
retry_ms = 1000 })
|
|
}
|
|
public start(listener: dever.system.Listener) () {
|
|
dever.http.serve_live(route, listener, dever.http.default_limits(), dever.http.default_live_limits())
|
|
}
|
|
"#;
|
|
|
|
#[test]
|
|
fn live_handler_contract_and_transitive_effects_are_checked() {
|
|
let source = ROUTE;
|
|
let map = sources(source);
|
|
let program = checked(&map);
|
|
let api = program.api_snapshot();
|
|
let start = api
|
|
.lines()
|
|
.find(|line| line.starts_with("function main.start"))
|
|
.unwrap();
|
|
assert!(
|
|
start.contains("network")
|
|
&& start.contains("concurrency")
|
|
&& start.contains("connection policy"),
|
|
"{start}"
|
|
);
|
|
rejected(
|
|
&source.replace("dever.system.HttpReply) ()", "dever.system.Socket) ()"),
|
|
"expected",
|
|
);
|
|
rejected(
|
|
&source.replace(
|
|
" dever.sse.start",
|
|
" dever.io.println(\"blocked\")\n dever.sse.start",
|
|
),
|
|
"cannot run inline",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn live_example_checks_and_formats_idempotently() {
|
|
let source = include_str!("../../../examples/old/dever/live_http/module/main.dever");
|
|
let map = sources(source);
|
|
checked(&map);
|
|
let first = dever_core::format::format(&map.files()[0]).unwrap();
|
|
let second = sources(&first);
|
|
assert_eq!(
|
|
dever_core::format::format(&second.files()[0]).unwrap(),
|
|
first
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn native_live_server_and_client_cover_stream_sse_and_websocket_resources() {
|
|
let example = include_str!("../../../examples/old/dever/live_http/module/main.dever");
|
|
let routes = example.split("\nmain() () {").next().unwrap();
|
|
let program = format!(
|
|
r#"{routes}
|
|
checked_response(result: dever.http.ResponseResult.Read(response), expected: Bytes) (ok: Bool) recover("test reports response errors") {{ ok = response.status == 200 and response.body == expected }}
|
|
checked_response(result: dever.http.ResponseResult.Failed(message), expected: Bytes) (ok: Bool) recover("test reports response errors") {{ ok = false }}
|
|
fetch(port: Int, target: Text, expected: Bytes) (ok: Bool) {{
|
|
request = dever.http.Request {{ method = "GET"
|
|
target = target
|
|
headers = [dever.http.header("Host", "test")]
|
|
body = dever.bytes.from_text("") }}
|
|
ok = checked_response(result(dever.http.send("127.0.0.1", port, request, dever.http.default_limits())), expected)
|
|
}}
|
|
received(result: dever.websocket.ReceiveResult.Done(state)) (ok: Bool) recover("test reports socket errors") {{ ok = received_state(state) }}
|
|
received(result: other) (ok: Bool) recover("test reports socket errors") {{ ok = false }}
|
|
received_state(state: dever.websocket.ReceiveState.Read(message)) (ok: Bool) {{ ok = text_message(message) }}
|
|
received_state(state: other) (ok: Bool) {{ ok = false }}
|
|
text_message(message: dever.websocket.Message.Text(value)) (ok: Bool) {{ ok = value == "native" }}
|
|
text_message(message: other) (ok: Bool) {{ ok = false }}
|
|
connected(result: dever.websocket.ConnectResult.Connected(socket)) (ok: Bool) recover("test reports socket errors") {{
|
|
dever.websocket.send(socket, dever.websocket.Message.Text("native"))
|
|
ok = received(result(dever.websocket.receive(socket)))
|
|
dever.websocket.close(socket, 1000, "done")
|
|
}}
|
|
connected(result: dever.websocket.ConnectResult.Failed(message)) (ok: Bool) recover("test reports socket errors") {{ ok = false }}
|
|
bound(result: dever.net.PortResult.Bound(port), listener: dever.system.Listener) (ok: Bool) recover("test reports startup errors") {{
|
|
server = run(dever.http.serve_live(route, listener, dever.http.default_limits(), dever.http.default_live_limits()))
|
|
normal = fetch(port, "/", dever.bytes.from_text("Dever: /stream, /events, /ws"))
|
|
stream = fetch(port, "/stream", dever.bytes.from_text("first\nsecond\n"))
|
|
events = fetch(port, "/events", dever.bytes.from_text("event: tick\nid: 1\nretry: 1000\ndata: 1\n\nevent: tick\nid: 2\nretry: 1000\ndata: 2\n\nevent: tick\nid: 3\nretry: 1000\ndata: 3\n\n"))
|
|
websocket = connected(result(dever.websocket.connect("127.0.0.1", port, "/ws", dever.websocket.default_limits())))
|
|
ok = normal and stream and events and websocket
|
|
stop(server)
|
|
dever.net.close_listener(listener)
|
|
}}
|
|
bound(result: dever.net.PortResult.Failed(message), listener: dever.system.Listener) (ok: Bool) recover("test reports startup errors") {{ ok = false }}
|
|
listening(result: dever.net.ListenResult.Listening(listener)) (ok: Bool) recover("test reports startup errors") {{ ok = bound(result(dever.net.port(listener)), listener) }}
|
|
listening(result: dever.net.ListenResult.Failed(message)) (ok: Bool) recover("test reports startup errors") {{ ok = false }}
|
|
main() (ok: Bool) {{ ok = listening(result(dever.net.listen("127.0.0.1", 0))) }}
|
|
"#
|
|
);
|
|
assert_eq!(stdout(&program), "ok = true\n");
|
|
}
|