import csv from pathlib import Path from src.config_loader import load_config from src.quality_checker import QualityChecker def write_table(path:Path,rows:list[dict])->None: path.parent.mkdir(parents=True);fields=["prompt_condition","valid_for_voice_analysis","turn_level","pose_estimated_ever","camera_position_note","reaction_time_sec","response_detected"] with path.open("w",encoding="utf-8-sig",newline="") as f:w=csv.DictWriter(f,fieldnames=fields);w.writeheader();w.writerows(rows) def test_missing_files_and_exports(tmp_path:Path)->None: q=QualityChecker(load_config("config/default.yaml",None).quality_check);issues=q.check(tmp_path/"logs",tmp_path/"analysis");assert any(i.issue_type=="missing_file" for i in issues) assert q.export_csv(issues,tmp_path/"quality_issues.csv").read_bytes().startswith(b"\xef\xbb\xbf");assert "ログ品質" in q.export_markdown(issues,tmp_path/"quality.md").read_text(encoding="utf-8") def test_quality_rates_conditions_and_negative_time(tmp_path:Path)->None: table=tmp_path/"logs"/"x_person_analysis_table.csv";write_table(table,[{"prompt_condition":"prompt","valid_for_voice_analysis":"false","turn_level":"not_evaluable","pose_estimated_ever":"false","camera_position_note":"","reaction_time_sec":"-1","response_detected":"true"}]);q=QualityChecker(load_config("config/default.yaml",None).quality_check);types={i.issue_type for i in q.check(tmp_path/"logs",tmp_path/"analysis")};assert {"no_control_records","low_valid_voice_analysis_rate","high_not_evaluable_rate","high_no_pose_rate","missing_camera_position_note","negative_reaction_time"}<=types