restructure
Some checks failed
CI - Multi-Platform Native / Build iOS (RSSuper) (push) Has been cancelled
CI - Multi-Platform Native / Build macOS (push) Has been cancelled
CI - Multi-Platform Native / Build Android (push) Has been cancelled
CI - Multi-Platform Native / Build Linux (push) Has been cancelled
CI - Multi-Platform Native / Build Summary (push) Has been cancelled
Some checks failed
CI - Multi-Platform Native / Build iOS (RSSuper) (push) Has been cancelled
CI - Multi-Platform Native / Build macOS (push) Has been cancelled
CI - Multi-Platform Native / Build Android (push) Has been cancelled
CI - Multi-Platform Native / Build Linux (push) Has been cancelled
CI - Multi-Platform Native / Build Summary (push) Has been cancelled
This commit is contained in:
423
linux/src/tests/database-tests.vala
Normal file
423
linux/src/tests/database-tests.vala
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* DatabaseTests.vala
|
||||
*
|
||||
* Unit tests for database layer.
|
||||
*/
|
||||
|
||||
public class RSSuper.DatabaseTests {
|
||||
private Database? db;
|
||||
private string test_db_path;
|
||||
|
||||
public void run_subscription_crud() {
|
||||
try {
|
||||
test_db_path = "/tmp/rssuper_test_%d.db".printf((int)new DateTime.now_local().to_unix());
|
||||
db = new Database(test_db_path);
|
||||
} catch (DBError e) {
|
||||
warning("Failed to create test database: %s", e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var store = new SubscriptionStore(db);
|
||||
|
||||
// Create test subscription
|
||||
var subscription = new FeedSubscription.with_values(
|
||||
"sub_1",
|
||||
"https://example.com/feed.xml",
|
||||
"Example Feed",
|
||||
60,
|
||||
"Technology",
|
||||
true,
|
||||
"2024-01-01T00:00:00Z",
|
||||
"2024-01-01T00:00:00Z"
|
||||
);
|
||||
|
||||
// Test add
|
||||
store.add(subscription);
|
||||
var retrieved = store.get_by_id("sub_1");
|
||||
if (retrieved == null) {
|
||||
printerr("FAIL: Expected subscription to exist after add\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Test get
|
||||
if (retrieved.title != "Example Feed") {
|
||||
printerr("FAIL: Expected title 'Example Feed', got '%s'\n", retrieved.title);
|
||||
return;
|
||||
}
|
||||
if (retrieved.url != "https://example.com/feed.xml") {
|
||||
printerr("FAIL: Expected url 'https://example.com/feed.xml', got '%s'\n", retrieved.url);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test update
|
||||
retrieved.title = "Updated Feed";
|
||||
store.update(retrieved);
|
||||
var updated = store.get_by_id("sub_1");
|
||||
if (updated.title != "Updated Feed") {
|
||||
printerr("FAIL: Expected title 'Updated Feed', got '%s'\n", updated.title);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test delete
|
||||
store.remove_subscription("sub_1");
|
||||
var deleted = store.get_by_id("sub_1");
|
||||
if (deleted != null) {
|
||||
printerr("FAIL: Expected subscription to be deleted\n");
|
||||
return;
|
||||
}
|
||||
|
||||
print("PASS: test_subscription_crud\n");
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public void run_subscription_list() {
|
||||
try {
|
||||
test_db_path = "/tmp/rssuper_test_%d.db".printf((int)new DateTime.now_local().to_unix());
|
||||
db = new Database(test_db_path);
|
||||
} catch (DBError e) {
|
||||
warning("Failed to create test database: %s", e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var store = new SubscriptionStore(db);
|
||||
|
||||
// Add multiple subscriptions
|
||||
var sub1 = new FeedSubscription.with_values("sub_1", "https://feed1.com", "Feed 1");
|
||||
var sub2 = new FeedSubscription.with_values("sub_2", "https://feed2.com", "Feed 2");
|
||||
var sub3 = new FeedSubscription.with_values("sub_3", "https://feed3.com", "Feed 3", 60, null, false);
|
||||
|
||||
store.add(sub1);
|
||||
store.add(sub2);
|
||||
store.add(sub3);
|
||||
|
||||
// Test get_all
|
||||
var all = store.get_all();
|
||||
if (all.length != 3) {
|
||||
printerr("FAIL: Expected 3 subscriptions, got %d\n", all.length);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test get_enabled
|
||||
var enabled = store.get_enabled();
|
||||
if (enabled.length != 2) {
|
||||
printerr("FAIL: Expected 2 enabled subscriptions, got %d\n", enabled.length);
|
||||
return;
|
||||
}
|
||||
|
||||
print("PASS: test_subscription_list\n");
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public void run_feed_item_crud() {
|
||||
try {
|
||||
test_db_path = "/tmp/rssuper_test_%d.db".printf((int)new DateTime.now_local().to_unix());
|
||||
db = new Database(test_db_path);
|
||||
} catch (DBError e) {
|
||||
warning("Failed to create test database: %s", e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var sub_store = new SubscriptionStore(db);
|
||||
var item_store = new FeedItemStore(db);
|
||||
|
||||
// Create subscription first
|
||||
var subscription = new FeedSubscription.with_values(
|
||||
"sub_1", "https://example.com/feed.xml", "Example Feed"
|
||||
);
|
||||
sub_store.add(subscription);
|
||||
|
||||
// Create test item
|
||||
var item = new FeedItem.with_values(
|
||||
"item_1",
|
||||
"Test Article",
|
||||
"https://example.com/article",
|
||||
"This is a test description",
|
||||
"Full content of the article",
|
||||
"John Doe",
|
||||
"2024-01-01T12:00:00Z",
|
||||
"2024-01-01T12:00:00Z",
|
||||
{"Technology", "News"},
|
||||
null, null, null, null,
|
||||
"sub_1" // subscription_id (stored as subscription_title in DB)
|
||||
);
|
||||
|
||||
// Test add
|
||||
item_store.add(item);
|
||||
var retrieved = item_store.get_by_id("item_1");
|
||||
if (retrieved == null) {
|
||||
printerr("FAIL: Expected item to exist after add\n");
|
||||
return;
|
||||
}
|
||||
if (retrieved.title != "Test Article") {
|
||||
printerr("FAIL: Expected title 'Test Article', got '%s'\n", retrieved.title);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test get by subscription
|
||||
var items = item_store.get_by_subscription("sub_1");
|
||||
if (items.length != 1) {
|
||||
printerr("FAIL: Expected 1 item, got %d\n", items.length);
|
||||
return;
|
||||
}
|
||||
|
||||
// Test mark as read
|
||||
item_store.mark_as_read("item_1");
|
||||
|
||||
// Test delete
|
||||
item_store.delete("item_1");
|
||||
var deleted = item_store.get_by_id("item_1");
|
||||
if (deleted != null) {
|
||||
printerr("FAIL: Expected item to be deleted\n");
|
||||
return;
|
||||
}
|
||||
|
||||
print("PASS: test_feed_item_crud\n");
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public void run_feed_item_batch() {
|
||||
try {
|
||||
test_db_path = "/tmp/rssuper_test_%d.db".printf((int)new DateTime.now_local().to_unix());
|
||||
db = new Database(test_db_path);
|
||||
} catch (DBError e) {
|
||||
warning("Failed to create test database: %s", e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var sub_store = new SubscriptionStore(db);
|
||||
var item_store = new FeedItemStore(db);
|
||||
|
||||
// Create subscription
|
||||
var subscription = new FeedSubscription.with_values(
|
||||
"sub_1", "https://example.com/feed.xml", "Example Feed"
|
||||
);
|
||||
sub_store.add(subscription);
|
||||
|
||||
// Create multiple items
|
||||
var items = new FeedItem[5];
|
||||
for (var i = 0; i < 5; i++) {
|
||||
items[i] = new FeedItem.with_values(
|
||||
"item_%d".printf(i),
|
||||
"Article %d".printf(i),
|
||||
"https://example.com/article%d".printf(i),
|
||||
"Description %d".printf(i),
|
||||
null,
|
||||
"Author %d".printf(i),
|
||||
"2024-01-%02dT12:00:00Z".printf(i + 1),
|
||||
null,
|
||||
null,
|
||||
null, null, null, null,
|
||||
"sub_1" // subscription_id
|
||||
);
|
||||
}
|
||||
|
||||
// Test batch insert
|
||||
item_store.add_batch(items);
|
||||
|
||||
var all = item_store.get_by_subscription("sub_1");
|
||||
if (all.length != 5) {
|
||||
printerr("FAIL: Expected 5 items, got %d\n", all.length);
|
||||
return;
|
||||
}
|
||||
|
||||
print("PASS: test_feed_item_batch\n");
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public void run_search_history() {
|
||||
try {
|
||||
test_db_path = "/tmp/rssuper_test_%d.db".printf((int)new DateTime.now_local().to_unix());
|
||||
db = new Database(test_db_path);
|
||||
} catch (DBError e) {
|
||||
warning("Failed to create test database: %s", e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var store = new SearchHistoryStore(db);
|
||||
|
||||
// Create test queries
|
||||
var query1 = SearchQuery("test query", 1, 20, null, SearchSortOption.RELEVANCE);
|
||||
var query2 = SearchQuery("another search", 1, 10, null, SearchSortOption.DATE_DESC);
|
||||
|
||||
// Test record
|
||||
store.record_search(query1, 15);
|
||||
store.record_search(query2, 8);
|
||||
|
||||
// Test get_history
|
||||
var history = store.get_history();
|
||||
if (history.length != 2) {
|
||||
printerr("FAIL: Expected 2 history entries, got %d\n", history.length);
|
||||
return;
|
||||
}
|
||||
// Check that both queries are in history (order may vary due to timing)
|
||||
bool found_test_query = false;
|
||||
bool found_another_search = false;
|
||||
foreach (var q in history) {
|
||||
if (q.query == "test query") found_test_query = true;
|
||||
if (q.query == "another search") found_another_search = true;
|
||||
}
|
||||
if (!found_test_query || !found_another_search) {
|
||||
printerr("FAIL: Expected both queries in history\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Test get_recent
|
||||
var recent = store.get_recent();
|
||||
if (recent.length != 2) {
|
||||
printerr("FAIL: Expected 2 recent entries, got %d\n", recent.length);
|
||||
return;
|
||||
}
|
||||
|
||||
print("PASS: test_search_history\n");
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
public void run_fts_search() {
|
||||
try {
|
||||
test_db_path = "/tmp/rssuper_test_%d.db".printf((int)new DateTime.now_local().to_unix());
|
||||
db = new Database(test_db_path);
|
||||
} catch (DBError e) {
|
||||
warning("Failed to create test database: %s", e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var sub_store = new SubscriptionStore(db);
|
||||
var item_store = new FeedItemStore(db);
|
||||
|
||||
// Create subscription
|
||||
var subscription = new FeedSubscription.with_values(
|
||||
"sub_1", "https://example.com/feed.xml", "Example Feed"
|
||||
);
|
||||
sub_store.add(subscription);
|
||||
|
||||
// Add items with searchable content
|
||||
var item1 = new FeedItem.with_values(
|
||||
"item_1",
|
||||
"Swift Programming Guide",
|
||||
"https://example.com/swift",
|
||||
"Learn Swift programming language basics",
|
||||
"A comprehensive guide to Swift",
|
||||
"Apple Developer",
|
||||
"2024-01-01T12:00:00Z",
|
||||
null,
|
||||
null,
|
||||
null, null, null, null,
|
||||
"sub_1" // subscription_id
|
||||
);
|
||||
|
||||
var item2 = new FeedItem.with_values(
|
||||
"item_2",
|
||||
"Python for Data Science",
|
||||
"https://example.com/python",
|
||||
"Data analysis with Python and pandas",
|
||||
"Complete Python data science tutorial",
|
||||
"Data Team",
|
||||
"2024-01-02T12:00:00Z",
|
||||
null,
|
||||
null,
|
||||
null, null, null, null,
|
||||
"sub_1" // subscription_id
|
||||
);
|
||||
|
||||
item_store.add(item1);
|
||||
item_store.add(item2);
|
||||
|
||||
// Test FTS search
|
||||
var results = item_store.search("swift");
|
||||
if (results.length != 1) {
|
||||
printerr("FAIL: Expected 1 result for 'swift', got %d\n", results.length);
|
||||
return;
|
||||
}
|
||||
if (results[0].title != "Swift Programming Guide") {
|
||||
printerr("FAIL: Expected 'Swift Programming Guide', got '%s'\n", results[0].title);
|
||||
return;
|
||||
}
|
||||
|
||||
results = item_store.search("python");
|
||||
if (results.length != 1) {
|
||||
printerr("FAIL: Expected 1 result for 'python', got %d\n", results.length);
|
||||
return;
|
||||
}
|
||||
if (results[0].title != "Python for Data Science") {
|
||||
printerr("FAIL: Expected 'Python for Data Science', got '%s'\n", results[0].title);
|
||||
return;
|
||||
}
|
||||
|
||||
print("PASS: test_fts_search\n");
|
||||
} finally {
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
if (db != null) {
|
||||
db.close();
|
||||
db = null;
|
||||
}
|
||||
|
||||
// Clean up test database
|
||||
if (test_db_path != null && test_db_path.length > 0) {
|
||||
var file = File.new_for_path(test_db_path);
|
||||
if (file.query_exists()) {
|
||||
try {
|
||||
file.delete();
|
||||
} catch (Error e) {
|
||||
warning("Failed to delete test database: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up WAL file
|
||||
var wal_file = File.new_for_path(test_db_path + "-wal");
|
||||
if (wal_file.query_exists()) {
|
||||
try {
|
||||
wal_file.delete();
|
||||
} catch (Error e) {
|
||||
warning("Failed to delete WAL file: %s", e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int main(string[] args) {
|
||||
print("Running database tests...\n");
|
||||
|
||||
var tests = new DatabaseTests();
|
||||
|
||||
print("\n=== Running subscription CRUD tests ===");
|
||||
tests.run_subscription_crud();
|
||||
|
||||
print("\n=== Running subscription list tests ===");
|
||||
tests.run_subscription_list();
|
||||
|
||||
print("\n=== Running feed item CRUD tests ===");
|
||||
tests.run_feed_item_crud();
|
||||
|
||||
print("\n=== Running feed item batch tests ===");
|
||||
tests.run_feed_item_batch();
|
||||
|
||||
print("\n=== Running search history tests ===");
|
||||
tests.run_search_history();
|
||||
|
||||
print("\n=== Running FTS search tests ===");
|
||||
tests.run_fts_search();
|
||||
|
||||
print("\nAll tests completed!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user