Files
bear-cli/test/bear_cli/tty_test.exs
alex a29b976f13 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)
2026-09-14 19:26:23 +08:00

58 lines
1.9 KiB
Elixir
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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