Files
hakorune/tools/smokes/v2/lib/output_validator.sh
nyash-codex 5602aff8a9 refactor(smokes): add output_validator.sh for SSOT numeric assertion
Output検証をSSOT化して保守性を向上

**新規追加**:
- tools/smokes/v2/lib/output_validator.sh
  - extract_numeric_lines N: 数値行をN行抽出(パターンマッチング)
  - assert_equals_multiline EXPECTED ACTUAL: 複数行期待値と比較
  - validate_numeric_output N EXPECTED OUTPUT: extract + assert の合成Box

**リファクタリング対象** (5ファイル):
- phase103_if_only_vm.sh
- phase103_if_only_early_return_vm.sh
- phase113_if_only_partial_assign_vm.sh
- phase114_if_only_return_then_post_vm.sh
- phase115_if_only_call_merge_vm.sh

**変更内容**:
- 重複パターン `grep -E '^-?[0-9]+$' | head -n N` → `extract_numeric_lines N`
- 比較ロジック → `validate_numeric_output` に統一
- 各smokeは `source output_validator.sh` で共通機能を利用

**検証結果**:
- phase103_if_only_vm: PASS 
- phase103_if_only_early_return_vm: PASS 
- phase113_if_only_partial_assign_vm: PASS 
- phase114_if_only_return_then_post_vm: PASS 
- phase115_if_only_call_merge_vm: PASS 

**箱化モジュール化の成果**:
- 単一責任: extract_numeric_lines(抽出のみ)、assert_equals_multiline(比較のみ)
- 分離: 各機能が独立したBox(テスト容易性向上)
- 合成: validate_numeric_output が extract + assert を組み合わせ
- Fail-Fast: 全関数でパラメータチェック(明示的エラー)
- 保守性: 検証パターン変更時は output_validator.sh の1箇所のみ修正

**設計原則**:
- Box-First: 機能を箱に切り出して境界を明確化
- SSOT: 数値行抽出と検証ロジックを1箇所に集約
- Fail-Fast: パラメータ不正時は即座にエラー(フォールバックなし)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 02:32:32 +09:00

77 lines
2.3 KiB
Bash

#!/bin/bash
# Output Validator SSOT
# Single Source of Truth for smoke test output validation
#
# Box-First principle: Separation of concerns
# - Extract: Pattern-based extraction (numeric lines, etc.)
# - Assert: Comparison and failure reporting
#
# Fail-Fast principle: Explicit errors with clear messages
set -e
# Extract numeric lines from output
# Usage: extract_numeric_lines N < output.txt
# Returns: First N lines that match numeric pattern (including negative numbers)
extract_numeric_lines() {
local limit="$1"
if [ -z "$limit" ]; then
echo "[ERROR] extract_numeric_lines: limit parameter required" >&2
return 1
fi
# Pattern: optional minus, followed by digits
# Use head to limit output
grep -E '^-?[0-9]+$' | head -n "$limit" | tr -d '\r'
}
# Assert multiline string equality
# Usage: assert_equals_multiline EXPECTED ACTUAL
# Returns: 0 if equal, 1 if different (with error message)
assert_equals_multiline() {
local expected="$1"
local actual="$2"
if [ -z "$expected" ]; then
echo "[ERROR] assert_equals_multiline: expected parameter required" >&2
return 1
fi
if [ "$actual" = "$expected" ]; then
return 0
else
echo "[FAIL] Output mismatch" >&2
echo "[EXPECTED]:" >&2
echo "$expected" >&2
echo "[ACTUAL]:" >&2
echo "$actual" >&2
return 1
fi
}
# Validate numeric output (extract + assert in one step)
# Usage: validate_numeric_output EXPECTED_LINES EXPECTED_VALUE OUTPUT
# Returns: 0 if valid, 1 if invalid
validate_numeric_output() {
local expected_lines="$1"
local expected_value="$2"
local output="$3"
if [ -z "$expected_lines" ] || [ -z "$expected_value" ]; then
echo "[ERROR] validate_numeric_output: expected_lines and expected_value required" >&2
return 1
fi
local clean
clean=$(printf "%s\n" "$output" | extract_numeric_lines "$expected_lines")
assert_equals_multiline "$expected_value" "$clean"
}
# Box-First design notes:
# 1. extract_numeric_lines: Single Responsibility - extraction only
# 2. assert_equals_multiline: Single Responsibility - comparison only
# 3. validate_numeric_output: Composition box - combines extract + assert
# 4. All functions follow Fail-Fast principle - explicit parameter checks
# 5. Clear separation of concerns - easy to extend with new patterns