1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
"""
Tests for flexible style loading from citeproc-py-styles package
"""
import os
import sys
import tempfile
import unittest
from unittest.mock import patch, MagicMock
from citeproc import CitationStylesStyle, STYLES_PATH
class TestStyleLoading(unittest.TestCase):
"""Test suite for flexible style loading"""
def test_bundled_style_loads(self):
"""Test that bundled harvard1 style loads correctly"""
style = CitationStylesStyle('harvard1', validate=False)
self.assertIsNotNone(style)
def test_full_path_style_loads(self):
"""Test that a style specified with full path loads correctly"""
harvard_path = os.path.join(STYLES_PATH, 'harvard1.csl')
style = CitationStylesStyle(harvard_path, validate=False)
self.assertIsNotNone(style)
def test_nonexistent_style_without_citeproc_py_styles(self):
"""Test error message when style not found and citeproc-py-styles not installed"""
with patch('citeproc.frontend.os.path.exists') as mock_exists:
# Make sure the style doesn't exist as a file or bundled
mock_exists.side_effect = lambda path: False
# Mock the import to fail
with patch.dict('sys.modules', {'citeproc_styles': None}):
with self.assertRaises(ValueError) as context:
CitationStylesStyle('nonexistent-style', validate=False)
error_msg = str(context.exception)
self.assertIn('nonexistent-style', error_msg)
self.assertIn('not found in bundled styles', error_msg)
self.assertIn('pip install citeproc-py-styles', error_msg)
def test_style_from_citeproc_py_styles(self):
"""Test that styles load from citeproc-py-styles when available"""
# Create a mock module
mock_module = MagicMock()
mock_module.get_style_filepath = MagicMock(return_value='/mock/path/to/apa.csl')
with patch('citeproc.frontend.os.path.exists') as mock_exists:
# First call checks if 'apa' exists as path (False)
# Second call checks bundled path (False)
mock_exists.side_effect = [False, False]
with patch.dict('sys.modules', {'citeproc_styles': mock_module}):
# Mock the parent class __init__ to set root properly
def mock_init(self, path, validate=False):
# Create a mock root object
self.root = MagicMock()
self.root.get.return_value = 'en-US'
self.root.set_locale_list = MagicMock()
# Store the path for verification
self._test_path = path
with patch('citeproc.frontend.CitationStylesXML.__init__', mock_init):
style = CitationStylesStyle('apa', validate=False)
# Verify get_style_filepath was called with correct argument
mock_module.get_style_filepath.assert_called_once_with('apa')
# Verify parent init was called with the path from citeproc-py-styles
self.assertEqual(style._test_path, '/mock/path/to/apa.csl')
def test_style_not_in_citeproc_py_styles(self):
"""Test error when style not found even in citeproc-py-styles"""
# Create a mock module that raises KeyError
mock_module = MagicMock()
mock_module.get_style_filepath = MagicMock(side_effect=KeyError('Style not found'))
with patch('citeproc.frontend.os.path.exists') as mock_exists:
# Style doesn't exist as file or bundled
mock_exists.return_value = False
with patch.dict('sys.modules', {'citeproc_styles': mock_module}):
with self.assertRaises(ValueError) as context:
CitationStylesStyle('unknown-style', validate=False)
error_msg = str(context.exception)
self.assertIn('unknown-style', error_msg)
self.assertIn('not found in bundled styles', error_msg)
self.assertIn('or in citeproc-py-styles package', error_msg)
def test_style_file_not_found_in_citeproc_py_styles(self):
"""Test error when citeproc-py-styles returns path but file doesn't exist"""
# Create a mock module that raises FileNotFoundError
mock_module = MagicMock()
mock_module.get_style_filepath = MagicMock(side_effect=FileNotFoundError('File not found'))
with patch('citeproc.frontend.os.path.exists') as mock_exists:
# Style doesn't exist as file or bundled
mock_exists.return_value = False
with patch.dict('sys.modules', {'citeproc_styles': mock_module}):
with self.assertRaises(ValueError) as context:
CitationStylesStyle('missing-style', validate=False)
error_msg = str(context.exception)
self.assertIn('missing-style', error_msg)
self.assertIn('not found in bundled styles', error_msg)
self.assertIn('or in citeproc-py-styles package', error_msg)
def test_citeproc_py_styles_load(self):
"""Test loading a real style from citeproc-py-styles if installed"""
try:
import citeproc_styles
except ImportError:
self.skipTest("citeproc-py-styles (provides citeproc_styles package) not installed")
from citeproc_styles import get_style_filepath
# Attempt to load a known style from citeproc-py-styles
style_name = 'chicago-author-date'
style_path = get_style_filepath(style_name)
style = CitationStylesStyle(style_name, validate=False)
self.assertIsNotNone(style)
self.assertTrue(hasattr(style, 'root'))
# And loading with the full path should also work
style = CitationStylesStyle(style_path, validate=False)
self.assertIsNotNone(style)
self.assertTrue(hasattr(style, 'root'))
|