| 186 | # ============================================================================= |
| 187 | |
| 188 | class TestResponseValidator: |
| 189 | |
| 190 | def setup_method(self): |
| 191 | self.validator = ResponseValidator() |
| 192 | |
| 193 | def test_empty_response_fails(self): |
| 194 | schema = ResponseSchema() |
| 195 | result = self.validator.validate("", schema) |
| 196 | assert result.passed is False |
| 197 | assert result.failure_mode == FailureMode.CONSTRAINT_VIOLATION |
| 198 | |
| 199 | def test_valid_json_passes(self): |
| 200 | schema = ResponseSchema(must_be_json=True, required_keys=["key"]) |
| 201 | result = self.validator.validate('{"key": "value"}', schema) |
| 202 | assert result.passed is True |
| 203 | |
| 204 | def test_invalid_json_fails(self): |
| 205 | schema = ResponseSchema(must_be_json=True) |
| 206 | result = self.validator.validate("not json", schema) |
| 207 | assert result.passed is False |
| 208 | assert result.failure_mode == FailureMode.SCHEMA_VIOLATION |
| 209 | |
| 210 | def test_missing_required_key_fails(self): |
| 211 | schema = ResponseSchema(must_be_json=True, required_keys=["missing_key"]) |
| 212 | result = self.validator.validate('{"other": "value"}', schema) |
| 213 | assert result.passed is False |
| 214 | assert result.failure_mode == FailureMode.SCHEMA_VIOLATION |
| 215 | |
| 216 | def test_max_length_enforced(self): |
| 217 | schema = ResponseSchema(max_length=10) |
| 218 | result = self.validator.validate("This is longer than ten characters.", schema) |
| 219 | assert result.passed is False |
| 220 | |
| 221 | def test_min_length_enforced(self): |
| 222 | schema = ResponseSchema(min_length=50) |
| 223 | result = self.validator.validate("Too short.", schema) |
| 224 | assert result.passed is False |
| 225 | |
| 226 | def test_forbidden_phrase_blocked(self): |
| 227 | schema = ResponseSchema(forbidden_phrases=["I cannot"]) |
| 228 | result = self.validator.validate("I cannot help with that.", schema) |
| 229 | assert result.passed is False |
| 230 | |
| 231 | def test_json_with_markdown_fencing_passes(self): |
| 232 | schema = ResponseSchema(must_be_json=True, required_keys=["key"]) |
| 233 | result = self.validator.validate('```json\n{"key": "value"}\n```', schema) |
| 234 | assert result.passed is True |
| 235 | |
| 236 | def test_quality_score_calculated(self): |
| 237 | schema = ResponseSchema(must_contain=["token", "budget"]) |
| 238 | result = self.validator.validate("token budget allocation", schema) |
| 239 | assert result.passed is True |
| 240 | assert result.score == 1.0 |
| 241 | |
| 242 | def test_partial_quality_score(self): |
| 243 | schema = ResponseSchema(must_contain=["token", "budget"]) |
| 244 | result = self.validator.validate("only token here", schema) |
| 245 | assert result.score == 0.5 |
nothing calls this directly
no outgoing calls
no test coverage detected