/****************************************************************************** __ ____ __ / / ___ ____ _/ __/_____________ _/ /__ / / / _ \/ __ `/ /_/ ___/ ___/ __ `/ / _ \ / /___/ __/ /_/ / __(__ ) /__/ /_/ / / __/ /_____/\___/\__,_/_/ /____/\___/\__,_/_/\___/ (C)opyright 2026, Leafscale, LLC - https://www.leafscale.com Project: repoman Filename: tests/test_config_merge.reef Authors: Chris Tusa License: Description: Tests: project + override merge logic ******************************************************************************/ import config import test.framework import sys.env fn make_defaults(): config.Defaults return config.Defaults { repos_root: "/home/u/repos", backup_root: "/nfs/repos", logdir: "/home/u/.local/state/repoman", incus_project: "repoman", default_image: "images:ubuntu/26.04/cloud", profiles: ["default", "claude-share"] } end make_defaults fn empty_override(): config.Override return config.Override { image: "", profiles: new [string](0), has_profiles: false, mounts: new [config.Mount](0), env_keys: new [string](0), env_values: new [string](0) } end empty_override proc main() let runner = new framework.TestRunner() // Pin HOME so paths.expand_home is deterministic across environments. env.set_env("HOME", "/home/test") let d = make_defaults() // 1. flag wins over override and defaults mut ov1: config.Override = empty_override() ov1.image = "images:debian/12/cloud" let e1 = config.merge_with_defaults("isurus", "isurus-project", "images:custom/x", ov1, d) runner.assert_eq_string(e1.image, "images:custom/x", "flag wins") runner.assert_eq_string(e1.repo_path, "/home/u/repos/isurus-project", "repo_path computed") // 2. override.image wins over defaults when no flag let e2 = config.merge_with_defaults("isurus", "isurus-project", "", ov1, d) runner.assert_eq_string(e2.image, "images:debian/12/cloud", "override.image wins") // 3. defaults when no flag, no override.image let e3 = config.merge_with_defaults("isurus", "isurus-project", "", empty_override(), d) runner.assert_eq_string(e3.image, "images:ubuntu/26.04/cloud", "defaults.image wins") // 4. profiles: override replaces defaults when has_profiles mut ov2: config.Override = empty_override() ov2.profiles = ["default", "claude-share", "node-dev"] ov2.has_profiles = true let e4 = config.merge_with_defaults("isurus", "isurus-project", "", ov2, d) runner.assert_eq_int(e4.profiles.length(), 3, "override profiles count") runner.assert_eq_string(e4.profiles[2], "node-dev", "override profiles[2]") // 5. profiles fall back to defaults let e5 = config.merge_with_defaults("isurus", "isurus-project", "", empty_override(), d) runner.assert_eq_int(e5.profiles.length(), 2, "defaults profiles count") // 6. mounts: auto bind always present, override appended mut m1: [config.Mount] = new [config.Mount](1) m1[0] = config.Mount { source: "~/.npm", path: "/home/u/.npm" } mut ov3: config.Override = empty_override() ov3.mounts = m1 let e6 = config.merge_with_defaults("isurus", "isurus-project", "", ov3, d) runner.assert_eq_int(e6.mounts.length(), 2, "auto bind + 1 override mount") runner.assert_eq_string(e6.mounts[0].source, "/home/u/repos/isurus-project", "auto bind source") runner.assert_eq_string(e6.mounts[0].path, "/home/u/repos/isurus-project", "auto bind dest") runner.assert_eq_string(e6.mounts[1].source, "/home/test/.npm", "override mount expanded") // 7. env: passed through mut keys: [string] = ["NODE_ENV"] mut vals: [string] = ["development"] mut ov4: config.Override = empty_override() ov4.env_keys = keys ov4.env_values = vals let e7 = config.merge_with_defaults("isurus", "isurus-project", "", ov4, d) runner.assert_eq_int(e7.env_keys.length(), 1, "env_keys count") runner.assert_eq_string(e7.env_keys[0], "NODE_ENV", "env_keys[0]") runner.assert_eq_string(e7.env_values[0], "development", "env_values[0]") runner.report() end main