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,148 @@
|
||||
mod support;
|
||||
|
||||
use support::{checked, sources, stdout};
|
||||
|
||||
#[test]
|
||||
fn async_program_compiles_and_runs_every_execution_class() {
|
||||
let output = stdout(
|
||||
r#"sleep_ok(result: dever.time.SleepResult.Done) () recover("test handles timer failures") {}
|
||||
sleep_ok(result: dever.time.SleepResult.Failed(message)) () recover("test handles timer failures") {}
|
||||
pause() (result: dever.time.SleepResult) { result = result(dever.time.sleep(1)) }
|
||||
double(value: Int) (answer: Int) pure { answer = value * 2 }
|
||||
delayed(value: Int, millis: Int) (answer: Int) {
|
||||
sleep_ok(result(dever.task.sleep(millis)))
|
||||
answer = value
|
||||
}
|
||||
send_value(channel: Channel<Int>, value: Int) () {
|
||||
send(channel, value)
|
||||
}
|
||||
wait_until_stopped() () {
|
||||
sleep_ok(result(dever.task.sleep(1000)))
|
||||
}
|
||||
public main() (direct: Int, first: Int, second: Int, received: Int?, grouped: Int?, computed: Int) {
|
||||
direct = delayed(1, 1)
|
||||
first_task = run(delayed(2, 10))
|
||||
second_task = run(delayed(3, 1))
|
||||
second = wait(second_task)
|
||||
first = wait(first_task)
|
||||
|
||||
channel = channel(Int, 2)
|
||||
sender = run(send_value(channel, 4))
|
||||
received = receive(channel)
|
||||
wait(sender)
|
||||
|
||||
workers = group(2)
|
||||
run(workers, send_value(channel, 5))
|
||||
wait(workers)
|
||||
grouped = receive(channel)
|
||||
close(channel)
|
||||
|
||||
cancelled = run(wait_until_stopped())
|
||||
stop(cancelled)
|
||||
computed = parallel(double(21))
|
||||
sleep_ok(blocking(pause()))
|
||||
}"#,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
output,
|
||||
"direct = 1\nfirst = 2\nsecond = 3\nreceived = 4\ngrouped = 5\ncomputed = 42\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_inferred_suspending_entries_start_the_shared_runtime() {
|
||||
let sync_sources = sources("public main() (answer: Int) { answer = 1 }");
|
||||
let sync =
|
||||
dever_core::native::emit(&checked(&sync_sources), &sync_sources, "main.main").unwrap();
|
||||
assert!(sync.contains("match entry()"), "{sync}");
|
||||
assert!(!sync.contains("task::run_entry_typed(entry())"), "{sync}");
|
||||
|
||||
let async_sources = sources(
|
||||
r#"sleep_ok(result: dever.time.SleepResult.Done) () recover("timer failure handled") {}
|
||||
sleep_ok(result: dever.time.SleepResult.Failed(message)) () recover("timer failure handled") {}
|
||||
public main() () { sleep_ok(result(dever.task.sleep(0))) }"#,
|
||||
);
|
||||
let asynchronous =
|
||||
dever_core::native::emit(&checked(&async_sources), &async_sources, "main.main").unwrap();
|
||||
assert!(
|
||||
asynchronous.contains("match task::run_entry_typed(entry())"),
|
||||
"{asynchronous}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn timer_suspension_is_inferred_without_a_source_modifier() {
|
||||
let program_sources = sources(
|
||||
"public main() (result: dever.time.SleepResult) { result = dever.system.task_sleep(1) }",
|
||||
);
|
||||
let generated =
|
||||
dever_core::native::emit(&checked(&program_sources), &program_sources, "main.main")
|
||||
.unwrap();
|
||||
assert!(generated.contains("async fn"), "{generated}");
|
||||
assert!(
|
||||
generated.contains("task::run_entry_typed(entry())"),
|
||||
"{generated}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn async_parallel_each_runs_outside_the_runtime_worker() {
|
||||
let source = r#"sleep_ok(result: dever.time.SleepResult.Done) () recover("timer failure handled") {}
|
||||
sleep_ok(result: dever.time.SleepResult.Failed(message)) () recover("timer failure handled") {}
|
||||
visit(value: Int) () {}
|
||||
public main() (answer: Int) {
|
||||
sleep_ok(result(dever.task.sleep(0)))
|
||||
parallel_each(visit, [1, 2, 3], 2)
|
||||
parallel_each(visit, dever.bytes.from_text("ab"), 2)
|
||||
answer = 7
|
||||
}"#;
|
||||
let program_sources = sources(source);
|
||||
let generated =
|
||||
dever_core::native::emit(&checked(&program_sources), &program_sources, "main.main")
|
||||
.unwrap();
|
||||
assert!(
|
||||
generated.contains("task::parallel_each_typed(a0.into_values()"),
|
||||
"{generated}"
|
||||
);
|
||||
assert_eq!(stdout(source), "answer = 7\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nullable_channel_items_are_flattened_at_the_language_boundary() {
|
||||
assert_eq!(
|
||||
stdout(
|
||||
"public main() (received: Int?) { channel = channel(Int?, 1)\nsend(channel, null)\nreceived = receive(channel)\nclose(channel) }",
|
||||
),
|
||||
"received = null\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inferred_suspension_requires_explicit_transitive_blocking_boundaries() {
|
||||
support::rejected(
|
||||
r#"sleep_ok(result: dever.time.SleepResult.Done) () recover("timer failure handled") {}
|
||||
sleep_ok(result: dever.time.SleepResult.Failed(message)) () recover("timer failure handled") {}
|
||||
pause() (result: dever.time.SleepResult) { result = result(dever.time.sleep(1)) }
|
||||
public main() (result: dever.time.SleepResult) {
|
||||
sleep_ok(result(dever.task.sleep(0)))
|
||||
result = pause()
|
||||
}"#,
|
||||
"cannot run inline inside a suspending function",
|
||||
);
|
||||
support::rejected(
|
||||
r#"sleep_ok(result: dever.time.SleepResult.Done) () recover("timer failure handled") {}
|
||||
sleep_ok(result: dever.time.SleepResult.Failed(message)) () recover("timer failure handled") {}
|
||||
visit(value: Int) () {}
|
||||
visit_all(values: List<Int>) () { parallel_each(visit, values, 2) }
|
||||
public main() () {
|
||||
sleep_ok(result(dever.task.sleep(0)))
|
||||
visit_all([1, 2, 3])
|
||||
}"#,
|
||||
"cannot run inline inside a suspending function",
|
||||
);
|
||||
checked(&sources(
|
||||
r#"visit(value: Int) () {}
|
||||
visit_all(values: Stream<Int>) () { parallel_each(visit, values, 2) }"#,
|
||||
));
|
||||
}
|
||||
Reference in new issue
Block a user