f808abff86
Fix JSON syntax errors in .devcontainer/devcontainer.json (removed
invalid JS-style // comments) and .devcontainer/opencode.json (removed
90+ trailing commas). Apply auto-fixes for end-of-file and trailing
whitespace issues across 100+ files. Fix SIM105 ruff violations in
benchmarks/core_circuit_breaker_bench.py (use contextlib.suppress).
Note: The security fix from issue #7478 (validate_path startswith bypass)
was already delivered to master in commit e18ac5f2. This PR as currently
structured is non-atomic (35 commits across 10+ issues) and needs
significant restructure before merge. This commit only addresses the
CI/pre-commit failures.
ISSUES CLOSED: #7478
671 lines
27 KiB
Gherkin
671 lines
27 KiB
Gherkin
Feature: Consolidated Config
|
|
Combined scenarios from: config_parser_coverage, config_resolution, config_service_coverage, coverage_threshold_config
|
|
|
|
# ============================================================
|
|
# Originally from: config_parser_coverage.feature
|
|
# Feature: Reactive config parser coverage
|
|
# ============================================================
|
|
|
|
Scenario: Parse combined configs with merges, routes, and pipelines
|
|
Given a temporary directory for reactive config parsing
|
|
Given reactive config files covering merges, routes, and pipelines
|
|
When I parse the reactive config files
|
|
Then the merged reactive config should preserve agents and replacements
|
|
And stream and graph routes should be built with defaults and bridges
|
|
And reactive config should include merges splits pipelines and templates
|
|
|
|
|
|
Scenario: Interpolate environment variables with defaults
|
|
Given a temporary directory for reactive config parsing
|
|
Given a reactive config file with environment placeholders
|
|
And environment variables are set for interpolation
|
|
When I parse the reactive config files
|
|
Then environment placeholders should resolve using values and defaults
|
|
|
|
|
|
Scenario: Raise error for missing required environment variable
|
|
Given a temporary directory for reactive config parsing
|
|
Given a reactive config file with a required environment placeholder
|
|
When I parse the reactive config files expecting failure
|
|
Then a configuration error should be raised for the missing variable
|
|
|
|
|
|
# ============================================================
|
|
# Originally from: config_resolution.feature
|
|
# Feature: Config service with multi-level resolution
|
|
# ============================================================
|
|
|
|
Scenario: Default value is returned when nothing else is set
|
|
Given a clean config service test environment
|
|
When I resolve config key "core.log.level"
|
|
Then the resolved value should be "FATAL"
|
|
And the resolved source should be "default"
|
|
|
|
|
|
Scenario: Global config file overrides default
|
|
Given a clean config service test environment
|
|
Given I have written global config key "core.log.level" with value "DEBUG"
|
|
When I resolve config key "core.log.level"
|
|
Then the resolved value should be "DEBUG"
|
|
And the resolved source should be "global"
|
|
|
|
|
|
Scenario: Environment variable overrides global config
|
|
Given a clean config service test environment
|
|
Given I have written global config key "core.log.level" with value "DEBUG"
|
|
And the environment variable "CLEVERAGENTS_LOG_LEVEL" is set to "WARNING"
|
|
When I resolve config key "core.log.level"
|
|
Then the resolved value should be "WARNING"
|
|
And the resolved source should be "env_var"
|
|
|
|
|
|
Scenario: CLI flag overrides environment variable
|
|
Given a clean config service test environment
|
|
Given the environment variable "CLEVERAGENTS_LOG_LEVEL" is set to "WARNING"
|
|
When I resolve config key "core.log.level" with CLI value "ERROR"
|
|
Then the resolved value should be "ERROR"
|
|
And the resolved source should be "cli_flag"
|
|
|
|
|
|
Scenario: Project-scoped value overrides global config
|
|
Given a clean config service test environment
|
|
Given I have written global config key "core.automation-profile" with value "review"
|
|
And I have written project "myproj" config key "core.automation-profile" with value "trusted"
|
|
When I resolve config key "core.automation-profile" for project "myproj"
|
|
Then the resolved value should be "trusted"
|
|
And the resolved source should be "project"
|
|
|
|
|
|
Scenario: Env var still overrides project-scoped value
|
|
Given a clean config service test environment
|
|
Given I have written project "myproj" config key "core.automation-profile" with value "trusted"
|
|
And the environment variable "CLEVERAGENTS_AUTOMATION_PROFILE" is set to "manual"
|
|
When I resolve config key "core.automation-profile" for project "myproj"
|
|
Then the resolved value should be "manual"
|
|
And the resolved source should be "env_var"
|
|
|
|
# --- Env var interpolation ---
|
|
|
|
|
|
Scenario: Env var name matches CLEVERAGENTS convention
|
|
Given a clean config service test environment
|
|
When I look up the env var for key "core.log.level"
|
|
Then the env var name should be "CLEVERAGENTS_LOG_LEVEL"
|
|
|
|
|
|
Scenario: Env var interpolation for plan keys
|
|
Given a clean config service test environment
|
|
When I look up the env var for key "plan.concurrency"
|
|
Then the env var name should be "CLEVERAGENTS_PLAN_CONCURRENCY"
|
|
|
|
|
|
Scenario: Env var interpolation for plan budget keys
|
|
Given a clean config service test environment
|
|
When I look up the env var for key "plan.budget.warn-threshold"
|
|
Then the env var name should be "CLEVERAGENTS_PLAN_BUDGET_WARN"
|
|
|
|
|
|
Scenario: Provider keys use custom env var names
|
|
Given a clean config service test environment
|
|
When I look up the env var for key "provider.openai.api-key"
|
|
Then the env var name should be "OPENAI_API_KEY"
|
|
|
|
# --- Unknown key rejection ---
|
|
|
|
|
|
Scenario: Resolving an unknown key raises an error
|
|
Given a clean config service test environment
|
|
When I attempt to resolve unknown key "bogus.nonexistent"
|
|
Then the config ValueError message should contain "Unknown configuration key"
|
|
|
|
|
|
Scenario: Validating an unknown key raises an error
|
|
Given a clean config service test environment
|
|
When I attempt to validate unknown key "invalid.key"
|
|
Then the config ValueError message should contain "Unknown configuration key"
|
|
|
|
# --- Type validation ---
|
|
|
|
|
|
Scenario: Integer value is coerced from string
|
|
Given a clean config service test environment
|
|
Given the environment variable "CLEVERAGENTS_PLAN_CONCURRENCY" is set to "9090"
|
|
When I resolve config key "plan.concurrency"
|
|
Then the resolved value should be integer 9090
|
|
|
|
|
|
Scenario: Boolean value true is coerced from string
|
|
Given a clean config service test environment
|
|
Given the environment variable "CLEVERAGENTS_LOG_FILE_ENABLED" is set to "true"
|
|
When I resolve config key "core.log.file-enabled"
|
|
Then the resolved value should be boolean true
|
|
|
|
|
|
Scenario: Boolean value false is coerced from string
|
|
Given a clean config service test environment
|
|
Given the environment variable "CLEVERAGENTS_LOG_FILE_ENABLED" is set to "false"
|
|
When I resolve config key "core.log.file-enabled"
|
|
Then the resolved value should be boolean false
|
|
|
|
|
|
Scenario: Float value is coerced from string
|
|
Given a clean config service test environment
|
|
Given the environment variable "CLEVERAGENTS_PLAN_BUDGET_WARN" is set to "0.9"
|
|
When I resolve config key "plan.budget.warn-threshold"
|
|
Then the resolved value should be float 0.9
|
|
|
|
|
|
Scenario: Invalid boolean string raises TypeError
|
|
Given a clean config service test environment
|
|
When I attempt to validate type for key "core.log.file-enabled" with value "notabool"
|
|
Then the config TypeError message should contain "Cannot convert"
|
|
|
|
|
|
Scenario: Invalid integer string raises TypeError
|
|
Given a clean config service test environment
|
|
When I attempt to validate type for key "plan.concurrency" with value "notanumber"
|
|
Then the config TypeError message should contain "Type mismatch"
|
|
|
|
# --- Verbose resolution chain ---
|
|
|
|
|
|
Scenario: Verbose mode returns full resolution chain
|
|
Given a clean config service test environment
|
|
When I resolve config key "core.log.level" with verbose mode
|
|
Then the resolution chain should have 6 entries
|
|
And the chain should include source "cli_flag"
|
|
And the chain should include source "env_var"
|
|
And the chain should include source "local"
|
|
And the chain should include source "project"
|
|
And the chain should include source "global"
|
|
And the chain should include source "default"
|
|
|
|
# --- Key registry ---
|
|
|
|
|
|
Scenario: Registry contains core keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "core.log.level"
|
|
And the registry should contain key "core.log.file-enabled"
|
|
And the registry should contain key "core.data-dir"
|
|
|
|
|
|
Scenario: Registry contains plan keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "plan.concurrency"
|
|
And the registry should contain key "plan.max-child-depth"
|
|
And the registry should contain key "plan.budget.per-plan"
|
|
|
|
|
|
Scenario: Registry contains provider keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "provider.openai.api-key"
|
|
And the registry should contain key "provider.anthropic.api-key"
|
|
|
|
|
|
Scenario: Registry contains sandbox keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "sandbox.strategy"
|
|
And the registry should contain key "sandbox.cleanup"
|
|
And the registry should contain key "sandbox.checkpoint.enabled"
|
|
|
|
|
|
Scenario: Registry contains context keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "context.hot.max-tokens"
|
|
And the registry should contain key "context.warm.max-decisions"
|
|
|
|
|
|
Scenario: Registry contains index keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "index.auto-reindex"
|
|
And the registry should contain key "index.text.backend"
|
|
|
|
|
|
Scenario: Registry contains server keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "server.url"
|
|
And the registry should contain key "server.token"
|
|
And the registry should contain key "server.sync.auto"
|
|
|
|
|
|
Scenario: Registry contains actor keys
|
|
Given a clean config service test environment
|
|
Then the registry should contain key "actor.default.strategy"
|
|
And the registry should contain key "actor.default.execution"
|
|
|
|
# --- TOML file management ---
|
|
|
|
|
|
Scenario: Writing and reading TOML config roundtrips
|
|
Given a clean config service test environment
|
|
Given I write config data with key "core.log.level" and value "TRACE"
|
|
When I read the config file
|
|
Then the config data should contain key "core.log.level" with value "TRACE"
|
|
|
|
|
|
Scenario: Config directory is auto-created
|
|
Given a clean config service test environment
|
|
When I write config data to a new directory
|
|
Then the config directory should exist
|
|
|
|
|
|
Scenario: Non-project-scopable keys ignore project scope
|
|
Given a clean config service test environment
|
|
Given I have written project "proj" config key "core.data-dir" with value "/tmp/other"
|
|
When I resolve config key "core.data-dir" for project "proj"
|
|
Then the resolved source should be "default"
|
|
|
|
# --- Resolve all ---
|
|
|
|
|
|
Scenario: Resolve all returns all registered keys
|
|
Given a clean config service test environment
|
|
When I resolve all keys
|
|
Then the result should contain all registered keys
|
|
|
|
# --- Set value ---
|
|
|
|
|
|
Scenario: Set value persists to TOML file
|
|
Given a clean config service test environment
|
|
When I set config value "core.log.level" to "CRITICAL"
|
|
And I read the config file
|
|
Then the config data should contain key "core.log.level" with value "CRITICAL"
|
|
|
|
# --- Entry lookup ---
|
|
|
|
|
|
Scenario: Get entry returns ConfigEntry for valid key
|
|
Given a clean config service test environment
|
|
When I get entry for key "core.log.level"
|
|
Then the entry should have section "core"
|
|
And the entry should have python type "str"
|
|
|
|
|
|
Scenario: Get entry returns None for unknown key
|
|
Given a clean config service test environment
|
|
When I get entry for key "nonexistent.key"
|
|
Then the entry should be None
|
|
|
|
|
|
# ============================================================
|
|
# Originally from: config_service_coverage.feature
|
|
# Feature: ConfigService full coverage
|
|
# ============================================================
|
|
|
|
Scenario: ConfigLevel enum has six precedence levels
|
|
Then ConfigLevel should have values CLI_FLAG ENV_VAR LOCAL PROJECT GLOBAL DEFAULT
|
|
|
|
# ---------- ConfigEntry and ResolvedValue dataclasses ----------
|
|
|
|
|
|
Scenario: ConfigEntry dataclass stores all metadata fields
|
|
Given a ConfigEntry with key "test.key" and type str
|
|
Then the ConfigEntry fields should match the provided values
|
|
|
|
|
|
Scenario: ResolvedValue dataclass stores resolution result
|
|
Given a ResolvedValue with key "test.key" and source DEFAULT
|
|
Then the ResolvedValue fields should match including an empty chain by default
|
|
|
|
# ---------- _env_name helper ----------
|
|
|
|
|
|
Scenario: _env_name builds uppercase CLEVERAGENTS env var name
|
|
When I call _env_name with section "core" and key "log_level"
|
|
Then the env name should be "CLEVERAGENTS_CORE_LOG_LEVEL"
|
|
|
|
# ---------- _register and _build_catalog ----------
|
|
|
|
|
|
Scenario: _register adds an entry to the global registry
|
|
When I register a custom key "custom.test_key" with type int and default 42
|
|
Then the registry should contain "custom.test_key" with default 42
|
|
|
|
|
|
Scenario: _register uses explicit env_var when provided
|
|
When I register a key "custom.explicit_env" with explicit env_var "MY_CUSTOM_VAR"
|
|
Then the entry "custom.explicit_env" should have env_var "MY_CUSTOM_VAR"
|
|
|
|
|
|
Scenario: _build_catalog populates all expected config sections
|
|
Then the registry should contain keys from sections core plan provider sandbox context index
|
|
|
|
|
|
Scenario: _build_catalog registers the expected number of keys
|
|
Then the registry should contain at least 20 keys
|
|
|
|
# ---------- ConfigService instantiation ----------
|
|
|
|
|
|
Scenario: ConfigService uses custom config_dir and config_path
|
|
Given a temporary directory for config service
|
|
When I create a ConfigService with custom paths
|
|
Then the service should use the custom config directory and path
|
|
|
|
|
|
Scenario: ConfigService uses defaults when no paths provided
|
|
When I create a ConfigService with default paths
|
|
Then the service config path should end with ".cleveragents/config.toml"
|
|
|
|
# ---------- registry(), get_entry(), registered_keys() ----------
|
|
|
|
|
|
Scenario: registry returns a copy of all registered entries
|
|
When I call ConfigService.registry
|
|
Then it should return a dict with the same keys as the internal registry
|
|
|
|
|
|
Scenario: get_entry returns the entry for a known key
|
|
When I call ConfigService.get_entry with "core.log.level"
|
|
Then it should return a ConfigEntry with key "core.log.level"
|
|
|
|
|
|
Scenario: get_entry returns None for an unknown key
|
|
When I call ConfigService.get_entry with "nonexistent.key"
|
|
Then it should return None
|
|
|
|
|
|
Scenario: registered_keys returns a sorted list of all keys
|
|
When I call ConfigService.registered_keys
|
|
Then it should return a sorted list containing "core.log.level"
|
|
|
|
# ---------- read_config ----------
|
|
|
|
|
|
Scenario: read_config returns empty dict when file does not exist
|
|
Given a temporary directory for config service
|
|
When I create a ConfigService pointing to a missing config file
|
|
Then read_config should return an empty dict
|
|
|
|
|
|
Scenario: read_config parses an existing TOML file
|
|
Given a temporary directory for config service
|
|
And a TOML config file with key "core.log.level" set to "DEBUG"
|
|
When I create a ConfigService pointing to that TOML file
|
|
Then read_config should return a dict with "core.log.level" equal to "DEBUG"
|
|
|
|
# ---------- write_config ----------
|
|
|
|
|
|
Scenario: write_config creates directories and writes a new TOML file
|
|
Given a temporary directory for config service
|
|
When I create a ConfigService with a nested non-existent config directory
|
|
And I call write_config with key "greeting" value "hello"
|
|
Then the TOML file should exist and contain key "greeting" with value "hello"
|
|
|
|
|
|
Scenario: write_config merges data into an existing TOML file
|
|
Given a temporary directory for config service
|
|
And a TOML config file with key "existing" set to "value1"
|
|
When I create a ConfigService pointing to that TOML file
|
|
And I call write_config with key "new_key" value "value2"
|
|
Then read_config should return a dict containing both "existing" and "new_key"
|
|
|
|
# ---------- set_value ----------
|
|
|
|
|
|
Scenario: set_value persists a single key-value pair
|
|
Given a temporary directory for config service
|
|
When I create a ConfigService with custom paths
|
|
And I call set_value with key "mykey" and value "myval"
|
|
Then read_config should return a dict with "mykey" equal to "myval"
|
|
|
|
# ---------- validate_key ----------
|
|
|
|
|
|
Scenario: validate_key returns entry for a known key
|
|
When I call validate_key with "core.log.level"
|
|
Then it should return the ConfigEntry for "core.log.level" without error
|
|
|
|
|
|
Scenario: validate_key raises ValueError for an unknown key
|
|
When I call validate_key with "totally.unknown"
|
|
Then a ValueError should be raised mentioning "Unknown configuration key"
|
|
|
|
# ---------- validate_type ----------
|
|
|
|
|
|
Scenario: validate_type returns value unchanged when type already matches
|
|
When I call validate_type with key "core.log.level" and value "INFO"
|
|
Then it should return "INFO" unchanged
|
|
|
|
|
|
Scenario: validate_type coerces a string to int
|
|
When I call validate_type with key "plan.concurrency" and string value "9090"
|
|
Then it should return the integer 9090
|
|
|
|
|
|
Scenario: validate_type coerces a string to float
|
|
When I call validate_type with key "plan.budget.warn-threshold" and string value "0.5"
|
|
Then it should return the float 0.5
|
|
|
|
|
|
Scenario: validate_type coerces non-string to str
|
|
When I call validate_type with key "core.log.level" and integer value 123
|
|
Then it should return the string "123"
|
|
|
|
|
|
Scenario: validate_type coerces "true" string to bool True
|
|
When I call validate_type with key "core.log.file-enabled" and string value "true"
|
|
Then it should return boolean True
|
|
|
|
|
|
Scenario: validate_type coerces "1" string to bool True
|
|
When I call validate_type with key "core.log.file-enabled" and string value "1"
|
|
Then it should return boolean True
|
|
|
|
|
|
Scenario: validate_type coerces "yes" string to bool True
|
|
When I call validate_type with key "core.log.file-enabled" and string value "yes"
|
|
Then it should return boolean True
|
|
|
|
|
|
Scenario: validate_type coerces "false" string to bool False
|
|
When I call validate_type with key "core.log.file-enabled" and string value "false"
|
|
Then it should return boolean False
|
|
|
|
|
|
Scenario: validate_type coerces "0" string to bool False
|
|
When I call validate_type with key "core.log.file-enabled" and string value "0"
|
|
Then it should return boolean False
|
|
|
|
|
|
Scenario: validate_type coerces "no" string to bool False
|
|
When I call validate_type with key "core.log.file-enabled" and string value "no"
|
|
Then it should return boolean False
|
|
|
|
|
|
Scenario: validate_type raises TypeError for invalid bool string
|
|
When I call validate_type with key "core.log.file-enabled" and string value "maybe"
|
|
Then a TypeError should be raised mentioning "Cannot convert"
|
|
|
|
|
|
Scenario: validate_type raises TypeError for non-coercible int value
|
|
When I call validate_type with key "plan.concurrency" and string value "not_a_number"
|
|
Then a TypeError should be raised mentioning "Type mismatch"
|
|
|
|
|
|
Scenario: validate_type raises TypeError for non-bool non-string to bool key
|
|
When I call validate_type with key "core.log.file-enabled" and a list value
|
|
Then a TypeError should be raised mentioning "Type mismatch"
|
|
|
|
|
|
Scenario: validate_type raises ValueError for completely unknown key
|
|
When I call validate_type with unknown key "fake.unknown" and value "x"
|
|
Then the raised ValueError should mention "Cannot validate type for unknown key"
|
|
|
|
# ---------- resolve: six-level chain ----------
|
|
|
|
|
|
Scenario: resolve returns default value when no overrides exist
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
When I resolve key "core.log.level" with no overrides
|
|
Then the resolved value should be "FATAL" from source DEFAULT
|
|
|
|
|
|
Scenario: resolve returns CLI flag value when provided
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
When I resolve key "core.log.level" with cli_value "TRACE"
|
|
Then the resolved value should be "TRACE" from source CLI_FLAG
|
|
|
|
|
|
Scenario: resolve returns environment variable when no CLI flag
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
And the env var "CLEVERAGENTS_LOG_LEVEL" is injected with "WARNING"
|
|
When I resolve key "core.log.level" with no overrides
|
|
Then the resolved value should be "WARNING" from source ENV_VAR
|
|
|
|
|
|
Scenario: CLI flag takes precedence over environment variable
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
And the env var "CLEVERAGENTS_LOG_LEVEL" is injected with "WARNING"
|
|
When I resolve key "core.log.level" with cli_value "TRACE"
|
|
Then the resolved value should be "TRACE" from source CLI_FLAG
|
|
|
|
|
|
Scenario: resolve returns project-scoped value when set
|
|
Given a temporary directory for config service
|
|
And a ConfigService with project-scoped config for key "core.automation-profile" value "PROJECT_DEBUG" under project "myproj"
|
|
When I resolve key "core.automation-profile" with project_name "myproj"
|
|
Then the resolved value should be "PROJECT_DEBUG" from source PROJECT
|
|
|
|
|
|
Scenario: resolve returns global config value when no higher overrides
|
|
Given a temporary directory for config service
|
|
And a ConfigService with global config key "core.log.level" set to "GLOBAL_WARN"
|
|
When I resolve key "core.log.level" with no overrides
|
|
Then the resolved value should be "GLOBAL_WARN" from source GLOBAL
|
|
|
|
|
|
Scenario: resolve populates chain when verbose is True
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
When I resolve key "core.log.level" with verbose True and no overrides
|
|
Then the resolved chain should have 6 entries covering all levels
|
|
|
|
|
|
Scenario: resolve verbose chain includes env_name for ENV_VAR level
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
When I resolve key "core.log.level" with verbose True and no overrides
|
|
Then the verbose chain ENV_VAR entry should include env_name "CLEVERAGENTS_LOG_LEVEL"
|
|
|
|
|
|
Scenario: resolve verbose chain includes path for GLOBAL level
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
When I resolve key "core.log.level" with verbose True and no overrides
|
|
Then the verbose chain GLOBAL entry should include the config file path
|
|
|
|
|
|
Scenario: resolve verbose chain shows project value when project-scoped wins
|
|
Given a temporary directory for config service
|
|
And a ConfigService with project-scoped config for key "core.automation-profile" value "PROJECT_DEBUG" under project "myproj"
|
|
When I resolve key "core.automation-profile" with project_name "myproj" and verbose True
|
|
Then the resolved value should be "PROJECT_DEBUG" from source PROJECT
|
|
And the verbose chain PROJECT entry should have value "PROJECT_DEBUG"
|
|
|
|
|
|
Scenario: resolve verbose chain shows global value when global config wins
|
|
Given a temporary directory for config service
|
|
And a ConfigService with global config key "core.log.level" set to "GLOBAL_WARN"
|
|
When I resolve key "core.log.level" with verbose True and no overrides
|
|
Then the resolved value should be "GLOBAL_WARN" from source GLOBAL
|
|
And the verbose chain GLOBAL entry should have value "GLOBAL_WARN"
|
|
|
|
|
|
Scenario: resolve skips project scope for non-scopable keys
|
|
Given a temporary directory for config service
|
|
And a ConfigService with project-scoped config for key "core.data-dir" value "/proj/data" under project "myproj"
|
|
When I resolve key "core.data-dir" with project_name "myproj"
|
|
Then the resolved value should not be "/proj/data"
|
|
And the resolved source should be DEFAULT or GLOBAL
|
|
|
|
# ---------- env_var_for_key ----------
|
|
|
|
|
|
Scenario: env_var_for_key returns the env var name for a valid key
|
|
When I call env_var_for_key with "core.log.level"
|
|
Then it should return "CLEVERAGENTS_LOG_LEVEL"
|
|
|
|
|
|
Scenario: env_var_for_key raises ValueError for an unknown key
|
|
When I call env_var_for_key with "nonexistent.key"
|
|
Then a ValueError should be raised mentioning "Unknown configuration key"
|
|
|
|
# ---------- resolve_all ----------
|
|
|
|
|
|
Scenario: resolve_all returns a resolved value for every registered key
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
When I call resolve_all with no overrides
|
|
Then the result should contain an entry for every registered key
|
|
|
|
|
|
Scenario: resolve_all applies CLI overrides to matching keys
|
|
Given a temporary directory for config service
|
|
And a ConfigService with empty config for resolve tests
|
|
When I call resolve_all with cli_override "core.log.level" set to "FATAL"
|
|
Then the resolve_all result for "core.log.level" should have value "FATAL" and source CLI_FLAG
|
|
|
|
|
|
# ============================================================
|
|
# Originally from: coverage_threshold_config.feature
|
|
# Feature: Coverage threshold configuration enforcement
|
|
# ============================================================
|
|
|
|
Scenario: Coverage configuration exists in pyproject.toml
|
|
Given the pyproject toml file is loaded for coverage check
|
|
Then the coverage run section should exist
|
|
And the coverage source should include "src"
|
|
And the coverage branch tracking should be enabled
|
|
|
|
|
|
@tdd_issue @tdd_issue_4227
|
|
Scenario: Coverage threshold is at least 96.5 percent in noxfile
|
|
Given the noxfile py is loaded for coverage check
|
|
Then the noxfile should contain a fail-under threshold of at least 96.5
|
|
|
|
|
|
Scenario: Coverage report session exists in noxfile
|
|
Given the noxfile py is loaded for coverage check
|
|
Then the noxfile should define a coverage_report session
|
|
|
|
|
|
Scenario: Coverage HTML output directory is configured
|
|
Given the pyproject toml file is loaded for coverage check
|
|
Then the coverage html directory should be "build/htmlcov"
|
|
|
|
|
|
Scenario: Coverage XML output path is configured
|
|
Given the pyproject toml file is loaded for coverage check
|
|
Then the coverage xml output should be "build/coverage.xml"
|
|
|
|
|
|
Scenario: Coverage data file path is configured
|
|
Given the pyproject toml file is loaded for coverage check
|
|
Then the coverage data file should be "build/.coverage"
|
|
|
|
|
|
Scenario: Coverage omits test directories
|
|
Given the pyproject toml file is loaded for coverage check
|
|
Then the coverage omit patterns should include "features/*"
|
|
And the coverage omit patterns should include "*/tests/*"
|
|
|
|
|
|
Scenario: CI workflow enforces coverage via nox session
|
|
Given the ci workflow file is loaded for coverage check
|
|
Then the ci workflow should reference nox coverage_report session
|
|
|
|
|
|
Scenario: Nightly workflow uses at least 96.5 percent threshold
|
|
Given the nightly quality workflow file is loaded for coverage check
|
|
Then the nightly workflow should use a fail-under of at least 96.5
|