fix: stdin TTY 偵測改以 fd 0 實際裝置判定,escript 真終端機不再誤判(issue #19)
- 新增 BearCli.TTY:readlink /proc/self/fd/0 判定 pts/tty/console/ptmx; 無 /proc 平台退回 :io.rows/0 - vault/self_service 的 tty_stdin?、accounts 的 tty? 改用 TTY.stdin_tty? - 根因::io.rows/0/:io.columns/0 走 io 協定問 group leader,escript (noshell standard_io)不支援行列查詢,一律回 enotsup——真終端機被 誤判成非 TTY,互動指令(vault unlock 等)無法讀 stdin 密碼 (bear #52 驗收建議 2) - 非 TTY(pipe/redirect)行為不變:明確提示+退出碼 2 - 新增 tty_test(4 測試);mix precommit 全綠(200 passed)
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
defmodule BearCli.TTYTest do
|
||||
@moduledoc """
|
||||
`BearCli.TTY` 單元測試(issue #19):
|
||||
|
||||
- `tty_path?/1`:裝置路徑分類(pts/tty/console=TTY;pipe/檔案/
|
||||
socket//dev/null=非 TTY)。
|
||||
- `stdin_tty?/0`:在本測試環境(ExUnit 捕獲 IO,stdin 非 TTY)應為
|
||||
`false`;`rows_tty?/0` 在 escript/noshell 環境回 `enotsup` → `false`。
|
||||
- fd 0 偵測走 `/proc/self/fd/0`,Linux 上必可用。
|
||||
"""
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias BearCli.TTY
|
||||
|
||||
describe "tty_path?/1" do
|
||||
test "終端機裝置路徑 → true" do
|
||||
assert TTY.tty_path?("/dev/pts/0")
|
||||
assert TTY.tty_path?("/dev/pts/17")
|
||||
assert TTY.tty_path?("/dev/tty1")
|
||||
assert TTY.tty_path?("/dev/tty")
|
||||
assert TTY.tty_path?("/dev/ttyS0")
|
||||
assert TTY.tty_path?("/dev/console")
|
||||
assert TTY.tty_path?("/dev/ptmx")
|
||||
end
|
||||
|
||||
test "pipe/檔案/socket/null → false" do
|
||||
refute TTY.tty_path?("pipe:[12345]")
|
||||
refute TTY.tty_path?("socket:[12345]")
|
||||
refute TTY.tty_path?("/dev/null")
|
||||
refute TTY.tty_path?("/home/user/secret.txt")
|
||||
refute TTY.tty_path?("/proc/self/fd/0")
|
||||
refute TTY.tty_path?("")
|
||||
end
|
||||
end
|
||||
|
||||
describe "stdin_tty?/0" do
|
||||
test "測試環境(stdin 非 TTY)→ false" do
|
||||
# ExUnit 的 group leader 為擷取裝置、測試程序的 stdin 非終端機。
|
||||
refute TTY.stdin_tty?()
|
||||
end
|
||||
end
|
||||
|
||||
describe "fd0 實體判定(Linux /proc)" do
|
||||
test "/proc/self/fd/0 可解析且與路徑分類一致" do
|
||||
# 本測試在 Linux 跑:readlink 一定有結果;stdin 非 TTY → 分類為非 TTY。
|
||||
assert {:ok, path} = call_fd0_path()
|
||||
assert TTY.stdin_tty?() == TTY.tty_path?(path)
|
||||
end
|
||||
end
|
||||
|
||||
defp call_fd0_path do
|
||||
case :file.read_link('/proc/self/fd/0') do
|
||||
{:ok, p} -> {:ok, to_string(p)}
|
||||
{:error, e} -> {:error, e}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user