Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,175 @@
|
||||
#[path = "inspection/documentation.rs"]
|
||||
mod documentation;
|
||||
|
||||
use super::Directory;
|
||||
use dever::compiler::project::Project;
|
||||
use std::process::Command;
|
||||
|
||||
#[path = "inspection/dispatch.rs"]
|
||||
mod dispatch;
|
||||
#[path = "inspection/flows.rs"]
|
||||
mod flows;
|
||||
#[path = "inspection/links.rs"]
|
||||
mod links;
|
||||
|
||||
#[test]
|
||||
fn inspection_preserves_multiple_callers_sites_and_utf16_columns() {
|
||||
let directory = Directory::new();
|
||||
let path = directory.0.join("main.dever");
|
||||
let source = "label(name: Text) (text: Text) {\n text = name\n}\n\nfirst(name: Text) (text: Text) {\n text = \"😀\" + label(name) + label(\"另\")\n}\n\nsecond(name: Text) (text: Text) {\n text = label(name)\n}\n";
|
||||
std::fs::write(&path, source).unwrap();
|
||||
let project = Project::load(&path).unwrap();
|
||||
let mut index = project.inspect().unwrap();
|
||||
index.select("main.label", 1).unwrap();
|
||||
let label = index
|
||||
.symbols
|
||||
.iter()
|
||||
.find(|symbol| symbol.name == "main.label")
|
||||
.unwrap();
|
||||
let calls: Vec<_> = index
|
||||
.calls
|
||||
.iter()
|
||||
.filter(|call| call.callee == label.id)
|
||||
.collect();
|
||||
assert_eq!(calls.len(), 3);
|
||||
assert_eq!(
|
||||
calls
|
||||
.iter()
|
||||
.map(|call| call.caller)
|
||||
.collect::<std::collections::BTreeSet<_>>()
|
||||
.len(),
|
||||
2
|
||||
);
|
||||
let line = source.lines().nth(5).unwrap();
|
||||
let first = calls.iter().find(|call| call.site.start.line == 5).unwrap();
|
||||
assert_eq!(
|
||||
first.site.start.character,
|
||||
line[..line.find("label").unwrap()].encode_utf16().count()
|
||||
);
|
||||
assert_eq!(
|
||||
first.site.end.character - first.site.start.character,
|
||||
"label".len()
|
||||
);
|
||||
assert_eq!(index.files.len(), 1);
|
||||
assert!(index.select("does.not.exist", 1).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inspection_retains_clauses_and_distinguishes_callback_and_task_dispatch() {
|
||||
let directory = Directory::new();
|
||||
let path = directory.0.join("main.dever");
|
||||
std::fs::write(&path, "label(value: true) (text: Text) {\n text = \"yes\"\n}\nlabel(value: other) (text: Text) {\n text = \"no\"\n}\nmain() (texts: List<Text>, text: Text) {\n texts = each(label, [true, false])\n task = run(label(true))\n text = wait(task)\n}\n").unwrap();
|
||||
let index = Project::load(&path).unwrap().inspect().unwrap();
|
||||
let label = index
|
||||
.symbols
|
||||
.iter()
|
||||
.find(|symbol| symbol.name == "main.label")
|
||||
.unwrap();
|
||||
assert_eq!(label.declarations.len(), 2);
|
||||
let calls: Vec<_> = index
|
||||
.calls
|
||||
.iter()
|
||||
.filter(|call| call.callee == label.id)
|
||||
.collect();
|
||||
assert_eq!(calls.len(), 2);
|
||||
assert!(calls.iter().any(|call| call.kind == "callback"));
|
||||
assert!(calls.iter().any(|call| call.kind == "run"));
|
||||
for call in calls {
|
||||
assert_eq!(call.site.end.character - call.site.start.character, 5);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inspection_cli_resolves_real_command_bindings_and_reports_failures() {
|
||||
let directory = Directory::new();
|
||||
let root = directory.0.join("app");
|
||||
dever::compiler::project::create(&root).unwrap();
|
||||
let output = Command::new(env!("CARGO_BIN_EXE_dever"))
|
||||
.args([
|
||||
"inspect",
|
||||
root.to_str().unwrap(),
|
||||
"--symbol",
|
||||
"hello.greeting.greet",
|
||||
"--json",
|
||||
])
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
let index: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
|
||||
assert_eq!(index["calls"].as_array().unwrap().len(), 1);
|
||||
assert_eq!(index["calls"][0]["kind"], "command");
|
||||
let failed = Command::new(env!("CARGO_BIN_EXE_dever"))
|
||||
.args(["inspect", root.to_str().unwrap(), "--symbol", "missing"])
|
||||
.output()
|
||||
.unwrap();
|
||||
assert!(!failed.status.success());
|
||||
assert!(failed.stdout.is_empty());
|
||||
assert!(String::from_utf8_lossy(&failed.stderr).contains("unknown symbol"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inspection_does_not_change_generated_rust_or_accept_invalid_source() {
|
||||
let directory = Directory::new();
|
||||
let path = directory.0.join("main.dever");
|
||||
std::fs::write(&path, "main() (value: Int) {\n value = 42\n}\n").unwrap();
|
||||
let project = Project::load(&path).unwrap();
|
||||
let emit = || {
|
||||
let program = project.check().unwrap();
|
||||
dever::compiler::emit::generate(
|
||||
&program,
|
||||
&project.sources,
|
||||
&std::collections::BTreeSet::from([0]),
|
||||
)
|
||||
};
|
||||
let before = emit();
|
||||
project.inspect().unwrap();
|
||||
assert_eq!(emit(), before);
|
||||
std::fs::write(&path, "main() (value: Int) {\n value = unknown()\n}\n").unwrap();
|
||||
assert!(Project::load(&path).unwrap().inspect().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inspection_keeps_job_dispatch_and_static_handler_specializations() {
|
||||
let fixtures = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../test/rust/fixtures");
|
||||
let jobs = Project::load(&fixtures.join("job"))
|
||||
.unwrap()
|
||||
.inspect()
|
||||
.unwrap();
|
||||
let publish = jobs
|
||||
.symbols
|
||||
.iter()
|
||||
.find(|symbol| symbol.name == "demo.queue.job.publish")
|
||||
.unwrap();
|
||||
assert!(
|
||||
jobs.calls
|
||||
.iter()
|
||||
.any(|call| call.callee == publish.id && call.kind == "enqueue")
|
||||
);
|
||||
assert!(
|
||||
jobs.calls
|
||||
.iter()
|
||||
.any(|call| call.caller == publish.id && call.kind == "call")
|
||||
);
|
||||
let handlers = Project::load(&fixtures.join("handler.dever"))
|
||||
.unwrap()
|
||||
.inspect()
|
||||
.unwrap();
|
||||
let apply = handlers
|
||||
.symbols
|
||||
.iter()
|
||||
.filter(|symbol| symbol.name == "main.apply")
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(apply.len(), 1);
|
||||
let targets: std::collections::BTreeSet<_> = handlers
|
||||
.calls
|
||||
.iter()
|
||||
.filter(|call| call.caller == apply[0].id)
|
||||
.map(|call| handlers.symbols[call.callee].name.as_str())
|
||||
.collect();
|
||||
assert!(targets.contains("main.increment"));
|
||||
assert!(targets.contains("main.decrement"));
|
||||
}
|
||||
Reference in new issue
Block a user