1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! Shared helpers for CLI integration tests under
//! `djogi-cli/tests/internal/`.
//!
//! These functions back the integration tests that spawn the compiled
//! `djogi` binary as a subprocess (`djogi verify`, `djogi analyze`, …)
//! and seed a per-test database via `#[djogi_test]`. Before this module
//! existed, every CLI integration test re-declared its own copy of the
//! same four helpers; centralising them here lets each test file focus
//! on the scenario under test and keeps the binary-locating, workspace
//! provisioning, and `Djogi.toml`-writing logic in one auditable place.
//!
//! # Surface visibility
//!
//! Gated behind `cfg(any(test, feature = "testing"))` (matching the
//! existing convention used by other `testing`-feature surfaces in this
//! crate). Adopter integration test crates that consume these helpers
//! must enable djogi's `testing` feature on their dev dependency on
//! `djogi`.
//!
//! # Raw access
//!
//! [`current_database`] uses [`crate::__bypass::RawAccessExt::raw_scalar`]
//! to issue `SELECT current_database()` against the per-test
//! [`crate::DjogiContext`]. The use is internal to djogi (no `raw_*`
//! method appears at the call site outside this crate), so adopter test
//! files do not need a `#[deliberately_bypass_convention_with_raw_sql]`
//! attribute solely on account of these helpers.
use fs;
use ;
use crateRawAccessExt as _;
use crateDjogiContext;
/// Walk from the running test executable to the workspace's compiled
/// `djogi` binary.
///
/// Test binaries live at `target/<profile>/deps/<test_name>-<hash>`; the
/// CLI binary lives at `target/<profile>/djogi`. We walk up one level
/// (drop the test-binary file) to reach `deps/`, then up another level to
/// reach `<profile>/`, then join `djogi`.
///
/// # Why the `option_env!` branch is structurally retained
///
/// Cargo only sets `CARGO_BIN_EXE_<name>` for integration tests in the
/// same package as the matching `[[bin]]`. In today's `djogi-cli`
/// tests this helper is compiled by the `djogi` crate, so the env-var
/// branch is expected to be inactive and the walk fallback is
/// load-bearing. The branch is preserved verbatim so the helper's
/// surface stays identical to the per-file copies it replaces, and so
/// a future relocation that compiles this code in the binary package
/// can use Cargo's direct path without touching call sites. The walk
/// reliably finds the binary because Cargo builds the package's
/// `[[bin]]` targets before its `[[test]]` targets when running
/// `cargo test -p djogi-cli`.
/// Resolve the connected test context's `current_database()` so callers
/// can splice the per-test database name into a fixture `Djogi.toml`
/// URL.
///
/// Issues a single `SELECT current_database()::text` against `ctx` via
/// the in-crate raw escape hatch. The cast to `text` is deliberate —
/// `current_database()` returns a `name`, and decoding `name` directly
/// into Rust's `String` is fragile across `tokio_postgres` versions.
pub async
/// Build a unique temporary workspace directory and return its path.
///
/// The directory is named `djogi-{tag}-{nanos-since-epoch}-{counter}`
/// under the platform's temp dir, where `counter` is a process-local
/// monotonic value. The combination of nanos + counter keeps every
/// invocation distinct even under heavy parallel test scheduling.
///
/// Callers should pass a `tag` that incorporates both their test-suite
/// identity (e.g. `t9-7-verify`) and the per-case discriminator
/// (e.g. `clean`, `mismatch`). The full string lands verbatim in the
/// directory name and is the easiest way to attribute a stale temp dir
/// back to the test that left it on disk.
/// Write a minimal `Djogi.toml` in `workspace` whose `database.url`
/// points at the supplied per-test URL.
///
/// The CLI subcommands these tests drive (`djogi verify`,
/// `djogi analyze`, …) read this file via
/// `DjogiConfig::load_from_workspace`. The `[server]` block is required
/// by the loader; `port = 0` lets the OS pick an ephemeral port if the
/// loaded config later spawns a server.