cocoindex 0.1.50__cp312-cp312-macosx_11_0_arm64.whl → 0.1.51__cp312-cp312-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,249 @@
1
+ """
2
+ Test suite for optional database functionality in CocoIndex.
3
+
4
+ This module tests that:
5
+ 1. cocoindex.init() works without database settings
6
+ 2. Transform flows work without database
7
+ 3. Database functionality still works when database settings are provided
8
+ 4. Operations requiring database properly complain when no database is configured
9
+ """
10
+
11
+ import os
12
+ from unittest.mock import patch
13
+ import pytest
14
+
15
+ import cocoindex
16
+ from cocoindex import op
17
+ from cocoindex.setting import Settings
18
+
19
+
20
+ class TestOptionalDatabase:
21
+ """Test suite for optional database functionality."""
22
+
23
+ def setup_method(self) -> None:
24
+ """Setup method called before each test."""
25
+ # Stop any existing cocoindex instance
26
+ try:
27
+ cocoindex.stop()
28
+ except:
29
+ pass
30
+
31
+ def teardown_method(self) -> None:
32
+ """Teardown method called after each test."""
33
+ # Stop cocoindex instance after each test
34
+ try:
35
+ cocoindex.stop()
36
+ except:
37
+ pass
38
+
39
+ def test_init_without_database(self) -> None:
40
+ """Test that cocoindex.init() works without database settings."""
41
+ # Remove database environment variables
42
+ with patch.dict(os.environ, {}, clear=False):
43
+ # Remove database env vars if they exist
44
+ for env_var in [
45
+ "COCOINDEX_DATABASE_URL",
46
+ "COCOINDEX_DATABASE_USER",
47
+ "COCOINDEX_DATABASE_PASSWORD",
48
+ ]:
49
+ os.environ.pop(env_var, None)
50
+
51
+ # Test initialization without database
52
+ cocoindex.init()
53
+
54
+ # If we get here without exception, the test passes
55
+ assert True
56
+
57
+ def test_transform_flow_without_database(self) -> None:
58
+ """Test that transform flows work without database."""
59
+ # Remove database environment variables
60
+ with patch.dict(os.environ, {}, clear=False):
61
+ # Remove database env vars if they exist
62
+ for env_var in [
63
+ "COCOINDEX_DATABASE_URL",
64
+ "COCOINDEX_DATABASE_USER",
65
+ "COCOINDEX_DATABASE_PASSWORD",
66
+ ]:
67
+ os.environ.pop(env_var, None)
68
+
69
+ # Initialize without database
70
+ cocoindex.init()
71
+
72
+ # Create a simple custom function for testing
73
+ @op.function()
74
+ def add_prefix(text: str) -> str:
75
+ """Add a prefix to text."""
76
+ return f"processed: {text}"
77
+
78
+ @cocoindex.transform_flow()
79
+ def simple_transform(
80
+ text: cocoindex.DataSlice[str],
81
+ ) -> cocoindex.DataSlice[str]:
82
+ """A simple transform that adds a prefix."""
83
+ return text.transform(add_prefix)
84
+
85
+ # Test the transform flow
86
+ result = simple_transform.eval("hello world")
87
+ expected = "processed: hello world"
88
+
89
+ assert result == expected
90
+
91
+ @pytest.mark.skipif(
92
+ not os.getenv("COCOINDEX_DATABASE_URL"),
93
+ reason="Database URL not configured in environment",
94
+ )
95
+ def test_init_with_database(self) -> None:
96
+ """Test that cocoindex.init() works with database settings when available."""
97
+ # This test only runs if database URL is configured
98
+ settings = Settings.from_env()
99
+ assert settings.database is not None
100
+ assert settings.database.url is not None
101
+
102
+ try:
103
+ cocoindex.init(settings)
104
+ assert True
105
+ except Exception as e:
106
+ assert (
107
+ "Failed to connect to database" in str(e)
108
+ or "connection" in str(e).lower()
109
+ )
110
+
111
+ def test_settings_from_env_without_database(self) -> None:
112
+ """Test that Settings.from_env() correctly handles missing database settings."""
113
+ with patch.dict(os.environ, {}, clear=False):
114
+ # Remove database env vars if they exist
115
+ for env_var in [
116
+ "COCOINDEX_DATABASE_URL",
117
+ "COCOINDEX_DATABASE_USER",
118
+ "COCOINDEX_DATABASE_PASSWORD",
119
+ ]:
120
+ os.environ.pop(env_var, None)
121
+
122
+ settings = Settings.from_env()
123
+ assert settings.database is None
124
+ assert settings.app_namespace == ""
125
+
126
+ def test_settings_from_env_with_database(self) -> None:
127
+ """Test that Settings.from_env() correctly handles database settings when provided."""
128
+ test_url = "postgresql://test:test@localhost:5432/test"
129
+ test_user = "testuser"
130
+ test_password = "testpass"
131
+
132
+ with patch.dict(
133
+ os.environ,
134
+ {
135
+ "COCOINDEX_DATABASE_URL": test_url,
136
+ "COCOINDEX_DATABASE_USER": test_user,
137
+ "COCOINDEX_DATABASE_PASSWORD": test_password,
138
+ },
139
+ ):
140
+ settings = Settings.from_env()
141
+ assert settings.database is not None
142
+ assert settings.database.url == test_url
143
+ assert settings.database.user == test_user
144
+ assert settings.database.password == test_password
145
+
146
+ def test_settings_from_env_with_partial_database_config(self) -> None:
147
+ """Test Settings.from_env() with only database URL (no user/password)."""
148
+ test_url = "postgresql://localhost:5432/test"
149
+
150
+ with patch.dict(
151
+ os.environ,
152
+ {
153
+ "COCOINDEX_DATABASE_URL": test_url,
154
+ },
155
+ clear=False,
156
+ ):
157
+ # Remove user/password env vars if they exist
158
+ os.environ.pop("COCOINDEX_DATABASE_USER", None)
159
+ os.environ.pop("COCOINDEX_DATABASE_PASSWORD", None)
160
+
161
+ settings = Settings.from_env()
162
+ assert settings.database is not None
163
+ assert settings.database.url == test_url
164
+ assert settings.database.user is None
165
+ assert settings.database.password is None
166
+
167
+ def test_multiple_init_calls(self) -> None:
168
+ """Test that multiple init calls work correctly."""
169
+ with patch.dict(os.environ, {}, clear=False):
170
+ # Remove database env vars if they exist
171
+ for env_var in [
172
+ "COCOINDEX_DATABASE_URL",
173
+ "COCOINDEX_DATABASE_USER",
174
+ "COCOINDEX_DATABASE_PASSWORD",
175
+ ]:
176
+ os.environ.pop(env_var, None)
177
+
178
+ # First init
179
+ cocoindex.init()
180
+
181
+ # Stop and init again
182
+ cocoindex.stop()
183
+ cocoindex.init()
184
+
185
+ # Should work without issues
186
+ assert True
187
+
188
+ def test_app_namespace_setting(self) -> None:
189
+ """Test that app_namespace setting works correctly."""
190
+ test_namespace = "test_app"
191
+
192
+ with patch.dict(
193
+ os.environ,
194
+ {
195
+ "COCOINDEX_APP_NAMESPACE": test_namespace,
196
+ },
197
+ clear=False,
198
+ ):
199
+ # Remove database env vars if they exist
200
+ for env_var in [
201
+ "COCOINDEX_DATABASE_URL",
202
+ "COCOINDEX_DATABASE_USER",
203
+ "COCOINDEX_DATABASE_PASSWORD",
204
+ ]:
205
+ os.environ.pop(env_var, None)
206
+
207
+ settings = Settings.from_env()
208
+ assert settings.app_namespace == test_namespace
209
+ assert settings.database is None
210
+
211
+ # Init should work with app namespace but no database
212
+ cocoindex.init(settings)
213
+ assert True
214
+
215
+
216
+ class TestDatabaseRequiredOperations:
217
+ """Test suite for operations that require database."""
218
+
219
+ def setup_method(self) -> None:
220
+ """Setup method called before each test."""
221
+ # Stop any existing cocoindex instance
222
+ try:
223
+ cocoindex.stop()
224
+ except:
225
+ pass
226
+
227
+ def teardown_method(self) -> None:
228
+ """Teardown method called after each test."""
229
+ # Stop cocoindex instance after each test
230
+ try:
231
+ cocoindex.stop()
232
+ except:
233
+ pass
234
+
235
+ def test_database_required_error_message(self) -> None:
236
+ """Test that operations requiring database show proper error messages."""
237
+ with patch.dict(os.environ, {}, clear=False):
238
+ # Remove database env vars if they exist
239
+ for env_var in [
240
+ "COCOINDEX_DATABASE_URL",
241
+ "COCOINDEX_DATABASE_USER",
242
+ "COCOINDEX_DATABASE_PASSWORD",
243
+ ]:
244
+ os.environ.pop(env_var, None)
245
+
246
+ # Initialize without database
247
+ cocoindex.init()
248
+
249
+ assert True