22#define TEST_START(name) \
23 std::cout << "\n[TEST] " << name << "...\n"
25#define ASSERT_TRUE(condition, message) \
28 std::cout << " FAILED: " << message << "\n"; \
29 std::cout << " at " << __FILE__ << ":" << __LINE__ << "\n"; \
35#define ASSERT_FALSE(condition, message) \
36 ASSERT_TRUE(!(condition), message)
38#define ASSERT_EQ(expected, actual, message) \
40 if ((expected) != (actual)) { \
41 std::cout << " FAILED: " << message << "\n"; \
42 std::cout << " Expected: \"" << (expected) << "\"\n"; \
43 std::cout << " Actual: \"" << (actual) << "\"\n"; \
44 std::cout << " at " << __FILE__ << ":" << __LINE__ << "\n"; \
52 std::cout << " PASSED\n"; \
62 TEST_START(
"PostgreSQL - Basic Connection String");
70 .
build(backend_type::postgres);
72 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
74 auto conn_str = result.value();
75 ASSERT_TRUE(conn_str.find(
"host=localhost") != std::string::npos,
"Should contain host");
76 ASSERT_TRUE(conn_str.find(
"port=5432") != std::string::npos,
"Should contain port");
77 ASSERT_TRUE(conn_str.find(
"dbname=mydb") != std::string::npos,
"Should contain dbname");
78 ASSERT_TRUE(conn_str.find(
"user=admin") != std::string::npos,
"Should contain user");
79 ASSERT_TRUE(conn_str.find(
"password=secret") != std::string::npos,
"Should contain password");
91 .
build(backend_type::postgres);
93 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
94 ASSERT_TRUE(result.value().find(
"sslmode=require") != std::string::npos,
"Should contain sslmode");
105 .
build(backend_type::postgres);
107 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
108 ASSERT_TRUE(result.value().find(
"sslmode=verify-ca") != std::string::npos,
"Should contain verify-ca");
114 TEST_START(
"PostgreSQL - Connection Timeout");
119 .
build(backend_type::postgres);
121 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
122 ASSERT_TRUE(result.value().find(
"connect_timeout=30") != std::string::npos,
"Should contain timeout");
133 .
build(backend_type::postgres);
135 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
136 ASSERT_TRUE(result.value().find(
"application_name=my_app") != std::string::npos,
"Should contain app name");
146 .
option(
"client_encoding",
"UTF8")
147 .
build(backend_type::postgres);
149 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
150 ASSERT_TRUE(result.value().find(
"client_encoding=UTF8") != std::string::npos,
"Should contain custom option");
159 .
build(backend_type::postgres);
161 ASSERT_TRUE(result.is_ok(),
"Build should succeed even with empty builder");
162 ASSERT_EQ(
"", result.value(),
"Empty builder should produce empty string");
176 .
build(backend_type::sqlite);
178 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
179 ASSERT_EQ(
"mydb.db", result.value(),
"Should return file path");
189 .
build(backend_type::sqlite);
191 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
192 ASSERT_EQ(
":memory:", result.value(),
"Should return :memory:");
201 .
build(backend_type::sqlite);
203 ASSERT_TRUE(result.is_err(),
"Build should fail without database");
209 TEST_START(
"SQLite - In-Memory Overrides File");
214 .
build(backend_type::sqlite);
216 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
217 ASSERT_EQ(
":memory:", result.value(),
"In-memory should override file");
227 TEST_START(
"MongoDB - Basic Connection String");
233 .
build(backend_type::mongodb);
235 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
236 ASSERT_EQ(
"mongodb://localhost:27017/mydb", result.value(),
"Should return MongoDB URI");
249 .
build(backend_type::mongodb);
251 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
252 ASSERT_EQ(
"mongodb://admin:secret@localhost/mydb", result.value(),
"Should include credentials");
262 .
build(backend_type::mongodb);
264 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
265 ASSERT_TRUE(result.value().find(
"localhost") != std::string::npos,
"Should default to localhost");
276 .
build(backend_type::mongodb);
278 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
279 ASSERT_TRUE(result.value().find(
"ssl=true") != std::string::npos,
"Should include SSL option");
289 TEST_START(
"Redis - Basic Connection String");
294 .
build(backend_type::redis);
296 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
297 ASSERT_EQ(
"redis://localhost:6379", result.value(),
"Should return Redis URI");
308 .
build(backend_type::redis);
310 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
311 ASSERT_EQ(
"redis://:secret@localhost", result.value(),
"Should include password");
322 .
build(backend_type::redis);
324 ASSERT_TRUE(result.is_ok(),
"Build should succeed");
325 ASSERT_EQ(
"redis://localhost/0", result.value(),
"Should include database number");
338 builder.
host(
"localhost")
342 auto result1 = builder.
build(backend_type::postgres);
343 ASSERT_TRUE(result1.is_ok(),
"First build should succeed");
344 ASSERT_TRUE(result1.value().find(
"localhost") != std::string::npos,
"Should contain host");
348 auto result2 = builder.
build(backend_type::postgres);
349 ASSERT_TRUE(result2.is_ok(),
"Build after reset should succeed");
350 ASSERT_EQ(
"", result2.value(),
"After reset should be empty");
359 .
host(
"db.example.com")
367 .
option(
"target_session_attrs",
"read-write")
368 .
build(backend_type::postgres);
370 ASSERT_TRUE(result.is_ok(),
"Chained build should succeed");
372 auto conn_str = result.value();
373 ASSERT_TRUE(conn_str.find(
"host=db.example.com") != std::string::npos,
"Should have host");
374 ASSERT_TRUE(conn_str.find(
"sslmode=verify-full") != std::string::npos,
"Should have SSL mode");
375 ASSERT_TRUE(conn_str.find(
"target_session_attrs=read-write") != std::string::npos,
"Should have custom option");
381 TEST_START(
"Builder - Reuse for Multiple Connections");
384 builder.
host(
"localhost")
390 auto pg_result = builder.
build(backend_type::postgres);
391 ASSERT_TRUE(pg_result.is_ok(),
"PostgreSQL build should succeed");
396 auto sqlite_result = builder.
build(backend_type::sqlite);
397 ASSERT_TRUE(sqlite_result.is_ok(),
"SQLite build should succeed");
406 builder1.
host(
"localhost").
port(5432);
411 auto result1 = builder1.
build(backend_type::postgres);
412 auto result2 = builder2.
build(backend_type::postgres);
414 ASSERT_TRUE(result1.is_ok(),
"Original build should succeed");
415 ASSERT_TRUE(result2.is_ok(),
"Copy build should succeed");
418 ASSERT_TRUE(result1.value().find(
"dbname") == std::string::npos,
"Original should not have database");
420 ASSERT_TRUE(result2.value().find(
"dbname=mydb") != std::string::npos,
"Copy should have database");
431 std::cout <<
"========================================\n";
432 std::cout <<
"Connection String Builder Tests\n";
433 std::cout <<
"========================================\n";
469 std::cout <<
"========================================\n";
470 std::cout <<
"Test Summary\n";
471 std::cout <<
"========================================\n";
476 std::cout <<
"\nAll tests passed!\n\n";
479 std::cout <<
"\nSome tests failed!\n\n";
Fluent builder for constructing database connection strings.
connection_string_builder & database(std::string_view db)
Set the database name.
connection_string_builder & user(std::string_view u)
Set the username for authentication.
connection_string_builder & port(uint16_t p)
Set the database port.
connection_string_builder & host(std::string_view h)
Set the database host.
connection_string_builder & ssl_mode(enum ssl_mode mode)
Set the SSL connection mode.
connection_string_builder & application_name(std::string_view name)
Set the application name (for PostgreSQL)
connection_string_builder & reset()
Reset the builder to initial state.
connection_string_builder & option(std::string_view key, std::string_view value)
Add a custom option.
connection_string_builder & in_memory()
Configure SQLite to use in-memory database.
connection_string_builder & password(std::string_view p)
Set the password for authentication.
connection_string_builder & connect_timeout(uint32_t seconds)
Set the connection timeout.
kcenon::common::Result< std::string > build(backend_type type) const
Build the connection string for the specified backend.
Fluent builder for constructing type-safe database connection strings.
#define ASSERT_EQ(expected, actual, message)
bool test_mongodb_default_host()
bool test_sqlite_memory()
bool test_builder_chaining()
bool test_postgres_basic()
bool test_postgres_empty()
bool test_postgres_app_name()
#define ASSERT_TRUE(condition, message)
bool test_postgres_verify_ca()
bool test_postgres_custom_option()
bool test_redis_with_database()
bool test_postgres_timeout()
bool test_sqlite_no_database()
bool test_builder_reuse()
bool test_mongodb_basic()
bool test_redis_with_password()
bool test_builder_reset()
bool test_mongodb_with_auth()
bool test_sqlite_memory_overrides_file()