Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+125
View File
@@ -0,0 +1,125 @@
use super::signature;
use dever::compiler::{check, model::Program};
use dever::syntax::{diagnostic::Diagnostic, source::Source};
fn packages(files: &[(&str, &str)]) -> Result<Program, Diagnostic> {
let mut modules = Vec::new();
let mut identities = Vec::new();
for (index, (identity, text)) in files.iter().enumerate() {
let path = if *identity == "dever.io" {
"lib/dever/io.dever"
} else {
"case.dever"
};
modules.push(dever::syntax::parse(&Source::new(
index,
path,
(*text).into(),
))?);
identities.push((*identity).into());
}
check::check(modules, &identities)
}
const IO: &str = include_str!("../../../../lib/dever/io.dever");
const PORT: &str = "open(path: Text) (file: dever.system.File) fails dever.io.OpenResult";
const ADAPTER: &str = "port.open(path: Text) (file: dever.system.File) { file = open(path) }\nopen(path: Text) (file: dever.system.File) { file = dever.io.open(path) }";
#[test]
fn boundary_retains_real_effects_without_permitting_unmediated_io() {
let app = "open(path: Text) (file: dever.system.File) { file = port.open(path) }";
let program = packages(&[
("shop.files.app", app),
("shop.files.port", PORT),
("shop.files.adapter", ADAPTER),
("dever.io", IO),
])
.unwrap();
let effects = signature(&program, "open").effects;
assert!(effects.file && effects.blocking && !effects.unmediated_io);
for body in [
"file = dever.io.open(path)",
"old = port.open(path)\nfile = dever.io.open(path)",
"files = each(dever.io.open, [path])\nfile = port.open(path)",
"old = result(dever.io.open(path))\nfile = port.open(path)",
] {
let app = format!("open(path: Text) (file: dever.system.File) {{ {body} }}");
assert!(
packages(&[
("shop.files.app", &app),
("shop.files.port", PORT),
("shop.files.adapter", ADAPTER),
("dever.io", IO)
])
.is_err(),
"{body}"
);
}
let pure = app.replace(" {", " pure {");
assert_eq!(
packages(&[
("shop.files.app", &pure),
("shop.files.port", PORT),
("shop.files.adapter", ADAPTER),
("dever.io", IO)
])
.unwrap_err()
.code,
"C013"
);
let scheduled = app.replace("port.open(path)", "blocking(port.open(path))");
assert!(
packages(&[
("shop.files.app", &scheduled),
("shop.files.port", PORT),
("shop.files.adapter", ADAPTER),
("dever.io", IO)
])
.is_ok()
);
let asynchronous = app.replace(
"file = port.open(path)",
"other = blocking(port.open(path))\nfile = port.open(path)",
);
assert_eq!(
packages(&[
("shop.files.app", &asynchronous),
("shop.files.port", PORT),
("shop.files.adapter", ADAPTER),
("dever.io", IO)
])
.unwrap_err()
.code,
"C013"
);
}
#[test]
fn selection_cannot_hide_blocking_candidate_effects() {
let app = "open(path: Text) (file: dever.system.File) { file = port.open(path) }";
let worker =
"port.open(path: Text) (file: dever.system.File) { file = blocking(dever.io.open(path)) }";
assert_eq!(
packages(&[
("shop.files.app", app),
("shop.files.port", PORT),
("shop.files.adapter.inline", ADAPTER),
("shop.files.adapter.worker", worker),
("dever.io", IO),
])
.unwrap_err()
.code,
"C013"
);
let program = packages(&[
("shop.files.app", app),
("shop.files.port", PORT),
("shop.files.adapter.first", worker),
("shop.files.adapter.second", worker),
("dever.io", IO),
])
.unwrap();
let effects = signature(&program, "open").effects;
assert!(effects.file && effects.suspend && effects.configuration);
assert!(!effects.blocking && !effects.unmediated_io);
}