use std::path::PathBuf;
use droidsaw::commands::strings;
use droidsaw::context::CrossLayerContext;
use serde_json::Value;
fn classes_dex() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("worktree parent")
.join("droidsaw-dex/tests/fixtures/classes.dex")
}
#[test]
fn layer_dex_wildcard_returns_strings_on_single_dex() {
let ctx = CrossLayerContext::parse(&classes_dex(), None).expect("parse classes.dex");
assert!(!ctx.dex.is_empty(), "fixture should have ≥1 DEX layer");
let v = strings(&ctx, None, None, None, Some("dex")).expect("strings call");
let arr = v.get("strings").and_then(Value::as_array).expect("strings array");
assert!(
!arr.is_empty(),
"`--layer dex` wildcard must emit strings on a DEX context (was 0 prior to filter-shape fix)"
);
for entry in arr {
let layer = entry.get("layer").and_then(Value::as_str).unwrap_or("");
assert!(
layer.starts_with("dex"),
"every entry under `--layer dex` must have a dex* layer; got {layer:?}"
);
}
}
#[test]
fn layer_dex_specific_matches_only_that_layer() {
let ctx = CrossLayerContext::parse(&classes_dex(), None).expect("parse classes.dex");
let v = strings(&ctx, None, None, None, Some("dex1")).expect("strings call");
let arr = v.get("strings").and_then(Value::as_array).expect("strings array");
for entry in arr {
let layer = entry.get("layer").and_then(Value::as_str).unwrap_or("");
assert_eq!(
layer, "dex1",
"`--layer dex1` must emit only dex1 entries; got {layer:?}"
);
}
}
#[test]
fn layer_none_returns_all_layers() {
let ctx = CrossLayerContext::parse(&classes_dex(), None).expect("parse classes.dex");
let v = strings(&ctx, None, None, None, None).expect("strings call");
let arr = v.get("strings").and_then(Value::as_array).expect("strings array");
assert!(
!arr.is_empty(),
"filter=None must emit every available layer (≥1 entry on a DEX-bearing context)"
);
}