// IACore-OSS; The Core Library for All IA Open Source Projects // Copyright (C) 2025 IAS (ias@iasoft.dev) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include using namespace IACore; // ----------------------------------------------------------------------------- // Constants // ----------------------------------------------------------------------------- // We use a unique prefix to ensure we don't accidentally mess with real // system variables like PATH or HOME. static const char* TEST_KEY = "IA_TEST_ENV_VAR_12345"; static const char* TEST_VAL = "Hello World"; // ----------------------------------------------------------------------------- // Test Block Definition // ----------------------------------------------------------------------------- IAT_BEGIN_BLOCK(Core, Environment) // ------------------------------------------------------------------------- // 1. Basic Set and Get (The Happy Path) // ------------------------------------------------------------------------- BOOL TestBasicCycle() { // 1. Ensure clean slate Environment::Unset(TEST_KEY); IAT_CHECK_NOT(Environment::Exists(TEST_KEY)); // 2. Set BOOL setRes = Environment::Set(TEST_KEY, TEST_VAL); IAT_CHECK(setRes); IAT_CHECK(Environment::Exists(TEST_KEY)); // 3. Find (Optional) auto opt = Environment::Find(TEST_KEY); IAT_CHECK(opt.has_value()); IAT_CHECK_EQ(*opt, String(TEST_VAL)); // 4. Get (Direct) String val = Environment::Get(TEST_KEY); IAT_CHECK_EQ(val, String(TEST_VAL)); // Cleanup Environment::Unset(TEST_KEY); return TRUE; } // ------------------------------------------------------------------------- // 2. Overwriting Values // ------------------------------------------------------------------------- BOOL TestOverwrite() { Environment::Set(TEST_KEY, "ValueA"); IAT_CHECK_EQ(Environment::Get(TEST_KEY), String("ValueA")); // Overwrite Environment::Set(TEST_KEY, "ValueB"); IAT_CHECK_EQ(Environment::Get(TEST_KEY), String("ValueB")); Environment::Unset(TEST_KEY); return TRUE; } // ------------------------------------------------------------------------- // 3. Unset Logic // ------------------------------------------------------------------------- BOOL TestUnset() { Environment::Set(TEST_KEY, "To Be Deleted"); IAT_CHECK(Environment::Exists(TEST_KEY)); BOOL unsetRes = Environment::Unset(TEST_KEY); IAT_CHECK(unsetRes); // Verify it is actually gone IAT_CHECK_NOT(Environment::Exists(TEST_KEY)); // Find should return nullopt auto opt = Environment::Find(TEST_KEY); IAT_CHECK_NOT(opt.has_value()); return TRUE; } // ------------------------------------------------------------------------- // 4. Default Value Fallbacks // ------------------------------------------------------------------------- BOOL TestDefaults() { const char* ghostKey = "IA_THIS_KEY_DOES_NOT_EXIST"; // Ensure it really doesn't exist Environment::Unset(ghostKey); // Test Get with implicit default ("") String empty = Environment::Get(ghostKey); IAT_CHECK(empty.empty()); // Test Get with explicit default String fallback = Environment::Get(ghostKey, "MyDefault"); IAT_CHECK_EQ(fallback, String("MyDefault")); return TRUE; } // ------------------------------------------------------------------------- // 5. Empty Strings vs Null/Unset // ------------------------------------------------------------------------- // This is a critical edge case. // Does Set(Key, "") create an existing empty variable, or unset it? // Standard POSIX/Windows API behavior is that it EXISTS, but is empty. BOOL TestEmptyValue() { Environment::Set(TEST_KEY, ""); // It should exist IAT_CHECK(Environment::Exists(TEST_KEY)); // It should be retrievable as empty string auto opt = Environment::Find(TEST_KEY); IAT_CHECK(opt.has_value()); IAT_CHECK(opt->empty()); // Cleanup Environment::Unset(TEST_KEY); IAT_CHECK_NOT(Environment::Exists(TEST_KEY)); return TRUE; } // ------------------------------------------------------------------------- // 6. Validation / Bad Input // ------------------------------------------------------------------------- BOOL TestBadInput() { // Setting an empty key should fail gracefully BOOL res = Environment::Set("", "Value"); IAT_CHECK_NOT(res); // Unsetting an empty key should fail BOOL resUnset = Environment::Unset(""); IAT_CHECK_NOT(resUnset); return TRUE; } // ------------------------------------------------------------------------- // Registration // ------------------------------------------------------------------------- IAT_BEGIN_TEST_LIST() IAT_ADD_TEST(TestBasicCycle); IAT_ADD_TEST(TestOverwrite); IAT_ADD_TEST(TestUnset); IAT_ADD_TEST(TestDefaults); IAT_ADD_TEST(TestEmptyValue); IAT_ADD_TEST(TestBadInput); IAT_END_TEST_LIST() IAT_END_BLOCK() int main(int argc, char* argv[]) { UNUSED(argc); UNUSED(argv); // Define runner (StopOnFail=false, Verbose=true) ia::iatest::runner testRunner; // Run the BinaryReader block testRunner.testBlock(); return 0; }