Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,148 @@
|
||||
use dever::{
|
||||
compiler::{build, check, model::Program},
|
||||
syntax::{diagnostic::Diagnostic, source::Source},
|
||||
};
|
||||
|
||||
fn linked(text: &str) -> Result<Program, Diagnostic> {
|
||||
let inputs = [
|
||||
("main", text),
|
||||
("dever.io", include_str!("../../../lib/dever/io.dever")),
|
||||
("dever.time", include_str!("../../../lib/dever/time.dever")),
|
||||
("dever.task", include_str!("../../../lib/dever/task.dever")),
|
||||
(
|
||||
"dever.net",
|
||||
include_str!("../../../lib/dever/net/socket.dever"),
|
||||
),
|
||||
(
|
||||
"dever.net",
|
||||
include_str!("../../../lib/dever/net/listener.dever"),
|
||||
),
|
||||
];
|
||||
let modules = inputs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, (_, text))| {
|
||||
dever::syntax::parse(&Source::new(
|
||||
index,
|
||||
if index == 0 {
|
||||
"main.dever".into()
|
||||
} else {
|
||||
format!("source{index}.dever")
|
||||
},
|
||||
(*text).into(),
|
||||
))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
check::check(
|
||||
modules,
|
||||
&inputs
|
||||
.iter()
|
||||
.map(|(package, _)| (*package).into())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn network_effects_and_runtime_features_match_the_actual_entry() {
|
||||
for (source, suspends, schedules, net) in [
|
||||
("main() (answer: Int) { answer = 42 }", false, false, false),
|
||||
(
|
||||
"main() (socket: dever.system.Socket?) { socket = null }",
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
),
|
||||
(
|
||||
"main(socket: dever.system.Socket) () { dever.net.close(socket) }",
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
),
|
||||
(
|
||||
"main(listener: dever.system.Listener) (port: Int) { port = dever.net.port(listener) }",
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
),
|
||||
(
|
||||
"main() (socket: dever.system.Socket) { socket = dever.net.connectTimeout(\"127.0.0.1\", 80, 1000) }",
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
),
|
||||
(
|
||||
"main() (socket: dever.system.Socket) { socket = dever.net.connect(\"localhost\", 80) }",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
(
|
||||
"main() (listener: dever.system.Listener) { listener = dever.net.listen(\"127.0.0.1\", 0) }",
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
] {
|
||||
let program = linked(source).unwrap();
|
||||
let main = program
|
||||
.functions
|
||||
.iter()
|
||||
.position(|function| function.signature.name == "main")
|
||||
.unwrap();
|
||||
let effects = program.functions[main].signature.effects;
|
||||
assert_eq!(effects.suspend, suspends, "{source}");
|
||||
assert_eq!(effects.schedule, schedules, "{source}");
|
||||
assert_eq!(
|
||||
build::runtime_features(&program, &program.reachable([main])).contains(&"net"),
|
||||
net,
|
||||
"{source}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn network_resources_obey_visibility_equality_and_effect_boundaries() {
|
||||
for (source, code) in [
|
||||
("main() () { value = dever.system.tcpPort(null) }", "C006"),
|
||||
(
|
||||
"main(socket: dever.system.Socket) (answer: Bool) { answer = socket == socket }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main(values: List<dever.system.Listener?>) (answer: Bool) { answer = values == values }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main(listener: dever.system.Listener) (port: Int) pure { port = dever.net.port(listener) }",
|
||||
"C013",
|
||||
),
|
||||
("main(value: dever.net.SystemReadResult) () {}", "C006"),
|
||||
(
|
||||
"main(socket: dever.system.Socket) () { value = dever.net.read(socket, true) }",
|
||||
"C005",
|
||||
),
|
||||
(
|
||||
"main(socket: dever.system.Socket) () { value = dever.net.read(socket, 1)\n dever.io.println(\"blocking\") }",
|
||||
"C013",
|
||||
),
|
||||
] {
|
||||
assert_eq!(linked(source).unwrap_err().code, code, "{source}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lazy_network_streams_do_not_claim_unread_errors_but_captured_failures_remain_obligations() {
|
||||
for source in [
|
||||
"main(socket: dever.system.Socket) () { close(dever.net.chunks(socket, 1)) }",
|
||||
"main(listener: dever.system.Listener) () { close(dever.net.connections(listener)) }",
|
||||
] {
|
||||
assert!(linked(source).is_ok(), "{source}");
|
||||
}
|
||||
for source in [
|
||||
"main(socket: dever.system.Socket) () { lost = result(dever.net.read(socket, 1)) }",
|
||||
"main(socket: dever.system.Socket) () { lost = result(dever.net.chunks(socket, 1)) }",
|
||||
"main(socket: dever.system.Socket) () { lost = result(dever.net.close(socket)) }",
|
||||
] {
|
||||
assert_eq!(linked(source).unwrap_err().code, "C012", "{source}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user