Skip to content

Commit d156fab

Browse files
Prove bubblewrap fallback and TypeScript symbol indexing in tests.
Empty PATH forces the honest Doctor unavailable path, and the symbol fixture covers Rust plus TypeScript definitions, references, and callers. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent f85cfe5 commit d156fab

3 files changed

Lines changed: 90 additions & 2 deletions

File tree

‎native/core/src/sandbox.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,4 +277,35 @@ mod tests {
277277
assert_eq!(report["ok"], false);
278278
assert_eq!(report["kernel_proof"], false);
279279
}
280+
281+
#[test]
282+
fn missing_bubblewrap_reports_honest_fallback() {
283+
let previous = std::env::var_os("PATH");
284+
// Empty PATH: bwrap cannot be resolved even if installed on the host.
285+
std::env::set_var("PATH", "");
286+
let mode = detect();
287+
let report = probe_workspace_cow();
288+
let checks = doctor_checks();
289+
match previous {
290+
Some(value) => std::env::set_var("PATH", value),
291+
None => std::env::remove_var("PATH"),
292+
}
293+
assert!(matches!(
294+
mode,
295+
SandboxMode::Off { reason } if reason.contains("bubblewrap")
296+
));
297+
assert_eq!(report["shell_available"], false);
298+
assert_eq!(report["mode"], "unavailable");
299+
assert_eq!(report["kernel_proof"], false);
300+
let bubble = checks
301+
.iter()
302+
.find(|c| c["id"] == "bubblewrap")
303+
.expect("doctor includes bubblewrap");
304+
assert_eq!(bubble["status"], "info");
305+
assert!(bubble["detail"]
306+
.as_str()
307+
.unwrap_or("")
308+
.to_ascii_lowercase()
309+
.contains("bubblewrap"));
310+
}
280311
}

‎native/core/src/symbol_index.rs‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,4 +641,26 @@ mod tests {
641641
assert!(status["storage"].as_str().unwrap().contains("private"));
642642
assert!(!root.path().join(".shadow").exists());
643643
}
644+
645+
#[test]
646+
fn indexes_typescript_definitions_references_and_signatures() {
647+
let root = tempfile::tempdir().unwrap();
648+
let src = root.path().join("src");
649+
fs::create_dir_all(&src).unwrap();
650+
fs::write(
651+
src.join("math.ts"),
652+
"export function add(a: number, b: number): number { return a + b; }\nexport function useAdd() { return add(1, 2); }\n",
653+
)
654+
.unwrap();
655+
let status = ensure_index(root.path(), &["src/math.ts".into()], false).unwrap();
656+
assert!(status["symbols_total"].as_i64().unwrap() >= 2);
657+
let defs = query_definitions(root.path(), "add", 10).unwrap();
658+
assert!(!defs["definitions"].as_array().unwrap().is_empty());
659+
let refs = query_references(root.path(), "add", 16).unwrap();
660+
assert!(!refs["references"].as_array().unwrap().is_empty());
661+
let sig = get_type_signature(root.path(), "add").unwrap();
662+
assert!(sig["ok"].as_bool().unwrap());
663+
let callers = callers_for(root.path(), "add", 8).unwrap();
664+
assert!(callers["count"].as_u64().unwrap() >= 1);
665+
}
644666
}

‎native/core/tests/flagship_complete.rs‎

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,30 @@ fn sandbox_scratch_and_home_readonly_args() {
119119
assert!(args
120120
.windows(3)
121121
.any(|w| w[0] == "--bind" && w[2] == "/shadowcode-scratch"));
122+
if std::path::Path::new("/home").exists() {
123+
assert!(args
124+
.windows(3)
125+
.any(|w| w == ["--ro-bind", "/home", "/home"]));
126+
}
127+
assert!(args.iter().any(|a| a == "--unshare-net"));
122128
sandbox::discard_scratch(&scratch.path).unwrap();
123129
let cow = sandbox::probe_workspace_cow();
124130
assert_eq!(cow["kernel_proof"], false);
131+
// Fallback: Doctor reports unavailable when bubblewrap cannot be found.
132+
let previous = std::env::var_os("PATH");
133+
std::env::set_var("PATH", "");
134+
let fallback = sandbox::probe_workspace_cow();
135+
let doctor = sandbox::doctor_checks();
136+
match previous {
137+
Some(value) => std::env::set_var("PATH", value),
138+
None => std::env::remove_var("PATH"),
139+
}
140+
assert_eq!(fallback["mode"], "unavailable");
141+
assert_eq!(fallback["shell_available"], false);
142+
assert_eq!(
143+
doctor.iter().find(|c| c["id"] == "bubblewrap").unwrap()["status"],
144+
"info"
145+
);
125146
}
126147

127148
#[test]
@@ -134,12 +155,26 @@ fn symbol_index_fixture_tools() {
134155
"pub fn add(a: i32, b: i32) -> i32 { a + b }\npub fn use_add() { let _ = add(1, 2); }\n",
135156
)
136157
.unwrap();
137-
let status = symbol_index::ensure_index(root.path(), &["src/lib.rs".into()], false).unwrap();
138-
assert!(status["symbols_total"].as_i64().unwrap() >= 2);
158+
fs::write(
159+
src.join("math.ts"),
160+
"export function mul(a: number, b: number): number { return a * b; }\nexport function useMul() { return mul(2, 3); }\n",
161+
)
162+
.unwrap();
163+
let status = symbol_index::ensure_index(
164+
root.path(),
165+
&["src/lib.rs".into(), "src/math.ts".into()],
166+
false,
167+
)
168+
.unwrap();
169+
assert!(status["symbols_total"].as_i64().unwrap() >= 4);
139170
let sig = symbol_index::get_type_signature(root.path(), "add").unwrap();
140171
assert!(sig["ok"].as_bool().unwrap());
141172
let callers = symbol_index::callers_for(root.path(), "add", 8).unwrap();
142173
assert!(callers["count"].as_u64().unwrap() >= 1);
174+
let ts_defs = symbol_index::query_definitions(root.path(), "mul", 8).unwrap();
175+
assert!(!ts_defs["definitions"].as_array().unwrap().is_empty());
176+
let ts_refs = symbol_index::query_references(root.path(), "mul", 16).unwrap();
177+
assert!(!ts_refs["references"].as_array().unwrap().is_empty());
143178
}
144179

145180
#[test]

0 commit comments

Comments
 (0)