Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user