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>
77 lines
2.3 KiB
Bash
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
|