Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,37 @@
|
||||
use super::*;
|
||||
|
||||
const LIVE: &str = "route(request: dever.http.Request, reply: dever.system.HttpReply) () { dever.sse.start(reply, [])\ndever.sse.send(reply, dever.sse.Event { event = \"tick\", data = request.target, id = null, retry_ms = 10 }) }\nmain(listener: dever.system.Listener) () { dever.http.serveLive(route, listener, dever.http.defaultLimits(), dever.http.defaultLiveLimits()) }";
|
||||
|
||||
#[test]
|
||||
fn live_static_handler_shapes_effects_and_metadata_are_checked() {
|
||||
let program = linked(LIVE).unwrap();
|
||||
let main = program
|
||||
.functions
|
||||
.iter()
|
||||
.find(|function| function.signature.name == "main")
|
||||
.unwrap();
|
||||
assert!(
|
||||
main.signature.effects.network
|
||||
&& main.signature.effects.schedule
|
||||
&& main.signature.effects.suspend
|
||||
);
|
||||
for (source, code) in [
|
||||
(LIVE.replace("reply: dever.system.HttpReply", "reply: dever.system.Socket"), "C005"),
|
||||
(LIVE.replace("dever.sse.start(reply, [])", "dever.io.println(\"blocked\")\ndever.sse.start(reply, [])"), "C013"),
|
||||
("main(reply: dever.system.HttpReply) (same: Bool) { same = reply == reply }".into(), "C005"),
|
||||
("main(reply: dever.system.HttpReply) () { lost = result(dever.http.write(reply, dever.bytes.fromText(\"x\"))) }".into(), "C012"),
|
||||
("main(reply: dever.system.HttpReply) () { dever.system.httpFinish(reply) }".into(), "C006"),
|
||||
] { let error = linked(&source).unwrap_err(); assert!(error.contains(code), "{source}\n{error}"); }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn live_context_keeps_concrete_type_and_rejects_nontransferable_values() {
|
||||
let source = "type Context { prefix: Text }\nroute(request: dever.http.Request, reply: dever.system.HttpReply, context: Context) () { dever.http.start(reply, 200, [])\ndever.http.write(reply, dever.bytes.fromText(context.prefix + request.target)) }\nmain(listener: dever.system.Listener, context: Context) () { dever.system.httpServeLive(route, listener, dever.http.defaultLimits(), dever.http.defaultLiveLimits(), context) }";
|
||||
linked(source).unwrap();
|
||||
let error = linked(&source.replace(
|
||||
"context: Context) () { dever.http.start",
|
||||
"context: Text) () { dever.http.start",
|
||||
))
|
||||
.unwrap_err();
|
||||
assert!(error.contains("C005"), "{error}");
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn streaming_original_source_contract_checks_and_selects_http_runtime() {
|
||||
let project = Project::load(
|
||||
&Path::new(env!("CARGO_MANIFEST_DIR")).join("../test/rust/fixtures/http-stream.dever"),
|
||||
)
|
||||
.unwrap();
|
||||
let program = project.check().unwrap();
|
||||
let entry = program
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == "verify")
|
||||
.unwrap();
|
||||
let effects = program.functions[entry].signature.effects;
|
||||
assert!(effects.network && effects.suspend && effects.schedule);
|
||||
assert!(build::runtime_features(&program, &program.reachable([entry])).contains(&"http"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn streaming_intrinsics_preserve_types_effects_and_failure_obligations() {
|
||||
linked("main(client: dever.system.HttpClient, request: dever.http.Request) () { response = dever.http.open(client, request)\nclose(response.body) }").unwrap();
|
||||
for (source, code) in [
|
||||
(
|
||||
"main(client: dever.system.HttpClient, request: dever.http.Request) (response: dever.http.StreamResponse) pure { response = dever.http.open(client, request) }",
|
||||
"C013",
|
||||
),
|
||||
(
|
||||
"main(client: dever.system.HttpClient, request: dever.http.Request) (response: dever.http.StreamResponse) { response = dever.http.openStream(client, request) }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main(client: dever.system.HttpClient, request: dever.http.Request) () { lost = result(dever.http.open(client, request)) }",
|
||||
"C012",
|
||||
),
|
||||
(
|
||||
"main(client: dever.system.HttpClient, request: dever.http.Request) () { dever.system.httpOpen(client, request) }",
|
||||
"C006",
|
||||
),
|
||||
] {
|
||||
let error = linked(source).unwrap_err();
|
||||
assert!(error.contains(code), "{source}\n{error}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn websocket_original_contract_effects_and_resource_rules() {
|
||||
let source = "route(request: dever.http.Request, reply: dever.system.HttpReply) () { socket = dever.websocket.accept(reply, dever.websocket.defaultLimits())\ndever.websocket.send(socket, dever.websocket.Message.Text(request.target))\ndever.websocket.close(socket, 1000, \"\") }\nmain(listener: dever.system.Listener) () { dever.http.serveLive(route, listener, dever.http.defaultLimits(), dever.http.defaultLiveLimits()) }";
|
||||
let program = linked(source).unwrap();
|
||||
let main = program
|
||||
.functions
|
||||
.iter()
|
||||
.find(|function| function.signature.name == "main")
|
||||
.unwrap();
|
||||
assert!(
|
||||
main.signature.effects.network
|
||||
&& main.signature.effects.suspend
|
||||
&& main.signature.effects.schedule
|
||||
);
|
||||
for (source, code) in [
|
||||
(
|
||||
"main(socket: dever.system.WebSocket) (same: Bool) { same = socket == socket }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main(socket: dever.system.WebSocket) () { dever.system.wsReceive(socket) }",
|
||||
"C006",
|
||||
),
|
||||
(
|
||||
"main(socket: dever.system.WebSocket) () { lost = result(dever.websocket.receive(socket)) }",
|
||||
"C012",
|
||||
),
|
||||
(
|
||||
"main() () { lost = result(dever.websocket.connect(\"127.0.0.1\", 80, \"/\", dever.websocket.defaultLimits())) }",
|
||||
"C012",
|
||||
),
|
||||
(
|
||||
"main(socket: dever.system.WebSocket) (value: dever.websocket.Message) { value = first(dever.websocket.messages(socket)) }",
|
||||
"C005",
|
||||
),
|
||||
] {
|
||||
let error = linked(source).unwrap_err();
|
||||
assert!(error.contains(code), "{source}\n{error}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn websocket_messages_are_lazy_and_keep_terminal_failure_obligations() {
|
||||
let source = "main(socket: dever.system.WebSocket) (stream: AsyncStream<dever.websocket.MessageEvent>) { stream = dever.websocket.messages(socket) }";
|
||||
let program = linked(source).unwrap();
|
||||
let main = program
|
||||
.functions
|
||||
.iter()
|
||||
.find(|function| function.signature.name == "main")
|
||||
.unwrap();
|
||||
assert!(!main.signature.effects.suspend);
|
||||
let source = "read(event: dever.websocket.MessageEvent.Read(message)) () {}\nread(event: dever.websocket.MessageEvent.Failed(message)) () { fail(dever.websocket.MessageEvent.Failed(message)) }\nmain(socket: dever.system.WebSocket) () { each(read, dever.websocket.messages(socket)) }";
|
||||
linked(source).unwrap();
|
||||
}
|
||||
Reference in new issue
Block a user