11"""Tests for SqliteCacheRequestsDocumentLoader and HTTP cache behavior."""
22
33import json
4+ import sqlite3
45import threading
56from http .server import BaseHTTPRequestHandler , HTTPServer
67from pathlib import Path
@@ -23,9 +24,11 @@ class _ContextHandler(BaseHTTPRequestHandler):
2324
2425 def do_GET (self ):
2526 type (self ).request_count += 1
26- body = json .dumps ({
27- '@context' : {'name' : 'http://example.org/name' },
28- }).encode ()
27+ body = json .dumps (
28+ {
29+ '@context' : {'name' : 'http://example.org/name' },
30+ }
31+ ).encode ()
2932 self .send_response (200 )
3033 self .send_header ('Content-Type' , 'application/ld+json' )
3134 self .send_header ('Cache-Control' , 'max-age=3600' )
@@ -52,33 +55,64 @@ def context_url():
5255def test_requests_document_loader_accepts_custom_session ():
5356 """RequestsDocumentLoader accepts a CachedSession via session=."""
5457 loader = RequestsDocumentLoader (
55- session = CachedSession (backend = 'memory' , cache_control = True ))
58+ session = CachedSession (backend = 'memory' , cache_control = True )
59+ )
5660 assert isinstance (loader , DocumentLoader )
5761 assert callable (loader )
5862 loader .session .close ()
5963
6064
61- def test_sqlite_cache_requests_document_loader_is_document_loader ():
65+ def test_sqlite_cache_requests_document_loader_is_document_loader (tmp_path ):
6266 """Sqlite loader is a DocumentLoader composing RequestsDocumentLoader."""
63- loader = SqliteCacheRequestsDocumentLoader ()
67+ loader = SqliteCacheRequestsDocumentLoader (
68+ sqlite_file_path = tmp_path / 'contexts.sqlite' ,
69+ )
6470 assert isinstance (loader , DocumentLoader )
65- assert isinstance (loader ._loader , RequestsDocumentLoader )
6671 assert callable (loader )
72+ assert isinstance (loader .session , CachedSession )
73+ assert isinstance (loader ._loader , RequestsDocumentLoader )
74+ loader .session .close ()
75+
76+
77+ def test_sqlite_cache_file_is_not_created_on_init (tmp_path ):
78+ """Constructing the loader touches neither the cache file nor its parent."""
79+ cache_path = tmp_path / 'cache' / 'contexts.sqlite'
80+ SqliteCacheRequestsDocumentLoader (sqlite_file_path = cache_path )
81+ assert not cache_path .exists ()
82+ assert not cache_path .parent .exists ()
83+
84+
85+ def test_sqlite_cache_file_is_created_on_first_load (context_url , tmp_path ):
86+ """The cache file appears once a document is actually loaded."""
87+ cache_path = tmp_path / 'contexts.sqlite'
88+ loader = SqliteCacheRequestsDocumentLoader (sqlite_file_path = cache_path )
89+ loader (context_url )
90+ assert cache_path .exists ()
6791 loader .session .close ()
6892
6993
94+ def test_unusable_sqlite_cache_path_raises_on_first_load (context_url , tmp_path ):
95+ """An unopenable cache path fails the load instead of silently degrading."""
96+ cache_path = tmp_path / 'contexts.sqlite'
97+ cache_path .mkdir ()
98+ loader = SqliteCacheRequestsDocumentLoader (sqlite_file_path = cache_path )
99+ with pytest .raises (sqlite3 .Error ):
100+ loader (context_url )
101+
102+
70103def test_sqlite_cache_requests_document_loader_rejects_relative_sqlite_file_path ():
71104 """Relative sqlite_file_path is rejected."""
72105 with pytest .raises (ValueError , match = 'absolute path' ):
73- SqliteCacheRequestsDocumentLoader (
74- sqlite_file_path = Path ('relative.sqlite' ))
106+ SqliteCacheRequestsDocumentLoader (sqlite_file_path = Path ('relative.sqlite' ))
75107
76108
77109def test_sqlite_cache_file_path_is_resolved (tmp_path ):
78110 """Absolute sqlite_file_path is normalized to a full path."""
79111 sqlite_file_path = tmp_path / 'cache' / '..' / 'contexts.sqlite'
80- assert _resolve_sqlite_file_path (sqlite_file_path ) == (
81- tmp_path / 'contexts.sqlite' ).resolve ()
112+ assert (
113+ _resolve_sqlite_file_path (sqlite_file_path )
114+ == (tmp_path / 'contexts.sqlite' ).resolve ()
115+ )
82116
83117
84118def test_http_cache_headers_serve_from_cache_with_cache_control (context_url ):
@@ -88,7 +122,8 @@ def test_http_cache_headers_serve_from_cache_with_cache_control(context_url):
88122 'test_memory_cache_control' ,
89123 backend = 'memory' ,
90124 cache_control = True ,
91- ))
125+ )
126+ )
92127 loader (context_url )
93128 loader (context_url )
94129 assert _ContextHandler .request_count == 1
@@ -103,7 +138,8 @@ def test_http_cache_headers_without_cache_control_hits_server_twice(context_url)
103138 backend = 'memory' ,
104139 cache_control = False ,
105140 expire_after = 0 ,
106- ))
141+ )
142+ )
107143 loader (context_url )
108144 loader (context_url )
109145 assert _ContextHandler .request_count == 2
0 commit comments