1
0
mirror of https://github.com/tw93/Mole.git synced 2026-03-22 20:15:07 +00:00

feat: add JSON output tests and README docs for analyze and status (#556)

* feat: add JSON output tests and README docs for analyze and status

Add 7 BATS tests covering `--json` output for `mo analyze` and `mo status`:
- schema structure
- field types
- pipe auto-detection.

Also document the `--json` flag in a new "Machine-Readable Output" README section, including the auto-detection behavior when piped.

* chore: use waitgroup go in status collector

---------

Co-authored-by: Tw93 <hitw93@gmail.com>
This commit is contained in:
Dylan Joss
2026-03-12 20:40:41 -07:00
committed by GitHub
parent cce26022f3
commit 7350547458
3 changed files with 179 additions and 4 deletions

View File

@@ -11,6 +11,19 @@ setup_file() {
export HOME
mkdir -p "$HOME"
# Build Go binaries from current source for JSON tests.
# Point GOPATH/GOMODCACHE at the real home so go build doesn't write
# module caches into the fake HOME under tests/.
if command -v go > /dev/null 2>&1; then
ANALYZE_BIN="$(mktemp "${TMPDIR:-/tmp}/analyze-go.XXXXXX")"
STATUS_BIN="$(mktemp "${TMPDIR:-/tmp}/status-go.XXXXXX")"
GOPATH="${ORIGINAL_HOME}/go" GOMODCACHE="${ORIGINAL_HOME}/go/pkg/mod" \
go build -o "$ANALYZE_BIN" "$PROJECT_ROOT/cmd/analyze" 2>/dev/null
GOPATH="${ORIGINAL_HOME}/go" GOMODCACHE="${ORIGINAL_HOME}/go/pkg/mod" \
go build -o "$STATUS_BIN" "$PROJECT_ROOT/cmd/status" 2>/dev/null
export ANALYZE_BIN STATUS_BIN
fi
}
teardown_file() {
@@ -19,6 +32,7 @@ teardown_file() {
if [[ -n "${ORIGINAL_HOME:-}" ]]; then
export HOME="$ORIGINAL_HOME"
fi
rm -f "${ANALYZE_BIN:-}" "${STATUS_BIN:-}"
}
create_fake_utils() {
@@ -278,3 +292,130 @@ EOF
run grep "pam_tid.so" "$pam_file"
[ "$status" -ne 0 ]
}
# --- JSON output mode tests ---
@test "mo analyze --json outputs valid JSON with expected fields" {
if [[ ! -x "${ANALYZE_BIN:-}" ]]; then
skip "analyze binary not available (go not installed?)"
fi
run "$ANALYZE_BIN" --json /tmp
[ "$status" -eq 0 ]
# Validate it is parseable JSON
echo "$output" | python3 -c "import sys, json; json.load(sys.stdin)"
# Check required top-level keys
echo "$output" | python3 -c "
import sys, json
data = json.load(sys.stdin)
assert 'path' in data, 'missing path'
assert 'entries' in data, 'missing entries'
assert 'total_size' in data, 'missing total_size'
assert 'total_files' in data, 'missing total_files'
assert isinstance(data['entries'], list), 'entries is not a list'
"
}
@test "mo analyze --json entries contain required fields" {
if [[ ! -x "${ANALYZE_BIN:-}" ]]; then
skip "analyze binary not available (go not installed?)"
fi
run "$ANALYZE_BIN" --json /tmp
[ "$status" -eq 0 ]
echo "$output" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for entry in data['entries']:
assert 'name' in entry, 'entry missing name'
assert 'path' in entry, 'entry missing path'
assert 'size' in entry, 'entry missing size'
assert 'is_dir' in entry, 'entry missing is_dir'
"
}
@test "mo analyze --json path reflects target directory" {
if [[ ! -x "${ANALYZE_BIN:-}" ]]; then
skip "analyze binary not available (go not installed?)"
fi
run "$ANALYZE_BIN" --json /tmp
[ "$status" -eq 0 ]
echo "$output" | python3 -c "
import sys, json
data = json.load(sys.stdin)
assert data['path'] == '/tmp' or data['path'] == '/private/tmp', \
f\"unexpected path: {data['path']}\"
"
}
@test "mo status --json outputs valid JSON with expected fields" {
if [[ ! -x "${STATUS_BIN:-}" ]]; then
skip "status binary not available (go not installed?)"
fi
run "$STATUS_BIN" --json
[ "$status" -eq 0 ]
# Validate it is parseable JSON
echo "$output" | python3 -c "import sys, json; json.load(sys.stdin)"
# Check required top-level keys
echo "$output" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for key in ['cpu', 'memory', 'disks', 'health_score', 'host', 'uptime']:
assert key in data, f'missing key: {key}'
"
}
@test "mo status --json cpu section has expected structure" {
if [[ ! -x "${STATUS_BIN:-}" ]]; then
skip "status binary not available (go not installed?)"
fi
run "$STATUS_BIN" --json
[ "$status" -eq 0 ]
echo "$output" | python3 -c "
import sys, json
data = json.load(sys.stdin)
cpu = data['cpu']
assert 'usage' in cpu, 'cpu missing usage'
assert 'logical_cpu' in cpu, 'cpu missing logical_cpu'
assert isinstance(cpu['usage'], (int, float)), 'cpu usage is not a number'
"
}
@test "mo status --json memory section has expected structure" {
if [[ ! -x "${STATUS_BIN:-}" ]]; then
skip "status binary not available (go not installed?)"
fi
run "$STATUS_BIN" --json
[ "$status" -eq 0 ]
echo "$output" | python3 -c "
import sys, json
data = json.load(sys.stdin)
mem = data['memory']
assert 'total' in mem, 'memory missing total'
assert 'used' in mem, 'memory missing used'
assert 'used_percent' in mem, 'memory missing used_percent'
assert mem['total'] > 0, 'memory total should be positive'
"
}
@test "mo status --json piped to stdout auto-detects JSON mode" {
if [[ ! -x "${STATUS_BIN:-}" ]]; then
skip "status binary not available (go not installed?)"
fi
# When piped (not a tty), status should auto-detect and output JSON
output=$("$STATUS_BIN" 2>/dev/null)
echo "$output" | python3 -c "import sys, json; json.load(sys.stdin)"
}