run.sh 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/env bash
  2. # Self-test for python-pytest-ops — fully offline, deterministic, Linux-safe.
  3. #
  4. # generate-conftest.sh writes ./tests/conftest.py relative to the cwd and, when
  5. # one already exists, prompts interactively (defaulting to KEEP the file). Every
  6. # run executes inside a mktemp -d sandbox so nothing is ever written into the
  7. # repo or a real project. Asserts the --help contract, the generated conftest's
  8. # fixture blocks (base + --async/--db/--api), and the overwrite-safety guarantee:
  9. # an existing user conftest.py is NOT clobbered unless the user answers the
  10. # prompt with "y" (the documented mechanism — fed "n" here keeps the file).
  11. #
  12. # Usage: bash tests/run.sh
  13. # Exit: 0 all pass, 1 one or more failures
  14. set -uo pipefail
  15. HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  16. SKILL="$(dirname "$HERE")"
  17. V="$SKILL/scripts/generate-conftest.sh"
  18. SB="$(mktemp -d)"; trap 'rm -rf "$SB"' EXIT
  19. PASS=0; FAIL=0
  20. ok() { PASS=$((PASS+1)); printf ' PASS %s\n' "$1"; }
  21. no() { FAIL=$((FAIL+1)); printf ' FAIL %s\n' "$1"; }
  22. expect_exit() { [[ "$2" == "$3" ]] && ok "$1 (exit $3)" || no "$1 (want $2 got $3)"; }
  23. expect_has() { case "$3" in *"$2"*) ok "$1";; *) no "$1 (missing '$2')";; esac; }
  24. echo "=== python-pytest-ops self-test ==="
  25. # ── contract ──────────────────────────────────────────────────────────────────
  26. echo "-- contract --"
  27. bash -n "$V" 2>/dev/null && ok "bash -n generate-conftest.sh" || no "bash -n generate-conftest.sh"
  28. bash "$V" --help >/dev/null 2>&1; expect_exit "--help exits 0" 0 $?
  29. bash "$V" -h >/dev/null 2>&1; expect_exit "-h exits 0" 0 $?
  30. out="$(bash "$V" --help 2>/dev/null)"
  31. expect_has "--help has Examples" "xamples" "$out"
  32. expect_has "--help lists --async" "--async" "$out"
  33. expect_has "--help lists --db" "--db" "$out"
  34. expect_has "--help lists --api" "--api" "$out"
  35. # --help must short-circuit before any side effect (no file created even though
  36. # the cwd has no tests/ dir)
  37. mkdir -p "$SB/help-cwd"
  38. ( cd "$SB/help-cwd" && bash "$V" --help >/dev/null 2>&1 )
  39. [[ ! -e "$SB/help-cwd/tests" ]] && ok "--help creates no files" || no "--help created files"
  40. # ── fresh generation ──────────────────────────────────────────────────────────
  41. echo "-- fresh generation --"
  42. mkdir -p "$SB/fresh"
  43. ( cd "$SB/fresh" && bash "$V" </dev/null >"$SB/fresh.out" 2>"$SB/fresh.err" ); expect_exit "fresh generate -> 0" 0 $?
  44. [[ -f "$SB/fresh/tests/conftest.py" ]] && ok "creates tests/conftest.py" || no "conftest.py not created"
  45. out="$(cat "$SB/fresh/tests/conftest.py")"
  46. expect_has "has module docstring" "Pytest configuration and fixtures" "$out"
  47. expect_has "imports pytest" "import pytest" "$out"
  48. expect_has "registers slow marker" '"slow: marks tests as slow"' "$out"
  49. expect_has "has sample_data fixture" "def sample_data():" "$out"
  50. expect_has "has temp_file fixture" "def temp_file(tmp_path):" "$out"
  51. expect_has "has pytest_addoption" "def pytest_addoption(parser):" "$out"
  52. expect_has "summary on stdout" "Generated tests/conftest.py" "$(cat "$SB/fresh.out")"
  53. # ── fixture-block flags ───────────────────────────────────────────────────────
  54. echo "-- fixture blocks --"
  55. mkdir -p "$SB/all"
  56. ( cd "$SB/all" && bash "$V" --async --db --api </dev/null >/dev/null 2>&1 ); expect_exit "all flags -> 0" 0 $?
  57. out="$(cat "$SB/all/tests/conftest.py")"
  58. expect_has "--async adds event_loop" "def event_loop():" "$out"
  59. expect_has "--async adds async_client" "async def async_client():" "$out"
  60. expect_has "--db adds db_engine" "def db_engine():" "$out"
  61. expect_has "--db adds db_session" "def db_session(db_engine):" "$out"
  62. expect_has "--api adds client fixture" "def client(app):" "$out"
  63. expect_has "--api adds authed client" "def authenticated_client(client):" "$out"
  64. # base generation must NOT include the optional blocks
  65. ! grep -q "def event_loop" "$SB/fresh/tests/conftest.py" && ok "base omits async blocks" || no "base included async blocks"
  66. ! grep -q "def db_engine" "$SB/fresh/tests/conftest.py" && ok "base omits db blocks" || no "base included db blocks"
  67. ! grep -q "def client" "$SB/fresh/tests/conftest.py" && ok "base omits api blocks" || no "base included api blocks"
  68. # ── overwrite safety ─────────────────────────────────────────────────────────
  69. echo "-- overwrite safety --"
  70. # Decline ("n", the documented default) MUST preserve an existing user conftest.
  71. mkdir -p "$SB/ow/tests"
  72. printf '# USER-SENTINEL: do not overwrite me\nimport user_thing\n' >"$SB/ow/tests/conftest.py"
  73. ( cd "$SB/ow" && printf 'n\n' | bash "$V" >/dev/null 2>&1 ); expect_exit "decline overwrite -> 0" 0 $?
  74. out="$(cat "$SB/ow/tests/conftest.py")"
  75. expect_has "user conftest preserved (decline)" "USER-SENTINEL" "$out"
  76. expect_has "user import preserved (decline)" "import user_thing" "$out"
  77. # Confirming ("y") DOES replace the file — that is the documented overwrite path.
  78. mkdir -p "$SB/ow2/tests"
  79. printf '# USER-SENTINEL-2\n' >"$SB/ow2/tests/conftest.py"
  80. ( cd "$SB/ow2" && printf 'y\n' | bash "$V" >/dev/null 2>&1 ); expect_exit "confirm overwrite -> 0" 0 $?
  81. out="$(cat "$SB/ow2/tests/conftest.py")"
  82. ! grep -q "USER-SENTINEL-2" "$SB/ow2/tests/conftest.py" && ok "confirm 'y' replaces user conftest" || no "confirm 'y' did not replace"
  83. expect_has "new conftest has pytest import" "import pytest" "$out"
  84. # Non-interactive (closed stdin, no answer) also keeps the existing file — the
  85. # safe default when there is no TTY to answer the prompt.
  86. mkdir -p "$SB/ow3/tests"
  87. printf '# USER-SENTINEL-3\n' >"$SB/ow3/tests/conftest.py"
  88. ( cd "$SB/ow3" && bash "$V" </dev/null >/dev/null 2>&1 )
  89. expect_has "closed-stdin keeps user conftest" "USER-SENTINEL-3" "$(cat "$SB/ow3/tests/conftest.py")"
  90. echo ""
  91. echo "=== $PASS passed, $FAIL failed ==="
  92. [[ "$FAIL" -eq 0 ]] || exit 1
  93. exit 0