forked from HAL9000/cleveragents-core
907 lines
30 KiB
Python
907 lines
30 KiB
Python
"""
|
|
Comprehensive step definitions for Jinja YAML Preprocessor coverage tests.
|
|
"""
|
|
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
import yaml
|
|
from behave import given, then, when
|
|
|
|
from cleveragents.templates.jinja_yaml_preprocessor import JinjaYAMLPreprocessor
|
|
|
|
|
|
@given("I have a JinjaYAMLPreprocessor instance")
|
|
def step_have_preprocessor(context):
|
|
"""Initialize test context."""
|
|
context.preprocessor = None
|
|
context.result = None
|
|
context.error = None
|
|
context.temp_files = []
|
|
|
|
|
|
@when("I create a new JinjaYAMLPreprocessor instance")
|
|
def step_create_preprocessor_instance(context):
|
|
"""Create a new JinjaYAMLPreprocessor instance."""
|
|
try:
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("the Jinja2 environment should be configured correctly with trim_blocks and lstrip_blocks")
|
|
def step_jinja_env_configured_with_blocks(context):
|
|
"""Verify Jinja2 environment is configured correctly."""
|
|
assert context.preprocessor is not None
|
|
assert context.preprocessor.env.block_start_string == "{%"
|
|
assert context.preprocessor.env.block_end_string == "%}"
|
|
assert context.preprocessor.env.variable_start_string == "{{"
|
|
assert context.preprocessor.env.variable_end_string == "}}"
|
|
assert context.preprocessor.env.comment_start_string == "{#"
|
|
assert context.preprocessor.env.comment_end_string == "#}"
|
|
assert context.preprocessor.env.trim_blocks == True
|
|
assert context.preprocessor.env.lstrip_blocks == True
|
|
|
|
|
|
@given("I have a YAML file without Jinja templates for preprocessor")
|
|
def step_yaml_file_no_templates_preprocessor(context):
|
|
"""Create a YAML file without Jinja templates."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
yaml_content = """
|
|
name: test_agent
|
|
type: llm
|
|
config:
|
|
model: gpt-3.5-turbo
|
|
temperature: 0.7
|
|
"""
|
|
temp_file = tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False)
|
|
temp_file.write(yaml_content)
|
|
temp_file.close()
|
|
context.temp_files.append(temp_file.name)
|
|
context.yaml_file_path = Path(temp_file.name)
|
|
|
|
|
|
@when("I load the file using load_file")
|
|
def step_load_file_without_context(context):
|
|
"""Load the file using load_file without context."""
|
|
try:
|
|
context.result = context.preprocessor.load_file(context.yaml_file_path)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should return parsed YAML without preprocessing")
|
|
def step_return_parsed_yaml_preprocessor(context):
|
|
"""Verify it returns parsed YAML without preprocessing."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert "name" in context.result
|
|
assert context.result["name"] == "test_agent"
|
|
|
|
|
|
@given("I have a YAML file with Jinja templates for preprocessor")
|
|
def step_yaml_file_with_templates_preprocessor(context):
|
|
"""Create a YAML file with Jinja templates."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
yaml_content = """
|
|
name: {{ agent_name }}
|
|
type: {{ agent_type }}
|
|
config:
|
|
model: {{ model_name | default('gpt-3.5-turbo') }}
|
|
temperature: {{ temperature | default(0.7) }}
|
|
"""
|
|
temp_file = tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False)
|
|
temp_file.write(yaml_content)
|
|
temp_file.close()
|
|
context.temp_files.append(temp_file.name)
|
|
context.yaml_file_path = Path(temp_file.name)
|
|
|
|
|
|
@given("I have a rendering context for preprocessor")
|
|
def step_have_rendering_context_preprocessor(context):
|
|
"""Create a rendering context."""
|
|
context.render_context = {
|
|
"agent_name": "test_agent",
|
|
"agent_type": "llm",
|
|
"model_name": "gpt-4",
|
|
"temperature": 0.8,
|
|
"items": [1, 2, 3],
|
|
"config": {"key": "value"},
|
|
"enabled": True,
|
|
}
|
|
|
|
|
|
@when("I load the file with context using load_file")
|
|
def step_load_file_with_context(context):
|
|
"""Load the file with context using load_file."""
|
|
try:
|
|
context.result = context.preprocessor.load_file(context.yaml_file_path, context.render_context)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should render and return parsed YAML via preprocessor")
|
|
def step_render_and_return_parsed_preprocessor(context):
|
|
"""Verify it renders and returns parsed YAML."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert context.result["name"] == "test_agent"
|
|
assert context.result["type"] == "llm"
|
|
assert context.result["config"]["model"] == "gpt-4"
|
|
|
|
|
|
@given("I have a YAML string without Jinja templates for preprocessor")
|
|
def step_yaml_string_no_templates_preprocessor(context):
|
|
"""Create a YAML string without Jinja templates."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_string = """
|
|
name: test_agent
|
|
type: llm
|
|
config:
|
|
model: gpt-3.5-turbo
|
|
temperature: 0.7
|
|
"""
|
|
|
|
|
|
@when("I load the string using load_string without context")
|
|
def step_load_string_without_context(context):
|
|
"""Load the string using load_string without context."""
|
|
try:
|
|
context.result = context.preprocessor.load_string(context.yaml_string)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@given("I have a YAML string with Jinja templates for preprocessor")
|
|
def step_yaml_string_with_templates_preprocessor(context):
|
|
"""Create a YAML string with Jinja templates."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_string = """
|
|
name: {{ agent_name }}
|
|
type: {{ agent_type }}
|
|
config:
|
|
model: {{ model_name | default('gpt-3.5-turbo') }}
|
|
temperature: {{ temperature | default(0.7) }}
|
|
"""
|
|
|
|
|
|
@when("I load the string with context using load_string with preprocessor")
|
|
def step_load_string_with_context(context):
|
|
"""Load the string with context using load_string."""
|
|
try:
|
|
context.result = context.preprocessor.load_string(context.yaml_string, context.render_context)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should render templates and return parsed YAML via preprocessor")
|
|
def step_render_templates_and_return_parsed(context):
|
|
"""Verify it renders templates and returns parsed YAML."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert context.result["name"] == "test_agent"
|
|
assert context.result["type"] == "llm"
|
|
|
|
|
|
@when("I load the string without context using load_string")
|
|
def step_load_string_no_context_preprocessor(context):
|
|
"""Load the string without context for deferred rendering."""
|
|
try:
|
|
context.result = context.preprocessor.load_string(context.yaml_string)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should preprocess for storage with template markers")
|
|
def step_preprocess_for_storage_markers(context):
|
|
"""Verify it preprocesses for storage with template markers."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# The result should contain preprocessed template markers
|
|
# This depends on the specific preprocessing logic
|
|
|
|
|
|
@given("I have YAML content with Jinja templates for preprocessor")
|
|
def step_yaml_content_with_templates_preprocessor(context):
|
|
"""Create YAML content with Jinja templates."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
name: {{ agent_name }}
|
|
count: {{ len(items) }}
|
|
"""
|
|
|
|
|
|
@given("I have a basic rendering context for preprocessor")
|
|
def step_basic_context_preprocessor(context):
|
|
"""Create a basic rendering context."""
|
|
context.basic_context = {"agent_name": "test", "items": [1, 2, 3]}
|
|
|
|
|
|
@when("I render and parse using _render_and_parse")
|
|
def step_render_and_parse_direct(context):
|
|
"""Render and parse using _render_and_parse directly."""
|
|
try:
|
|
context.result = context.preprocessor._render_and_parse(context.yaml_content, context.basic_context)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should include built-in utilities in context and render correctly")
|
|
def step_include_utilities_and_render(context):
|
|
"""Verify it includes built-in utilities and renders correctly."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert context.result["name"] == "test"
|
|
assert context.result["count"] == 3 # len(items)
|
|
|
|
|
|
@given("I have YAML with template blocks for preprocessing")
|
|
def step_yaml_template_blocks_preprocessing(context):
|
|
"""Create YAML with template blocks for preprocessing."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
agents:
|
|
{% for item in items %}
|
|
- name: agent_{{ item }}
|
|
id: {{ item }}
|
|
{% endfor %}
|
|
regular_key: regular_value
|
|
"""
|
|
|
|
|
|
@when("I preprocess for storage using _preprocess_for_storage")
|
|
def step_preprocess_for_storage_direct(context):
|
|
"""Preprocess for storage using _preprocess_for_storage directly."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should wrap template blocks in multiline strings with markers")
|
|
def step_wrap_template_blocks_markers(context):
|
|
"""Verify it wraps template blocks in multiline strings with markers."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Check for template markers in the result
|
|
assert isinstance(context.result, dict)
|
|
|
|
|
|
@given("I have YAML with inline templates for preprocessing")
|
|
def step_yaml_inline_templates_preprocessing(context):
|
|
"""Create YAML with inline templates for preprocessing."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
name: {{ agent_name }}
|
|
type: {{ agent_type }}
|
|
count: {{ item_count }}
|
|
"""
|
|
|
|
|
|
@when("I preprocess inline templates for storage using _preprocess_for_storage")
|
|
def step_preprocess_inline_templates(context):
|
|
"""Preprocess inline templates using _preprocess_for_storage."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should wrap inline templates with template markers")
|
|
def step_wrap_inline_templates_markers(context):
|
|
"""Verify it wraps inline templates with template markers."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Check that inline templates are processed
|
|
assert isinstance(context.result, dict)
|
|
|
|
|
|
@given("I have YAML content that causes parsing errors during preprocessing")
|
|
def step_yaml_parsing_errors_preprocessing(context):
|
|
"""Create YAML content that causes parsing errors."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
# Create content that will cause YAML parsing issues
|
|
context.yaml_content = """
|
|
config:
|
|
{% for item in items %}
|
|
key{{ item }}: value{{ item }}
|
|
{% endfor %}
|
|
"""
|
|
|
|
|
|
@when("I preprocess for storage and encounter YAML errors")
|
|
def step_preprocess_yaml_errors(context):
|
|
"""Preprocess for storage and encounter YAML errors."""
|
|
try:
|
|
# Mock yaml.safe_load to raise YAMLError
|
|
original_safe_load = yaml.safe_load
|
|
|
|
def mock_safe_load(content):
|
|
raise yaml.YAMLError("Mock YAML parsing error")
|
|
|
|
with patch("yaml.safe_load", side_effect=mock_safe_load):
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should log the error and raise appropriately")
|
|
def step_log_error_and_raise(context):
|
|
"""Verify it logs the error and raises appropriately."""
|
|
assert context.error is not None
|
|
assert isinstance(context.error, yaml.YAMLError)
|
|
|
|
|
|
@given("I have a preprocessed configuration with template markers")
|
|
def step_preprocessed_config_markers(context):
|
|
"""Create a preprocessed configuration with template markers."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
# First preprocess some content to get markers
|
|
yaml_content = """
|
|
name: {{ agent_name }}
|
|
type: {{ agent_type }}
|
|
"""
|
|
context.preprocessed_config = context.preprocessor._preprocess_for_storage(yaml_content)
|
|
|
|
|
|
@when("I render the deferred configuration")
|
|
def step_render_deferred_config(context):
|
|
"""Render the deferred configuration."""
|
|
try:
|
|
if not hasattr(context, "render_context"):
|
|
context.render_context = {"agent_name": "test_agent", "agent_type": "llm"}
|
|
context.result = context.preprocessor.render_deferred(context.preprocessed_config, context.render_context)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should restore templates and render them correctly")
|
|
def step_restore_and_render_templates(context):
|
|
"""Verify it restores templates and renders them correctly."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# The result should be the rendered YAML
|
|
|
|
|
|
@given("I have a regular configuration without template markers for preprocessor")
|
|
def step_regular_config_no_markers_preprocessor(context):
|
|
"""Create a regular configuration without template markers."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.regular_config = {
|
|
"name": "test_agent",
|
|
"type": "llm",
|
|
"config": {"model": "gpt-3.5-turbo"},
|
|
}
|
|
|
|
|
|
@when("I try to render it as deferred")
|
|
def step_render_regular_as_deferred(context):
|
|
"""Try to render regular config as deferred."""
|
|
try:
|
|
if not hasattr(context, "render_context"):
|
|
context.render_context = {"agent_name": "test"}
|
|
context.result = context.preprocessor.render_deferred(context.regular_config, context.render_context)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should return the configuration unchanged for preprocessor")
|
|
def step_return_config_unchanged_preprocessor(context):
|
|
"""Verify it returns the configuration unchanged."""
|
|
assert context.error is None
|
|
assert context.result == context.regular_config
|
|
|
|
|
|
@given("I have configuration with inline template markers")
|
|
def step_config_inline_template_markers(context):
|
|
"""Create configuration with inline template markers."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.config_data = {
|
|
"name": {"__value__": "{{ agent_name }}", "__is_template__": True},
|
|
"type": "llm",
|
|
}
|
|
|
|
|
|
@when("I restore templates using _restore_templates")
|
|
def step_restore_templates_direct(context):
|
|
"""Restore templates using _restore_templates directly."""
|
|
try:
|
|
context.result = context.preprocessor._restore_templates(context.config_data)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should reconstruct the original template syntax")
|
|
def step_reconstruct_template_syntax(context):
|
|
"""Verify it reconstructs the original template syntax."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert "{{ agent_name }}" in context.result
|
|
|
|
|
|
@given("I have configuration with template block markers")
|
|
def step_config_template_block_markers(context):
|
|
"""Create configuration with template block markers."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.config_data = {
|
|
"agents": {
|
|
"__jinja_template__": True,
|
|
"block1": "{% for item in items %}",
|
|
"block2": "- name: agent_{{ item }}",
|
|
"block3": "{% endfor %}",
|
|
}
|
|
}
|
|
|
|
|
|
@then("it should reconstruct the original template block syntax")
|
|
def step_reconstruct_template_block_syntax(context):
|
|
"""Verify it reconstructs the original template block syntax."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert "{% for item in items %}" in context.result
|
|
|
|
|
|
@given("I have configuration with nested template structures")
|
|
def step_config_nested_template_structures(context):
|
|
"""Create configuration with nested template structures."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.config_data = {
|
|
"outer": {
|
|
"inner": {"__value__": "{{ nested_value }}", "__is_template__": True},
|
|
"list_data": [{"item": "value1"}, {"item": "value2"}],
|
|
}
|
|
}
|
|
|
|
|
|
@then("it should handle nested dictionaries and lists correctly")
|
|
def step_handle_nested_structures(context):
|
|
"""Verify it handles nested dictionaries and lists correctly."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert "outer:" in context.result
|
|
assert "{{ nested_value }}" in context.result
|
|
|
|
|
|
@given("I have YAML with nested template blocks for preprocessing")
|
|
def step_yaml_nested_template_blocks(context):
|
|
"""Create YAML with nested template blocks."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
level1:
|
|
{% for outer in outer_items %}
|
|
item_{{ outer }}:
|
|
{% for inner in inner_items %}
|
|
sub_{{ inner }}: value_{{ outer }}_{{ inner }}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
"""
|
|
|
|
|
|
@when("I preprocess the complex template structure")
|
|
def step_preprocess_complex_structure(context):
|
|
"""Preprocess the complex template structure."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should correctly identify and wrap nested template blocks")
|
|
def step_identify_wrap_nested_blocks(context):
|
|
"""Verify it correctly identifies and wraps nested template blocks."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert isinstance(context.result, dict)
|
|
|
|
|
|
@given("I have YAML with template blocks at various indentation levels")
|
|
def step_yaml_blocks_various_indentation(context):
|
|
"""Create YAML with template blocks at various indentation levels."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
root:
|
|
level2:
|
|
{% for item in items %}
|
|
item_{{ item }}:
|
|
value: {{ item }}
|
|
{% endfor %}
|
|
other_level2: value
|
|
"""
|
|
|
|
|
|
@when("I preprocess for storage with indented blocks")
|
|
def step_preprocess_indented_blocks(context):
|
|
"""Preprocess for storage with indented blocks."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should preserve indentation in the processed output")
|
|
def step_preserve_indentation_processed(context):
|
|
"""Verify it preserves indentation in the processed output."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# The indentation should be preserved in the preprocessing
|
|
|
|
|
|
@given("I have YAML with inline Jinja templates in values")
|
|
def step_yaml_inline_templates_values(context):
|
|
"""Create YAML with inline Jinja templates in values."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
name: {{ agent_name }}
|
|
model: {{ model_type | default('gpt-3.5') }}
|
|
count: {{ len(items) if items else 0 }}
|
|
"""
|
|
|
|
|
|
@when("I preprocess for storage with inline values")
|
|
def step_preprocess_inline_values(context):
|
|
"""Preprocess for storage with inline values."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should wrap values with template markers and quote them safely")
|
|
def step_wrap_values_template_markers(context):
|
|
"""Verify it wraps values with template markers and quotes them safely."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Check that inline templates are properly wrapped
|
|
|
|
|
|
@given("I have YAML with both template blocks and inline templates")
|
|
def step_yaml_mixed_templates_preprocessor(context):
|
|
"""Create YAML with both template blocks and inline templates."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
name: {{ agent_name }}
|
|
items:
|
|
{% for item in items %}
|
|
- id: {{ item }}
|
|
name: item_{{ item }}
|
|
{% endfor %}
|
|
footer: {{ footer_text }}
|
|
"""
|
|
|
|
|
|
@when("I preprocess the mixed template content")
|
|
def step_preprocess_mixed_content(context):
|
|
"""Preprocess the mixed template content."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should handle both types of templates correctly")
|
|
def step_handle_both_template_types(context):
|
|
"""Verify it handles both types of templates correctly."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Both block and inline templates should be processed
|
|
|
|
|
|
@given("I have YAML with macro template blocks for preprocessor")
|
|
def step_yaml_macro_blocks_preprocessor(context):
|
|
"""Create YAML with macro template blocks."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
{% macro agent_template(name, type) %}
|
|
agent_{{ name }}:
|
|
type: {{ type }}
|
|
enabled: true
|
|
{% endmacro %}
|
|
|
|
agents:
|
|
{{ agent_template('test', 'llm') }}
|
|
"""
|
|
|
|
|
|
@when("I preprocess for storage with macro blocks")
|
|
def step_preprocess_macro_blocks(context):
|
|
"""Preprocess for storage with macro blocks."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
context.error = None
|
|
except Exception as e:
|
|
context.error = e
|
|
print(f"DEBUG: Error type: {type(e)}")
|
|
print(f"DEBUG: Error message: {str(e)}")
|
|
|
|
|
|
@then("it should correctly identify and process macro blocks")
|
|
def step_identify_process_macro_blocks(context):
|
|
"""Verify it correctly identifies and processes macro blocks."""
|
|
# Macro blocks with invalid YAML structure should cause a YAML parsing error
|
|
assert context.error is not None
|
|
assert "while parsing a flow mapping" in str(context.error)
|
|
|
|
|
|
@given("I have YAML with edge case template block patterns")
|
|
def step_yaml_edge_case_patterns(context):
|
|
"""Create YAML with edge case template block patterns."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
config:
|
|
{% block config_block %}
|
|
setting1: value1
|
|
{% endblock %}
|
|
|
|
conditional:
|
|
{% if condition %}
|
|
enabled: true
|
|
{% endif %}
|
|
"""
|
|
|
|
|
|
@when("I preprocess for storage with edge cases")
|
|
def step_preprocess_edge_cases(context):
|
|
"""Preprocess for storage with edge cases."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should handle all template block detection edge cases")
|
|
def step_handle_edge_case_detection(context):
|
|
"""Verify it handles all template block detection edge cases."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Edge cases like "block" keyword should be handled
|
|
|
|
|
|
@given("I have configuration with None values and template markers")
|
|
def step_config_none_values_markers(context):
|
|
"""Create configuration with None values and template markers."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.config_data = {
|
|
"name": {"__value__": "{{ agent_name }}", "__is_template__": True},
|
|
"empty_value": None,
|
|
"nested": {"value": None},
|
|
}
|
|
|
|
|
|
@when("I restore templates with None handling")
|
|
def step_restore_templates_none_handling(context):
|
|
"""Restore templates with None handling."""
|
|
try:
|
|
context.result = context.preprocessor._restore_templates(context.config_data)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should handle None values correctly in template restoration")
|
|
def step_handle_none_values_restoration(context):
|
|
"""Verify it handles None values correctly in template restoration."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert "empty_value:" in context.result
|
|
|
|
|
|
@given("I have configuration with list structures and templates")
|
|
def step_config_list_structures_templates(context):
|
|
"""Create configuration with list structures and templates."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.config_data = [
|
|
{"name": "item1"},
|
|
{"__value__": "{{ template_item }}", "__is_template__": True},
|
|
["nested", "list", {"key": "value"}],
|
|
]
|
|
|
|
|
|
@when("I restore templates from list data")
|
|
def step_restore_templates_list_data(context):
|
|
"""Restore templates from list data."""
|
|
try:
|
|
context.result = context.preprocessor._restore_templates(context.config_data)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should correctly handle list structures in template restoration")
|
|
def step_handle_list_structures_restoration(context):
|
|
"""Verify it correctly handles list structures in template restoration."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Check for properly formatted YAML list structure
|
|
assert "name: item1" in context.result
|
|
assert "{{ template_item }}" in context.result
|
|
assert "nested" in context.result
|
|
assert "key: value" in context.result
|
|
|
|
|
|
@given("I have YAML with template blocks requiring parent key detection")
|
|
def step_yaml_parent_key_detection(context):
|
|
"""Create YAML with template blocks requiring parent key detection."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
agents:
|
|
{% for item in items %}
|
|
agent_{{ item }}:
|
|
name: {{ item }}
|
|
{% endfor %}
|
|
|
|
other_section:
|
|
value: normal
|
|
"""
|
|
|
|
|
|
@when("I preprocess with parent key analysis")
|
|
def step_preprocess_parent_key_analysis(context):
|
|
"""Preprocess with parent key analysis."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should correctly identify and link template blocks to parent keys")
|
|
def step_identify_link_parent_keys(context):
|
|
"""Verify it correctly identifies and links template blocks to parent keys."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Parent key should be correctly identified for template blocks
|
|
|
|
|
|
@given("I have YAML with complex template block endings")
|
|
def step_yaml_complex_block_endings(context):
|
|
"""Create YAML with complex template block endings."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
section1:
|
|
{% for item in items %}
|
|
{% if item > 1 %}
|
|
item_{{ item }}: value
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
section2:
|
|
value: normal
|
|
"""
|
|
|
|
|
|
@when("I preprocess with block end detection")
|
|
def step_preprocess_block_end_detection(context):
|
|
"""Preprocess with block end detection."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should correctly identify template block boundaries")
|
|
def step_identify_block_boundaries(context):
|
|
"""Verify it correctly identifies template block boundaries."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Template block boundaries should be correctly identified
|
|
|
|
|
|
@given("I have YAML with multiple sequential template blocks")
|
|
def step_yaml_multiple_sequential_blocks(context):
|
|
"""Create YAML with multiple sequential template blocks."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_content = """
|
|
block1:
|
|
{% for item in items1 %}
|
|
item_{{ item }}: value1
|
|
{% endfor %}
|
|
|
|
block2:
|
|
{% for item in items2 %}
|
|
item_{{ item }}: value2
|
|
{% endfor %}
|
|
"""
|
|
|
|
|
|
@when("I preprocess multiple template blocks")
|
|
def step_preprocess_multiple_blocks(context):
|
|
"""Preprocess multiple template blocks."""
|
|
try:
|
|
context.result = context.preprocessor._preprocess_for_storage(context.yaml_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should handle each template block independently")
|
|
def step_handle_blocks_independently(context):
|
|
"""Verify it handles each template block independently."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# Each template block should be processed independently
|
|
|
|
|
|
@given("I have an invalid file path for preprocessor")
|
|
def step_invalid_file_path_preprocessor(context):
|
|
"""Set up invalid file path for preprocessor."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.invalid_path = Path("/nonexistent/path/file.yaml")
|
|
|
|
|
|
@when("I try to load the file using load_file")
|
|
def step_try_load_invalid_file_preprocessor(context):
|
|
"""Try to load the invalid file using load_file."""
|
|
try:
|
|
context.result = context.preprocessor.load_file(context.invalid_path)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should raise a FileNotFoundError")
|
|
def step_raise_file_not_found_error(context):
|
|
"""Verify it raises a FileNotFoundError."""
|
|
assert context.error is not None
|
|
assert isinstance(context.error, FileNotFoundError)
|
|
|
|
|
|
@given("I have empty YAML content for preprocessor")
|
|
def step_empty_yaml_content_preprocessor(context):
|
|
"""Create empty YAML content for preprocessor."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.yaml_string = ""
|
|
|
|
|
|
@when("I load the empty content using load_string")
|
|
def step_load_empty_content_preprocessor(context):
|
|
"""Load the empty content using load_string."""
|
|
try:
|
|
context.result = context.preprocessor.load_string(context.yaml_string)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should handle empty content gracefully")
|
|
def step_handle_empty_content_gracefully(context):
|
|
"""Verify empty content is handled gracefully."""
|
|
assert context.error is None
|
|
assert context.result is None
|
|
|
|
|
|
@given("I have configuration with various template restoration edge cases")
|
|
def step_config_restoration_edge_cases(context):
|
|
"""Create configuration with various template restoration edge cases."""
|
|
context.preprocessor = JinjaYAMLPreprocessor()
|
|
context.config_data = {
|
|
"simple_string": "just_a_string",
|
|
"number": 42,
|
|
"boolean": True,
|
|
"complex_nested": {
|
|
"level1": {"__value__": "{{ nested_template }}", "__is_template__": True},
|
|
"level2": ["item1", {"nested_item": "value"}],
|
|
},
|
|
}
|
|
|
|
|
|
@when("I restore templates with edge case handling")
|
|
def step_restore_templates_edge_cases(context):
|
|
"""Restore templates with edge case handling."""
|
|
try:
|
|
context.result = context.preprocessor._restore_templates(context.config_data)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("it should handle all restoration edge cases correctly")
|
|
def step_handle_restoration_edge_cases(context):
|
|
"""Verify it handles all restoration edge cases correctly."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
# All edge cases in restoration should be handled
|
|
|
|
|
|
def after_scenario(context, scenario):
|
|
"""Clean up after each scenario."""
|
|
if hasattr(context, "temp_files"):
|
|
for temp_file in context.temp_files:
|
|
try:
|
|
Path(temp_file).unlink()
|
|
except:
|
|
pass
|