11# Copyright (c) Microsoft Corporation.
22# Licensed under the MIT license.
33
4+ import pytest
5+ from colorama import Fore , Style
6+
47from pyrit .models import Score , ScoreStatus
58from pyrit .output .score .pretty import PrettyScorePrinter
69
@@ -22,3 +25,68 @@ async def test_render_async_supports_undetermined_score() -> None:
2225 output = await printer .render_async ([score ])
2326
2427 assert "Value: undetermined" in output
28+
29+
30+ @pytest .mark .parametrize (
31+ ("categories" , "expected" ),
32+ [
33+ (["refusal" ], "refusal" ),
34+ (["refusal" , "scams" ], "refusal, scams" ),
35+ (["scams" , "refusal" , "scams" ], "scams, refusal, scams" ),
36+ ],
37+ )
38+ async def test_render_async_joins_score_categories (* , categories : list [str ], expected : str ) -> None :
39+ printer = PrettyScorePrinter (enable_colors = False )
40+ score = Score (score_value = "true" , score_type = "true_false" , score_category = categories )
41+
42+ output = await printer .render_async ([score ])
43+
44+ assert f"Category: { expected } " in output
45+
46+
47+ @pytest .mark .parametrize ("enable_colors" , [False , True ])
48+ @pytest .mark .parametrize (
49+ ("categories" , "expected" ),
50+ [
51+ (["refusal\n scams" ], r"refusal\nscams" ),
52+ (["refusal\r \n scams" ], r"refusal\r\nscams" ),
53+ (["refusal\r scams" ], r"refusal\rscams" ),
54+ (["\n refusal\n \n " ], r"\nrefusal\n\n" ),
55+ (["refusal\n scams" , "other\n category" ], r"refusal\nscams, other\ncategory" ),
56+ ([r"refusal\nscams" ], r"refusal\nscams" ),
57+ ],
58+ )
59+ async def test_write_async_keeps_category_line_breaks_on_one_line (
60+ * ,
61+ categories : list [str ],
62+ expected : str ,
63+ enable_colors : bool ,
64+ capsys : pytest .CaptureFixture [str ],
65+ ) -> None :
66+ printer = PrettyScorePrinter (enable_colors = enable_colors )
67+ score = Score (
68+ score_value = "true" ,
69+ score_type = "true_false" ,
70+ score_category = categories ,
71+ score_metadata = {"note" : "unchanged" },
72+ )
73+ original = score .model_dump (mode = "json" )
74+
75+ await printer .write_async ([score ])
76+
77+ lines = capsys .readouterr ().out .splitlines ()
78+ category_line = f" \u2022 Category: { expected } "
79+ if enable_colors :
80+ category_line = f"{ Fore .LIGHTMAGENTA_EX } { category_line } { Style .RESET_ALL } "
81+ assert lines [1 ] == category_line
82+ assert len (lines ) == 4
83+ assert score .model_dump (mode = "json" ) == original
84+
85+
86+ async def test_render_async_renders_missing_category_as_na () -> None :
87+ printer = PrettyScorePrinter (enable_colors = False )
88+ score = Score (score_value = "true" , score_type = "true_false" )
89+
90+ output = await printer .render_async ([score ])
91+
92+ assert "Category: N/A" in output
0 commit comments