/** * test_simple_pipeline.c - Simplified integration tests for GlaMaC pipeline * * Copyright (C) 2025 https://optics-design.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. */ #include "../test_framework.h" #include "../../include/glass_data.h" #include "../../include/glamac_view.h" #include "../../include/glautils/fgla.h" // Test glass data loading and basic operations int test_glass_data_operations() { TEST_START("Glass Data Operations"); // Initialize glass data system initialize_glass_data(); // Try to load JSON data b32 json_loaded = load_glasses_from_json((const byte*)"tests/data/test_glasses.json", NULL); if (json_loaded) { // Verify we have catalogs u32 catalog_count = get_catalog_count(); TEST_ASSERT(catalog_count > 0, "Should have loaded catalogs"); // Test each catalog for (u32 i = 0; i < catalog_count; i++) { set_current_catalog(i); const char* catalog_name = get_catalog_name(i); TEST_ASSERT_NOT_NULL(catalog_name, "Each catalog should have a name"); u32 glass_count = get_glass_count(); TEST_ASSERT(glass_count > 0, "Each catalog should have glasses"); // Test first glass in catalog if (glass_count > 0) { const Glass* glass = get_glass(0); TEST_ASSERT_NOT_NULL(glass, "Should be able to get first glass"); // Validate glass data TEST_ASSERT(glass->abbeNumber > 10.0f && glass->abbeNumber < 100.0f, "Abbe number should be in reasonable range"); TEST_ASSERT(glass->refractiveIndex > 1.0f && glass->refractiveIndex < 4.0f, "Refractive index should be in reasonable range"); const byte* name = get_glass_name(0); TEST_ASSERT_NOT_NULL(name, "Glass should have a name"); TEST_ASSERT(strlen((const char*)name) > 0, "Glass name should not be empty"); } } } else { printf(YELLOW " Info: JSON test data not available - testing with default data" RESET "\n"); // Test with default data u32 glass_count = get_glass_count(); TEST_ASSERT(glass_count > 0, "Should have default glasses"); } cleanup_glass_data(); TEST_END(); } // Test view system integration int test_view_integration() { TEST_START("View System Integration"); // Initialize systems initialize_glass_data(); ViewState view; init_view_state(&view, 1024, 768); // Load test data if available load_glasses_from_json((const byte*)"tests/data/test_glasses.json", NULL); // Refresh view with data refresh_view_data_range(&view); // After refreshing, we should have valid ranges TEST_ASSERT(view.minAbbe < view.maxAbbe, "Should have valid Abbe range"); TEST_ASSERT(view.minRI < view.maxRI, "Should have valid RI range"); // Test coordinate transformations with actual glass data u32 glass_count = get_glass_count(); if (glass_count > 0) { const Glass* glass = get_glass(0); i32 screenX, screenY; data_to_screen_coords(glass->abbeNumber, glass->refractiveIndex, &view, &screenX, &screenY); // Screen coordinates should be reasonable TEST_ASSERT(screenX >= -200 && screenX <= view.windowWidth + 200, "Screen X should be near window bounds"); TEST_ASSERT(screenY >= -200 && screenY <= view.windowHeight + 200, "Screen Y should be near window bounds"); // Test inverse transformation f32 recovered_abbe, recovered_ri; screen_to_data_coords(screenX, screenY, &view, &recovered_abbe, &recovered_ri); TEST_ASSERT_FLOAT_EQ(glass->abbeNumber, recovered_abbe, 1.0f, "Should approximately recover original Abbe number"); TEST_ASSERT_FLOAT_EQ(glass->refractiveIndex, recovered_ri, 0.01f, "Should approximately recover original refractive index"); } cleanup_glass_data(); TEST_END(); } // Test FGLA functionality with real search patterns int test_fgla_functionality() { TEST_START("FGLA Functionality"); // Test glass code pattern matching with realistic codes TEST_ASSERT(fgla_matches_glass_code_pattern_safe("517642", "517642"), "Should match exact glass code"); TEST_ASSERT(fgla_matches_glass_code_pattern_safe("517642123", "517642"), "Should match first 6 digits of longer code"); TEST_ASSERT(fgla_matches_glass_code_pattern_safe("517642", "51x64x"), "Should match wildcard pattern"); // Test realistic search terms TEST_ASSERT(fgla_validate_search_term("N-BK7"), "N-BK7 should be valid search term"); TEST_ASSERT(fgla_validate_search_term("SF10"), "SF10 should be valid search term"); TEST_ASSERT(fgla_validate_search_term("517642"), "517642 should be valid search term"); TEST_ASSERT(fgla_validate_search_term("51x64x"), "51x64x should be valid search term"); // Test substring matching with realistic glass names TEST_ASSERT(fgla_contains_substring_safe("N-BK7", "BK"), "Should find BK in N-BK7"); TEST_ASSERT(fgla_contains_substring_safe("SF10", "sf"), "Should find sf in SF10 (case insensitive)"); TEST_ASSERT(fgla_contains_substring_safe("FCD1", "fcd"), "Should find fcd in FCD1 (case insensitive)"); // Test catalog matching with real manufacturers const char* real_catalogs[] = {"SCHOTT", "HOYA", "CDGM", "Ohara"}; TEST_ASSERT(fgla_matches_catalog("SCHOTT", real_catalogs, 4), "Should match SCHOTT catalog"); TEST_ASSERT(fgla_matches_catalog("hoya", real_catalogs, 4), "Should match HOYA catalog (case insensitive)"); TEST_ASSERT(!fgla_matches_catalog("UNKNOWN", real_catalogs, 4), "Should not match unknown manufacturer"); TEST_END(); } // Test error handling across systems int test_error_handling() { TEST_START("Error Handling"); // Test glass data error handling b32 result = load_glasses_from_json((const byte*)"nonexistent.json", NULL); TEST_ASSERT(!result, "Should fail gracefully with non-existent file"); result = load_glasses_from_json(NULL, NULL); TEST_ASSERT(!result, "Should fail gracefully with NULL path"); // Test view system with edge case values ViewState view; init_view_state(&view, 1, 1); // Very small dimensions TEST_ASSERT(view.windowWidth > 0, "Should handle small width"); TEST_ASSERT(view.windowHeight > 0, "Should handle small height"); // Test FGLA with invalid inputs TEST_ASSERT(!fgla_validate_search_term(NULL), "Should reject NULL search term"); TEST_ASSERT(!fgla_validate_search_term(""), "Should reject empty search term"); TEST_ASSERT(!fgla_is_glass_code_pattern(NULL), "Should reject NULL glass code pattern"); TEST_END(); } // Test memory management int test_memory_management() { TEST_START("Memory Management"); // Test multiple initialize/cleanup cycles for (int i = 0; i < 3; i++) { initialize_glass_data(); // Load data if available load_glasses_from_json((const byte*)"tests/data/test_glasses.json", NULL); // Use the data u32 count = get_glass_count(); if (count > 0) { const Glass* glass = get_glass(0); (void)glass; // Suppress unused variable warning } // Cleanup cleanup_glass_data(); } // After all cycles, we should be able to initialize again initialize_glass_data(); u32 final_count = get_glass_count(); TEST_ASSERT(final_count < 1000000, "Should have reasonable glass count after cleanup cycles"); cleanup_glass_data(); TEST_END(); } // Main integration test runner int main() { printf(BLUE "=== GlaMaC Integration Tests (Simplified) ===" RESET "\n\n"); RUN_TEST(test_glass_data_operations); RUN_TEST(test_view_integration); RUN_TEST(test_fgla_functionality); RUN_TEST(test_error_handling); RUN_TEST(test_memory_management); TEST_SUMMARY(); }