feat: release Dever 0.1.5 with direct workers and long transactions
This commit is contained in:
1 parent
89629c2197
commit
a900d7e8db
153 files changed
+3676
-3708
No files matched your search
@@ -6,6 +6,9 @@ use dever_runtime::http::{Header, Request};
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
#[path = "support/process.rs"]
|
||||
#[allow(dead_code)]
|
||||
mod process;
|
||||
#[path = "support/temp.rs"]
|
||||
mod temp;
|
||||
|
||||
@@ -17,6 +20,81 @@ fn source(files: &[(&str, &str)]) -> SourceMap {
|
||||
sources
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
#[test]
|
||||
fn command_releases_short_transactions_before_waiting_and_preserves_committed_stages() {
|
||||
let sources = source(&[
|
||||
(
|
||||
"content/item/model.dever",
|
||||
"global type Item { name: Text unique }",
|
||||
),
|
||||
(
|
||||
"content/item/app.dever",
|
||||
"transaction store(name: Text) (value: Text) { saved = model.create({ name = name })\nvalue = saved.name }\ncount() (total: Int) { total = model.count() }\nperform() (total: Int) { saved = store(\"first\")\ntask = run(count())\ntotal = wait(task) }\nfail_later() (value: Text) { committed = store(\"second\")\nvalue = store(committed) }",
|
||||
),
|
||||
(
|
||||
"content/item/api.dever",
|
||||
"long cmd perform = app.perform\nlong cmd fail_later = app.fail_later\ncmd fail_atomic = app.fail_later\ncmd count = app.count",
|
||||
),
|
||||
]);
|
||||
let program = dever_core::check(&sources).unwrap_or_else(|errors| panic!("{errors:?}"));
|
||||
let rustc = std::env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
|
||||
let native = dever_core::native::compile_project(
|
||||
&program,
|
||||
&sources,
|
||||
&rustc,
|
||||
RuntimeProfile {
|
||||
sqlite: true,
|
||||
postgres: false,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
let root = native.executable().parent().unwrap();
|
||||
fs::create_dir_all(root.join("config")).unwrap();
|
||||
fs::write(
|
||||
root.join("config/setting.json"),
|
||||
r#"{"database":{"default":{"type":"sqlite","path":"data/db/app.db","max_connections":1}}}"#,
|
||||
)
|
||||
.unwrap();
|
||||
let invoke = |operation: &str| {
|
||||
let mut child = Command::new(native.executable())
|
||||
.current_dir(root)
|
||||
.args([operation, "{}"])
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
process::wait(&mut child, std::time::Duration::from_secs(10)).unwrap();
|
||||
child.wait_with_output().unwrap()
|
||||
};
|
||||
let first = invoke("content.item.perform");
|
||||
assert!(
|
||||
first.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&first.stderr)
|
||||
);
|
||||
let first: serde_json::Value = serde_json::from_slice(&first.stdout).unwrap();
|
||||
assert_eq!(first["data"], 1);
|
||||
let atomic = invoke("content.item.fail_atomic");
|
||||
assert!(!atomic.status.success());
|
||||
assert!(String::from_utf8_lossy(&atomic.stderr).contains("UNIQUE"));
|
||||
let retained = invoke("content.item.count");
|
||||
assert!(retained.status.success());
|
||||
let retained: serde_json::Value = serde_json::from_slice(&retained.stdout).unwrap();
|
||||
assert_eq!(retained["data"], 1);
|
||||
let failed = invoke("content.item.fail_later");
|
||||
assert!(!failed.status.success());
|
||||
assert!(String::from_utf8_lossy(&failed.stderr).contains("UNIQUE"));
|
||||
let count = invoke("content.item.count");
|
||||
assert!(
|
||||
count.status.success(),
|
||||
"{}",
|
||||
String::from_utf8_lossy(&count.stderr)
|
||||
);
|
||||
let count: serde_json::Value = serde_json::from_slice(&count.stdout).unwrap();
|
||||
assert_eq!(count["data"], 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_entry_collects_api_and_command_without_main() {
|
||||
let sources = source(&[
|
||||
@@ -175,13 +253,13 @@ fn generated_write_entry_rejects_detached_concurrency() {
|
||||
.map(|error| error.render(&sources))
|
||||
.collect::<String>();
|
||||
assert!(
|
||||
rendered.contains("transaction cannot start concurrent work"),
|
||||
rendered.contains("automatic entry transactions cannot contain"),
|
||||
"{rendered}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generated_write_entry_allows_structured_blocking_work() {
|
||||
fn generated_long_entry_keeps_password_work_outside_its_write_transaction() {
|
||||
let sources = source(&[
|
||||
(
|
||||
"user/account/model.dever",
|
||||
@@ -201,7 +279,10 @@ transaction persist(hash: Text) (id: model.id) {
|
||||
id = stored.id
|
||||
}"#,
|
||||
),
|
||||
("user/account/api.dever", "post register = app.register"),
|
||||
(
|
||||
"user/account/api.dever",
|
||||
"long post register = app.register",
|
||||
),
|
||||
]);
|
||||
let program = dever_core::check(&sources).unwrap_or_else(|errors| {
|
||||
panic!(
|
||||
|
||||
Reference in new issue
Block a user