feat(web): implement complete workspace with themes, tabs, sidebar, and mobile
Transform CalcText from a single-document calculator into a full workspace application with multi-document support, theming, and responsive mobile experience. - Theme system: 5 presets (Light, Dark, Matrix, Midnight, Warm) + accent colors - Document model with localStorage persistence and auto-save - Tab bar with keyboard shortcuts (Ctrl+N/W/Tab/1-9), rename, close - Sidebar with search, recent, favorites, folders, templates, drag-and-drop - 5 templates: Budget, Invoice, Unit Converter, Trip Planner, Loan Calculator - Status bar with cursor position, engine status, dedication to Igor Cassel - Results panel: type-specific colors, click-to-copy, error hints - Format toolbar: H, B, I, //, color labels with live preview toggle - Syntax highlighting using theme CSS variables - Error hover tooltips - Mobile: bottom results tray, sidebar drawer, touch targets, safe areas - Docker multi-stage build (Rust WASM + Vite + Nginx) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
95
_scripts/smoke-test.sh
Executable file
95
_scripts/smoke-test.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
# smoke-test.sh — Quick verification of CalcPad CLI and web app
|
||||
set -euo pipefail
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
SKIP=0
|
||||
|
||||
pass() { echo " PASS: $1"; ((PASS++)); }
|
||||
fail() { echo " FAIL: $1"; ((FAIL++)); }
|
||||
skip() { echo " SKIP: $1"; ((SKIP++)); }
|
||||
|
||||
# ─── CLI Tests ──────────────────────────────────────────────────────────────────
|
||||
|
||||
echo ""
|
||||
echo "=== CLI Tests ==="
|
||||
|
||||
if command -v cargo &>/dev/null; then
|
||||
|
||||
# 1. Basic arithmetic
|
||||
result=$(cargo run -q -p calcpad-cli -- "2 + 3" 2>/dev/null)
|
||||
if [[ "$result" == *"5"* ]]; then pass "arithmetic: 2 + 3 = 5"
|
||||
else fail "arithmetic: expected 5, got '$result'"; fi
|
||||
|
||||
# 2. Pipe / stdin
|
||||
result=$(echo -e "x = 10\nx * 3" | cargo run -q -p calcpad-cli 2>/dev/null)
|
||||
if [[ "$result" == *"30"* ]]; then pass "pipe/stdin: x=10, x*3 = 30"
|
||||
else fail "pipe/stdin: expected 30 in output, got '$result'"; fi
|
||||
|
||||
# 3. JSON output
|
||||
result=$(cargo run -q -p calcpad-cli -- --format json "42" 2>/dev/null)
|
||||
if [[ "$result" == *"42"* ]] && [[ "$result" == *"{"* ]]; then pass "JSON output"
|
||||
else fail "JSON output: expected JSON with 42, got '$result'"; fi
|
||||
|
||||
# 4. Error exit code for invalid input
|
||||
if cargo run -q -p calcpad-cli -- "???invalid???" &>/dev/null; then
|
||||
fail "error exit code: expected non-zero exit"
|
||||
else
|
||||
pass "error exit code: non-zero on bad input"
|
||||
fi
|
||||
|
||||
# 5. cargo test suite
|
||||
if cargo test --workspace -q 2>/dev/null; then pass "cargo test --workspace"
|
||||
else fail "cargo test --workspace"; fi
|
||||
|
||||
else
|
||||
skip "CLI tests (cargo not found)"
|
||||
fi
|
||||
|
||||
# ─── Web Tests ──────────────────────────────────────────────────────────────────
|
||||
|
||||
echo ""
|
||||
echo "=== Web Tests ==="
|
||||
|
||||
WEB_URL="${WEB_URL:-http://localhost:8080}"
|
||||
|
||||
if curl -sf "$WEB_URL" &>/dev/null; then
|
||||
|
||||
# 1. index.html returns 200
|
||||
status=$(curl -sf -o /dev/null -w "%{http_code}" "$WEB_URL/")
|
||||
if [[ "$status" == "200" ]]; then pass "index.html 200"
|
||||
else fail "index.html: got HTTP $status"; fi
|
||||
|
||||
# 2. HTML contains expected content
|
||||
body=$(curl -sf "$WEB_URL/")
|
||||
if [[ "$body" == *"CalcPad"* ]]; then pass "HTML contains CalcPad"
|
||||
else fail "HTML missing CalcPad title"; fi
|
||||
|
||||
# 3. WASM JS glue is served
|
||||
wasm_js_status=$(curl -sf -o /dev/null -w "%{http_code}" "$WEB_URL/wasm/calcpad_wasm.js")
|
||||
if [[ "$wasm_js_status" == "200" ]]; then pass "WASM JS served"
|
||||
else fail "WASM JS: got HTTP $wasm_js_status"; fi
|
||||
|
||||
# 4. WASM binary content-type
|
||||
ct=$(curl -sf -o /dev/null -w "%{content_type}" "$WEB_URL/wasm/calcpad_wasm_bg.wasm")
|
||||
if [[ "$ct" == *"wasm"* ]]; then pass "WASM content-type: $ct"
|
||||
else fail "WASM content-type: expected wasm, got '$ct'"; fi
|
||||
|
||||
# 5. SPA fallback — non-existent route returns index.html
|
||||
fallback=$(curl -sf "$WEB_URL/nonexistent/route")
|
||||
if [[ "$fallback" == *"CalcPad"* ]]; then pass "SPA fallback"
|
||||
else fail "SPA fallback: did not return index.html"; fi
|
||||
|
||||
else
|
||||
skip "Web tests ($WEB_URL not reachable — run 'docker compose up -d' first)"
|
||||
fi
|
||||
|
||||
# ─── Summary ────────────────────────────────────────────────────────────────────
|
||||
|
||||
echo ""
|
||||
echo "=== Summary ==="
|
||||
echo " Passed: $PASS Failed: $FAIL Skipped: $SKIP"
|
||||
|
||||
if [[ $FAIL -gt 0 ]]; then exit 1; fi
|
||||
exit 0
|
||||
Reference in New Issue
Block a user