// IACore-OSS; The Core Library for All IA Open Source Projects // Copyright (C) 2026 IAS (ias@iasoft.dev) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include using namespace IACore; // ----------------------------------------------------------------------------- // Constants // ----------------------------------------------------------------------------- static constexpr const char *TEST_KEY = "IA_TEST_ENV_VAR_12345"; static constexpr const char *TEST_VAL = "Hello World"; // ----------------------------------------------------------------------------- // Test Block Definition // ----------------------------------------------------------------------------- IAT_BEGIN_BLOCK(Core, Environment) // ------------------------------------------------------------------------- // 1. Basic Set and Get (The Happy Path) // ------------------------------------------------------------------------- auto test_basic_cycle() -> bool { // 1. Ensure clean slate (void)Environment::unset(TEST_KEY); IAT_CHECK_NOT(Environment::exists(TEST_KEY)); // 2. Set const auto set_res = Environment::set(TEST_KEY, TEST_VAL); IAT_CHECK(set_res.has_value()); IAT_CHECK(Environment::exists(TEST_KEY)); // 3. Find (Optional) const auto opt = Environment::find(TEST_KEY); IAT_CHECK(opt.has_value()); IAT_CHECK_EQ(*opt, String(TEST_VAL)); // 4. Get (Direct) const String val = Environment::get(TEST_KEY); IAT_CHECK_EQ(val, String(TEST_VAL)); // Cleanup (void)Environment::unset(TEST_KEY); return true; } // ------------------------------------------------------------------------- // 2. Overwriting Values // ------------------------------------------------------------------------- auto test_overwrite() -> bool { (void)Environment::set(TEST_KEY, "ValueA"); IAT_CHECK_EQ(Environment::get(TEST_KEY), String("ValueA")); // Overwrite (void)Environment::set(TEST_KEY, "ValueB"); IAT_CHECK_EQ(Environment::get(TEST_KEY), String("ValueB")); (void)Environment::unset(TEST_KEY); return true; } // ------------------------------------------------------------------------- // 3. Unset Logic // ------------------------------------------------------------------------- auto test_unset() -> bool { (void)Environment::set(TEST_KEY, "To Be Deleted"); IAT_CHECK(Environment::exists(TEST_KEY)); const auto unset_res = Environment::unset(TEST_KEY); IAT_CHECK(unset_res.has_value()); // Verify it is actually gone IAT_CHECK_NOT(Environment::exists(TEST_KEY)); // Find should return nullopt const auto opt = Environment::find(TEST_KEY); IAT_CHECK_NOT(opt.has_value()); return true; } // ------------------------------------------------------------------------- // 4. Default Value Fallbacks // ------------------------------------------------------------------------- auto test_defaults() -> bool { const char *ghost_key = "IA_THIS_KEY_DOES_NOT_EXIST"; // Ensure it really doesn't exist (void)Environment::unset(ghost_key); // Test Get with implicit default ("") const String empty = Environment::get(ghost_key); IAT_CHECK(empty.empty()); // Test Get with explicit default const String fallback = Environment::get(ghost_key, "MyDefault"); IAT_CHECK_EQ(fallback, String("MyDefault")); return true; } // ------------------------------------------------------------------------- // 5. Empty Strings vs Null/Unset // ------------------------------------------------------------------------- // Does Set(Key, "") create an existing empty variable, or unset it? // Standard POSIX/Windows API behavior is that it EXISTS, but is empty. auto test_empty_value() -> bool { (void)Environment::set(TEST_KEY, ""); #if IA_PLATFORM_WINDOWS // Windows behavior: Setting to empty string removes the variable // IAT_CHECK_NOT(Environment::exists(TEST_KEY)); // auto opt = Environment::find(TEST_KEY); // IAT_CHECK_NOT(opt.has_value()); #else // POSIX behavior: Variable exists but is empty IAT_CHECK(Environment::exists(TEST_KEY)); const auto opt = Environment::find(TEST_KEY); IAT_CHECK(opt.has_value()); IAT_CHECK(opt->empty()); #endif // Cleanup (void)Environment::unset(TEST_KEY); IAT_CHECK_NOT(Environment::exists(TEST_KEY)); return true; } // ------------------------------------------------------------------------- // 6. Validation / Bad Input // ------------------------------------------------------------------------- auto test_bad_input() -> bool { // Setting an empty key should fail gracefully const auto res = Environment::set("", "Value"); IAT_CHECK_NOT(res.has_value()); // Unsetting an empty key should fail const auto res_unset = Environment::unset(""); IAT_CHECK_NOT(res_unset.has_value()); return true; } // ------------------------------------------------------------------------- // Registration // ------------------------------------------------------------------------- IAT_BEGIN_TEST_LIST() IAT_ADD_TEST(test_basic_cycle); IAT_ADD_TEST(test_overwrite); IAT_ADD_TEST(test_unset); IAT_ADD_TEST(test_defaults); IAT_ADD_TEST(test_empty_value); IAT_ADD_TEST(test_bad_input); IAT_END_TEST_LIST() IAT_END_BLOCK() IAT_REGISTER_ENTRY(Core, Environment)