|
40 | 40 | TrueFalseScorer, |
41 | 41 | ) |
42 | 42 | from pyrit.score.fallback_scorer import _FallbackScorer |
| 43 | +from pyrit.score.score_utils import ORIGINAL_FLOAT_VALUE_KEY, normalize_score_to_float |
43 | 44 |
|
44 | 45 | pytestmark = pytest.mark.usefixtures("patch_central_database") |
45 | 46 |
|
@@ -156,6 +157,25 @@ async def test_complete_primary_skips_fallback_async( |
156 | 157 | assert isinstance(wrapper, FloatScaleScorer if family == "float_scale" else TrueFalseScorer) |
157 | 158 |
|
158 | 159 |
|
| 160 | +@pytest.mark.parametrize("primary_resolves", [False, True]) |
| 161 | +async def test_selected_original_float_value_stays_readable_async(*, primary_resolves: bool) -> None: |
| 162 | + primary, fallback = _TrueFalseScorer(), _TrueFalseScorer() |
| 163 | + wrapper = TrueFalseFallbackScorer(scorer=primary, fallback_scorer=fallback) |
| 164 | + primary_score = _score( |
| 165 | + family="true_false", |
| 166 | + value="True" if primary_resolves else None, |
| 167 | + metadata={ORIGINAL_FLOAT_VALUE_KEY: 0.3}, |
| 168 | + ) |
| 169 | + fallback_score = _score(family="true_false", value="True", metadata={ORIGINAL_FLOAT_VALUE_KEY: 0.6}) |
| 170 | + with ( |
| 171 | + patch.object(primary, "_score_scorable_async", new_callable=AsyncMock, return_value=[primary_score]), |
| 172 | + patch.object(fallback, "_score_scorable_async", new_callable=AsyncMock, return_value=[fallback_score]), |
| 173 | + ): |
| 174 | + result = (await wrapper.score_async(scorable=ContentScorable(value="evidence")))[0] |
| 175 | + |
| 176 | + assert normalize_score_to_float(result) == (0.3 if primary_resolves else 0.6) |
| 177 | + |
| 178 | + |
159 | 179 | @pytest.mark.parametrize("fallback_abstains", [False, True]) |
160 | 180 | async def test_fallback_preserves_both_attempts_without_mutating_children_async( |
161 | 181 | *, pair: tuple[Scorer, Scorer, Scorer], family: ScoreType, fallback_abstains: bool, sqlite_instance: MemoryInterface |
|
0 commit comments