uitest.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env python3
  2. """End-to-end UI test for the shell: compile-error jump + Ctrl-K-D quit.
  3. Compiler correctness is covered by matrix/run_compile_tests.sh (fast, no pty).
  4. This test covers the *shell* behaviour that only exists interactively:
  5. 1. W loads a work file (LoadWorkFile ends with a Pause: needs a filler key)
  6. 2. C reports a TP3 error (error number + relative text position)
  7. 3. ESC opens the editor with the cursor ON the error position
  8. (TP3 kcwait: waitesc ; BX:=txerrpos ; DEC BX ; JMP editor2)
  9. 4. Ctrl-K D returns to the main menu
  10. 5. Q exits the shell cleanly with status 0
  11. (a bare HALT aborts with SIGABRT under gm2 -fiso)
  12. Fixture: uierror.pas has a deliberate *syntax* error (a missing operand
  13. after '+'), reported as error 41 at pos 331 = line 9, column 12 (1-based).
  14. A syntax error is used deliberately rather than, say, a missing library
  15. feature: those come and go as the compiler grows, and a UI test whose
  16. expectations drift with it stops being a test.
  17. Usage: uitest.py [fixture.pas]
  18. """
  19. import os
  20. import sys
  21. sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
  22. from ptyharness import CTRL_K, SHELL_DIR, Screen, drain, reap, send, spawn, status_str, visible
  23. FIXTURE = sys.argv[1] if len(sys.argv) > 1 else os.path.join(
  24. os.path.dirname(os.path.abspath(__file__)), "fixtures", "uierror.pas")
  25. EXPECT_ERR = "41"
  26. EXPECT_LINE = 9
  27. EXPECT_COL = 12
  28. def main():
  29. pid, fd = spawn()
  30. checks = []
  31. try:
  32. drain(fd, quiet=0.6)
  33. send(fd, b"w")
  34. send(fd, FIXTURE.encode())
  35. send(fd, b"\r", quiet=0.8)
  36. send(fd, b" ", quiet=0.5) # clears LoadWorkFile's Pause
  37. comp = visible(send(fd, b"c", quiet=1.5))
  38. checks.append(("compile reports a TP3 error", "TP3-style error" in comp))
  39. checks.append(("error number is %s (not the 0 from the old "
  40. "self-assignment)" % EXPECT_ERR,
  41. ("error %s " % EXPECT_ERR) in comp))
  42. checks.append(("compile did not claim success", "Compiled OK" not in comp))
  43. ed = send(fd, b"\x1b", quiet=1.0) # accept the error jump
  44. scr = Screen()
  45. scr.feed(ed)
  46. text = scr.text()
  47. row = scr.row_with("x := 1 +")
  48. checks.append(("editor opened", "Line %d" % EXPECT_LINE in text))
  49. checks.append(("cursor on the faulty line (that row carries the bad stmt)",
  50. row is not None))
  51. checks.append(("status line reports Line %d" % EXPECT_LINE,
  52. ("Line %d" % EXPECT_LINE) in text.split("\n")[0]))
  53. checks.append(("status line reports Col %d" % EXPECT_COL,
  54. ("Col %d" % EXPECT_COL) in text.split("\n")[0]))
  55. checks.append(("cursor is on that row", row is not None and row == scr.r))
  56. send(fd, CTRL_K, quiet=0.4)
  57. after = visible(send(fd, b"d", quiet=0.6))
  58. checks.append(("Ctrl-K D returned to the main menu", "Main file" in after))
  59. send(fd, b"q", quiet=0.6)
  60. finally:
  61. status = reap(fd, pid)
  62. checks.append(("shell exited cleanly (status 0)", os.WIFEXITED(status)
  63. and os.WEXITSTATUS(status) == 0))
  64. print("UI TEST: %s" % os.path.basename(FIXTURE))
  65. print("-" * 60)
  66. ok = True
  67. for name, passed in checks:
  68. print("%-58s %s" % (name, "PASS" if passed else "FAIL"))
  69. ok = ok and passed
  70. print("-" * 60)
  71. print("child: %s" % status_str(status))
  72. print("RESULT: %s" % ("ALL PASS" if ok else "FAILURES PRESENT"))
  73. return 0 if ok else 1
  74. if __name__ == "__main__":
  75. sys.exit(main())