feat: publish Dever core with project scaffolding and versioned AI skills
This commit is contained in:
1 parent
70fa73cdc2
commit
ac458ffa7f
960 files changed
+221319
-1163
No files matched your search
@@ -0,0 +1,305 @@
|
||||
//! Checked-source resource acceptance using owned temporary files only.
|
||||
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
#[path = "dever-tests/tests/support/llvm.rs"]
|
||||
mod llvm;
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
#[path = "dever-tests/tests/support/llvm_managed.rs"]
|
||||
mod llvm_managed;
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
#[path = "dever-tests/tests/support/process.rs"]
|
||||
mod process;
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
#[path = "dever-tests/tests/support/temp.rs"]
|
||||
mod temp;
|
||||
|
||||
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
|
||||
mod native {
|
||||
use super::{llvm, llvm_managed, process, temp};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::time::Duration;
|
||||
|
||||
const HELPERS: &str = r#"read_text(value: dever.io.ReadState.Read(bytes)) (answer: Text) { answer = dever.bytes.to_text(bytes) }
|
||||
read_text(value: dever.io.ReadState.End) (answer: Text) { answer = "EOF" }
|
||||
closed(value: dever.io.CloseResult.Closed, wanted: Bool) (answer: Bool) recover("test explicitly checks close results") { answer = wanted }
|
||||
closed(value: dever.io.CloseResult.Failed(message), wanted: Bool) (answer: Bool) recover("test explicitly checks close results") { answer = not wanted and message == "resource is closed" }
|
||||
read_failed(value: dever.io.ReadResult.Done(state), expected: Text) (answer: Bool) recover("test checks failure identity and message") { answer = false }
|
||||
read_failed(value: dever.io.ReadResult.Failed(message), expected: Text) (answer: Bool) recover("test checks failure identity and message") { answer = message == expected }
|
||||
take_one(value: dever.io.ReadEvent.Chunk(bytes), previous: Text) (answer: Text, stop: Bool) recover("test records exactly one stream event") { answer = dever.bytes.to_text(bytes)
|
||||
stop = true }
|
||||
take_one(value: dever.io.ReadEvent.Failed(message), previous: Text) (answer: Text, stop: Bool) recover("test records exactly one stream event") { answer = message
|
||||
stop = true }
|
||||
next(stream: Stream<dever.io.ReadEvent>) (answer: Text) recover("test records exactly one stream event") { answer = reduce_until(take_one, stream, "EOF") }
|
||||
count(value: dever.io.ReadEvent.Chunk(bytes), total: Int) (answer: Int) recover("test observes stream terminal errors") { answer = total + dever.bytes.length(bytes) }
|
||||
count(value: dever.io.ReadEvent.Failed(message), total: Int) (answer: Int) recover("test observes stream terminal errors") { answer = -1 }
|
||||
finish(value: dever.io.ReadEvent.Chunk(bytes), total: Int) (answer: Int, stop: Bool) recover("test observes stream terminal errors") { answer = total + dever.bytes.length(bytes)
|
||||
stop = true }
|
||||
finish(value: dever.io.ReadEvent.Failed(message), total: Int) (answer: Int, stop: Bool) recover("test observes stream terminal errors") { answer = -1
|
||||
stop = true }
|
||||
"#;
|
||||
|
||||
fn source(body: &str, path: &Path) -> String {
|
||||
format!(
|
||||
"{HELPERS}\n{}",
|
||||
body.replace("FIXTURE_PATH", &format!("{:?}", path.to_str().unwrap()))
|
||||
)
|
||||
}
|
||||
|
||||
fn fixture() -> (temp::TemporaryDirectory, std::path::PathBuf) {
|
||||
let directory = temp::TemporaryDirectory::new();
|
||||
let path = directory.path().join("owned.txt");
|
||||
fs::write(&path, "abcdef").unwrap();
|
||||
(directory, path)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_and_stream_lowering_uses_runtime_owners_and_original_choices() {
|
||||
let ir = llvm::lower(&source(
|
||||
r#"public main() (answer: Bool) {
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
stream = dever.io.chunks(file, 2)
|
||||
first_chunk = next(stream)
|
||||
remaining = reduce(count, stream, 0)
|
||||
close(stream)
|
||||
answer = first_chunk == "ab" and remaining == 4
|
||||
}"#,
|
||||
Path::new("owned-test-file"),
|
||||
));
|
||||
assert!(ir.contains("@dever_rt_v1_file_open"));
|
||||
assert!(ir.contains("@dever_rt_v1_file_chunks"));
|
||||
assert!(ir.contains("@dever_rt_v1_stream_pull"));
|
||||
assert!(ir.contains("@dever_rt_v1_stream_release"));
|
||||
assert!(ir.contains("@dever_read_Chunk_"));
|
||||
assert!(ir.contains("@dever_read_Failed_"));
|
||||
assert!(!ir.contains("dever_runtime"));
|
||||
for target in dever_backend_bridge::Target::ALL {
|
||||
assert!(
|
||||
!dever_backend_bridge::emit_object(&ir, target)
|
||||
.unwrap()
|
||||
.is_empty()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn read_eof_and_alias_close_preserve_business_error_identity() {
|
||||
let (_directory, path) = fixture();
|
||||
llvm_managed::boolean(&source(
|
||||
r#"public main() (answer: Bool) {
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
alias = file
|
||||
first_read = read_text(dever.io.read(file, 2))
|
||||
remaining = read_text(dever.io.read(alias, 8))
|
||||
eof = read_text(dever.io.read(file, 2))
|
||||
bad_limit = read_failed(result(dever.io.read(file, 0)), "read size must be a positive Int")
|
||||
first_close = closed(result(dever.io.close(file)), true)
|
||||
second_close = closed(result(dever.io.close(alias)), false)
|
||||
closed_read = read_failed(result(dever.io.read(alias, 1)), "resource is closed")
|
||||
answer = first_read == "ab" and remaining == "cdef" and eof == "EOF" and bad_limit and first_close and second_close and closed_read
|
||||
}"#,
|
||||
&path,
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn stream_aliases_share_progress_and_early_close() {
|
||||
let (_directory, path) = fixture();
|
||||
llvm_managed::boolean(&source(
|
||||
r#"public main() (answer: Bool) {
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
stream = dever.io.chunks(file, 2)
|
||||
alias = stream
|
||||
first_chunk = next(stream)
|
||||
second_chunk = next(alias)
|
||||
close(stream)
|
||||
close(alias)
|
||||
ended = next(alias)
|
||||
file_still_open = read_text(dever.io.read(file, 2))
|
||||
answer = first_chunk == "ab" and second_chunk == "cd" and ended == "EOF" and file_still_open == "ef"
|
||||
}"#,
|
||||
&path,
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn terminal_read_failure_is_one_event_then_end() {
|
||||
let (_directory, path) = fixture();
|
||||
llvm_managed::boolean(&source(
|
||||
r#"public main() (answer: Bool) {
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
stream = dever.io.chunks(file, 2)
|
||||
dever.io.close(file)
|
||||
failed = next(stream)
|
||||
ended = next(stream)
|
||||
answer = failed == "resource is closed" and ended == "EOF"
|
||||
}"#,
|
||||
&path,
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn reduce_until_retains_the_shared_unvisited_cursor() {
|
||||
let (_directory, path) = fixture();
|
||||
llvm_managed::boolean(&source(
|
||||
r#"public main() (answer: Bool) {
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
stream = dever.io.chunks(file, 2)
|
||||
alias = stream
|
||||
total = reduce_until(finish, stream, 0)
|
||||
next_chunk = next(alias)
|
||||
remaining = reduce(count, alias, 0)
|
||||
answer = total == 2 and next_chunk == "cd" and remaining == 2
|
||||
}"#,
|
||||
&path,
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn owned_file_output_and_stream_release_do_not_leak() {
|
||||
let (_directory, path) = fixture();
|
||||
llvm_managed::execute(
|
||||
&source(
|
||||
r#"public main() (file: dever.system.File, answer: Bool) {
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
stream = dever.io.chunks(file, 2)
|
||||
answer = next(stream) == "ab"
|
||||
}"#,
|
||||
&path,
|
||||
),
|
||||
"{ ptr, i1 }",
|
||||
" %okay = icmp eq i32 %status, 0\n %row = load { ptr, i1 }, ptr %out\n %file = extractvalue { ptr, i1 } %row, 0\n %answer = extractvalue { ptr, i1 } %row, 1\n %present = icmp ne ptr %file, null\n %valid = and i1 %okay, %present\n %passed = and i1 %valid, %answer",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn create_new_and_write_never_overwrite_existing_content() {
|
||||
let directory = temp::TemporaryDirectory::new();
|
||||
let path = directory.path().join("exclusive.txt");
|
||||
assert!(!path.exists());
|
||||
llvm_managed::boolean(&source(
|
||||
r#"created(value: dever.io.OpenResult.Opened(file)) (answer: Bool) recover("test checks create_new on repeated calls") {
|
||||
dever.io.write(file, dever.bytes.from_text("written"))
|
||||
dever.io.close(file)
|
||||
answer = not_created(result(dever.io.create(FIXTURE_PATH)))
|
||||
}
|
||||
created(value: dever.io.OpenResult.Failed(message)) (answer: Bool) recover("test checks create_new on repeated calls") { answer = dever.system.text_contains(message, "File exists") }
|
||||
not_created(value: dever.io.OpenResult.Opened(file)) (answer: Bool) recover("test rejects a second successful creation") {
|
||||
dever.io.write(file, dever.bytes.from_text("unexpected overwrite"))
|
||||
dever.io.close(file)
|
||||
answer = false
|
||||
}
|
||||
not_created(value: dever.io.OpenResult.Failed(message)) (answer: Bool) recover("test rejects a second successful creation") { answer = dever.system.text_contains(message, "File exists") }
|
||||
public main() (answer: Bool) {
|
||||
created_once = created(result(dever.io.create(FIXTURE_PATH)))
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
answer = created_once and read_text(dever.io.read(file, 64)) == "written"
|
||||
}"#,
|
||||
&path,
|
||||
));
|
||||
assert_eq!(fs::read(&path).unwrap(), b"written");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn runtime_fault_unwinds_owned_file_and_partly_read_stream() {
|
||||
let (_directory, path) = fixture();
|
||||
llvm_managed::runtime_fault(
|
||||
&source(
|
||||
r#"identity(value: Text) (answer: Text) { answer = value }
|
||||
duplicate(file: dever.system.File) (answer: Int) {
|
||||
stream = dever.io.chunks(file, 2)
|
||||
observed = next(stream)
|
||||
key = identity("same")
|
||||
keys = { key = 1
|
||||
identity(key) = 2 }
|
||||
answer = length(keys) + length(observed)
|
||||
}
|
||||
public main() (answer: Int) {
|
||||
file = dever.io.open(FIXTURE_PATH)
|
||||
answer = duplicate(file)
|
||||
}"#,
|
||||
&path,
|
||||
),
|
||||
"duplicate Map key",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn each_propagates_owned_business_failure_and_releases_its_cursor() {
|
||||
let (_directory, path) = fixture();
|
||||
llvm_managed::boolean(&source(
|
||||
r#"type TraversalResult {
|
||||
Done
|
||||
error Failed(message: Text, history: List<Text>)
|
||||
}
|
||||
stream_value(value: dever.io.ReadStreamResult.Streaming(stream)) (answer: Stream<dever.io.ReadEvent>) { answer = stream }
|
||||
stream_value(value: dever.io.ReadStreamResult.Failed(message)) (answer: Stream<dever.io.ReadEvent>) { fail(TraversalResult.Failed(message, ["terminal error"])) }
|
||||
close_value(value: dever.io.CloseResult.Closed) () {}
|
||||
close_value(value: dever.io.CloseResult.Failed(message)) () { fail(TraversalResult.Failed(message, ["terminal error"])) }
|
||||
consume(value: dever.io.ReadEvent.Chunk(bytes), file: dever.system.File) () { close_value(result(dever.io.close(file))) }
|
||||
consume(value: dever.io.ReadEvent.Failed(message), file: dever.system.File) () { fail(TraversalResult.Failed(message, ["terminal error"])) }
|
||||
drain(file: dever.system.File) () {
|
||||
stream = stream_value(result(dever.io.chunks(file, 2)))
|
||||
each(consume, stream, file)
|
||||
}
|
||||
observed(value: TraversalResult.Done) (answer: Bool) recover("test requires the owned terminal failure") { answer = false }
|
||||
observed(value: TraversalResult.Failed(message, history)) (answer: Bool) recover("test requires the owned terminal failure") { answer = message == "resource is closed" and history == ["terminal error"] }
|
||||
public main() (answer: Bool) { answer = observed(result(drain(dever.io.open(FIXTURE_PATH)))) }
|
||||
"#,
|
||||
&path,
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "requires the explicitly prepared runtime-abi archive"]
|
||||
fn resource_c_abi_rejects_invalid_outputs_before_io_or_cursor_progress() {
|
||||
let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
|
||||
let archive = root.join("target/native-runtime-abi/debug/libdever_backend_bridge.a");
|
||||
assert!(
|
||||
archive.is_file(),
|
||||
"missing explicit runtime ABI fixture archive"
|
||||
);
|
||||
let directory = temp::TemporaryDirectory::new();
|
||||
let program = directory.path().join("resource-abi");
|
||||
let mut compiler = Command::new("/usr/bin/cc");
|
||||
compiler
|
||||
.env_clear()
|
||||
.args(["-std=c11", "-Wall", "-Wextra", "-Werror", "-O2", "-I"])
|
||||
.arg(root.join("crates/dever-backend-bridge/include"))
|
||||
.arg(root.join("test/native-runtime-abi/resource-driver.c"))
|
||||
.arg(archive)
|
||||
.args(["-ldl", "-lpthread", "-lm", "-o"])
|
||||
.arg(&program)
|
||||
.arg("-B/usr/bin/")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::inherit());
|
||||
assert!(
|
||||
process::status(&mut compiler, Duration::from_secs(30))
|
||||
.unwrap()
|
||||
.success()
|
||||
);
|
||||
assert!(
|
||||
process::status(
|
||||
Command::new(program)
|
||||
.arg(directory.path().join("exclusive.txt"))
|
||||
.env_clear()
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::inherit()),
|
||||
Duration::from_secs(5)
|
||||
)
|
||||
.unwrap()
|
||||
.success()
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user