blob: d4fdc9ea74323ffd13ef8960a4a1b958ef393012 [file]
#!/usr/bin/env vpython3
# Copyright 2025 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests for lint_promptfoo_testcases."""
import os
import unittest
from unittest import mock
import lint_promptfoo_testcases
class LintPromptfooTestcasesTest(unittest.TestCase):
def setUp(self):
self.mock_file_path = 'agents/test.promptfoo.yaml'
@mock.patch('lint_promptfoo_testcases._get_chromium_src_path',
return_value='/mock/chromium/src')
@mock.patch('os.path.exists', return_value=True)
def test_valid_file_references(self, _mock_exists, _mock_get_src_path):
"""Tests that no errors are returned for a valid config."""
data = {
'providers': [{
'config': {
'changes': [{
'apply': 'file://my_patch.diff'
}, {
'apply': 'file://my_patch_1.diff'
}],
'templates': ['file://my_template.txt'],
'extensions': ['my_extension']
}
}]
}
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 0)
@mock.patch('lint_promptfoo_testcases._get_chromium_src_path',
return_value='/mock/chromium/src')
@mock.patch('os.path.exists', return_value=False)
def test_non_existent_file(self, mock_exists, _mock_get_src_path):
"""Tests that an error is returned for a non-existent file."""
data = {
'providers': [{
'config': {
'changes': [{
'apply': 'file://agents/my_patch.diff'
}],
}
}]
}
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 1)
self.assertIn('refers to a non-existent file', errors[0])
# Check that os.path.exists was called with the absolute path.
expected_path = os.path.join('/mock/chromium/src', 'agents',
'my_patch.diff')
mock_exists.assert_called_with(expected_path)
@mock.patch('lint_promptfoo_testcases._get_chromium_src_path',
return_value='/mock/chromium/src')
@mock.patch('os.path.exists', return_value=False)
def test_non_existent_extension(self, mock_exists, _mock_get_src_path):
"""Tests that an error is returned for a non-existent extension."""
data = {
'providers': [{
'config': {
'extensions': ['non_existent_extension']
}
}]
}
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 1)
self.assertIn('refers to a non-existent extension', errors[0])
expected_path = os.path.join('/mock/chromium/src', 'agents',
'extensions', 'non_existent_extension')
mock_exists.assert_called_with(expected_path)
def test_extension_with_file_path(self):
"""Tests that an error is returned for an extension with a file path."""
data = {
'providers': [{
'config': {
'extensions': ['file://some/extension.py']
}
}]
}
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 1)
self.assertIn(
'contains a file path for an extension. Please use '
'the extension name instead', errors[0])
def test_non_string_path(self):
"""Tests that a non-string path value returns an error."""
data = {
'providers': [{
'config': {
'changes': [{
'apply': 12345
}],
}
}]
}
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 1)
self.assertIn('contains a non-string file reference', errors[0])
def test_non_string_extension(self):
"""Tests that a non-string extension value returns an error."""
data = {'providers': [{'config': {'extensions': [12345]}}]}
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 1)
self.assertIn('contains a non-string extension reference', errors[0])
def test_malformed_structure(self):
"""Tests that the linter doesn't crash on malformed data."""
data = {
'providers': [{
'id': 'test',
'config': 'not a dict'
}],
}
# Should run without raising exceptions and return an error.
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 1)
self.assertIn('"providers" field must have a dict "config" field',
errors[0])
def test_provider_without_config(self):
"""Tests that a provider without a config field is valid."""
data = {
'providers': [{
'id': 'test-provider-without-config',
}]
}
errors = lint_promptfoo_testcases.check_test_case(
data, self.mock_file_path)
self.assertEqual(len(errors), 0)
if __name__ == '__main__':
unittest.main()