forked from HAL9000/cleveragents-core
925 lines
31 KiB
Plaintext
925 lines
31 KiB
Plaintext
"""Step definitions for template loaders coverage tests."""
|
|
|
|
import os
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import Mock, MagicMock
|
|
|
|
from behave import given, when, then
|
|
from cleveragents.core.exceptions import TemplateError
|
|
from cleveragents.templates.loaders import (
|
|
TemplateLoader,
|
|
FileTemplateLoader,
|
|
DirectoryTemplateLoader,
|
|
ConfigTemplateLoader,
|
|
load_from_file,
|
|
load_from_string,
|
|
)
|
|
from cleveragents.templates.renderer import TemplateRenderer
|
|
|
|
|
|
@given("I have a clean test environment for template loaders")
|
|
def step_clean_environment_loaders(context):
|
|
"""Set up clean test environment."""
|
|
context.temp_files = []
|
|
context.temp_dirs = []
|
|
context.mock_renderer = None
|
|
context.loader = None
|
|
context.result = None
|
|
context.error = None
|
|
context.file_paths = []
|
|
context.directory_path = None
|
|
context.template_content = None
|
|
|
|
|
|
@given("I have a template renderer for loaders")
|
|
def step_template_renderer_loaders(context):
|
|
"""Create a mock template renderer."""
|
|
context.mock_renderer = Mock(spec=TemplateRenderer)
|
|
context.mock_renderer.register_template = Mock()
|
|
|
|
|
|
@when("I create a base TemplateLoader instance")
|
|
def step_create_base_loader(context):
|
|
"""Create a base TemplateLoader instance."""
|
|
context.loader = TemplateLoader(context.mock_renderer)
|
|
|
|
|
|
@then("the TemplateLoader should be initialized with renderer")
|
|
def step_verify_loader_initialized(context):
|
|
"""Verify TemplateLoader is initialized with renderer."""
|
|
assert context.loader is not None
|
|
assert context.loader.renderer == context.mock_renderer
|
|
|
|
|
|
@then("the renderer should be accessible")
|
|
def step_verify_renderer_accessible(context):
|
|
"""Verify renderer is accessible."""
|
|
assert hasattr(context.loader, "renderer")
|
|
assert context.loader.renderer is not None
|
|
|
|
|
|
@given("I have a base TemplateLoader instance")
|
|
def step_have_base_loader(context):
|
|
"""Create a base TemplateLoader instance."""
|
|
context.loader = TemplateLoader(context.mock_renderer)
|
|
|
|
|
|
@when("I call the load method on base TemplateLoader")
|
|
def step_call_base_loader_load(context):
|
|
"""Call load method on base TemplateLoader."""
|
|
try:
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("a NotImplementedError should be raised")
|
|
def step_verify_not_implemented_error(context):
|
|
"""Verify NotImplementedError is raised."""
|
|
assert context.error is not None
|
|
assert isinstance(context.error, NotImplementedError)
|
|
|
|
|
|
@then('the not implemented error message should be correct')
|
|
def step_verify_not_implemented_message(context):
|
|
"""Verify error message content."""
|
|
assert "Method 'load' is not implemented yet" in str(context.error)
|
|
|
|
|
|
@given("I have valid file paths for templates")
|
|
def step_valid_file_paths(context):
|
|
"""Create valid file paths."""
|
|
context.file_paths = [Path("/tmp/template1.j2"), Path("/tmp/template2.j2")]
|
|
|
|
|
|
@when("I create a FileTemplateLoader instance")
|
|
def step_create_file_loader(context):
|
|
"""Create FileTemplateLoader instance."""
|
|
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
|
|
|
|
|
|
@then("the FileTemplateLoader should be initialized correctly")
|
|
def step_verify_file_loader_init(context):
|
|
"""Verify FileTemplateLoader initialization."""
|
|
assert context.loader is not None
|
|
assert context.loader.renderer == context.mock_renderer
|
|
assert context.loader.file_paths == context.file_paths
|
|
|
|
|
|
@then("the file paths should be stored")
|
|
def step_verify_file_paths_stored(context):
|
|
"""Verify file paths are stored."""
|
|
assert hasattr(context.loader, "file_paths")
|
|
assert context.loader.file_paths == context.file_paths
|
|
|
|
|
|
@given("I have temporary template files created")
|
|
def step_create_temp_files(context):
|
|
"""Create temporary template files."""
|
|
context.temp_files = []
|
|
context.file_paths = []
|
|
|
|
# Create first temp file
|
|
temp1 = tempfile.NamedTemporaryFile(mode="w", suffix=".j2", delete=False)
|
|
temp1.write("Template 1 content: {{ variable1 }}")
|
|
temp1.close()
|
|
context.temp_files.append(temp1.name)
|
|
context.file_paths.append(Path(temp1.name))
|
|
|
|
# Create second temp file
|
|
temp2 = tempfile.NamedTemporaryFile(mode="w", suffix=".j2", delete=False)
|
|
temp2.write("Template 2 content: {{ variable2 }}")
|
|
temp2.close()
|
|
context.temp_files.append(temp2.name)
|
|
context.file_paths.append(Path(temp2.name))
|
|
|
|
|
|
@when("I create and use FileTemplateLoader to load templates")
|
|
def step_use_file_loader(context):
|
|
"""Create and use FileTemplateLoader."""
|
|
try:
|
|
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("the templates should be loaded successfully")
|
|
def step_verify_templates_loaded(context):
|
|
"""Verify templates loaded successfully."""
|
|
assert context.error is None
|
|
assert context.mock_renderer.register_template.call_count == len(context.file_paths)
|
|
|
|
|
|
@then("the templates should be registered with the renderer")
|
|
def step_verify_templates_registered(context):
|
|
"""Verify templates are registered."""
|
|
assert context.mock_renderer.register_template.called
|
|
assert context.mock_renderer.register_template.call_count > 0
|
|
|
|
|
|
@then("the template names should be derived from file stems")
|
|
def step_verify_template_names_from_stems(context):
|
|
"""Verify template names come from file stems."""
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
for i, call in enumerate(calls):
|
|
expected_name = Path(context.temp_files[i]).stem
|
|
actual_name = call[0][0] # First argument to register_template
|
|
assert actual_name == expected_name
|
|
|
|
|
|
@given("I have a non-existent file path")
|
|
def step_non_existent_file_path(context):
|
|
"""Create non-existent file path."""
|
|
context.file_paths = [Path("/non/existent/file.j2")]
|
|
|
|
|
|
@when("I create and use FileTemplateLoader with non-existent file")
|
|
def step_use_file_loader_non_existent(context):
|
|
"""Use FileTemplateLoader with non-existent file."""
|
|
try:
|
|
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("a TemplateError should be raised")
|
|
def step_verify_template_error(context):
|
|
"""Verify TemplateError is raised."""
|
|
assert context.error is not None
|
|
assert isinstance(context.error, TemplateError)
|
|
|
|
|
|
@then('the template file not found error should be raised')
|
|
def step_verify_file_not_found_error(context):
|
|
"""Verify error mentions file not found."""
|
|
assert "Template file not found" in str(context.error)
|
|
|
|
|
|
@given("I have an unreadable file path")
|
|
def step_unreadable_file_path(context):
|
|
"""Create unreadable file path."""
|
|
# Create a temp file and make it unreadable
|
|
temp = tempfile.NamedTemporaryFile(mode="w", suffix=".j2", delete=False)
|
|
temp.write("content")
|
|
temp.close()
|
|
|
|
# Make file unreadable
|
|
os.chmod(temp.name, 0o000)
|
|
|
|
context.temp_files.append(temp.name)
|
|
context.file_paths = [Path(temp.name)]
|
|
|
|
|
|
@when("I create and use FileTemplateLoader with unreadable file")
|
|
def step_use_file_loader_unreadable(context):
|
|
"""Use FileTemplateLoader with unreadable file."""
|
|
try:
|
|
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then('the failed to load template file error should be raised')
|
|
def step_verify_failed_load_error(context):
|
|
"""Verify error mentions failed to load."""
|
|
assert "Failed to load template from file" in str(context.error)
|
|
|
|
|
|
@given("I have a valid directory path")
|
|
def step_valid_directory_path(context):
|
|
"""Create valid directory path."""
|
|
context.directory_path = Path(tempfile.mkdtemp())
|
|
context.temp_dirs.append(str(context.directory_path))
|
|
|
|
|
|
@when("I create a DirectoryTemplateLoader instance")
|
|
def step_create_directory_loader(context):
|
|
"""Create DirectoryTemplateLoader instance."""
|
|
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
|
|
|
|
|
|
@then("the DirectoryTemplateLoader should be initialized correctly")
|
|
def step_verify_directory_loader_init(context):
|
|
"""Verify DirectoryTemplateLoader initialization."""
|
|
assert context.loader is not None
|
|
assert context.loader.renderer == context.mock_renderer
|
|
assert context.loader.directory_path == context.directory_path
|
|
assert context.loader.recursive is True # default
|
|
assert context.loader.pattern == "*.j2" # default
|
|
|
|
|
|
@then("the directory path should be stored")
|
|
def step_verify_directory_path_stored(context):
|
|
"""Verify directory path is stored."""
|
|
assert hasattr(context.loader, "directory_path")
|
|
assert context.loader.directory_path == context.directory_path
|
|
|
|
|
|
@then("the recursive flag should be set correctly")
|
|
def step_verify_recursive_flag(context):
|
|
"""Verify recursive flag is set."""
|
|
assert hasattr(context.loader, "recursive")
|
|
assert context.loader.recursive is True
|
|
|
|
|
|
@then("the pattern should be set correctly")
|
|
def step_verify_pattern_set(context):
|
|
"""Verify pattern is set."""
|
|
assert hasattr(context.loader, "pattern")
|
|
assert context.loader.pattern == "*.j2"
|
|
|
|
|
|
@when("I create a DirectoryTemplateLoader with custom parameters")
|
|
def step_create_directory_loader_custom(context):
|
|
"""Create DirectoryTemplateLoader with custom parameters."""
|
|
context.loader = DirectoryTemplateLoader(
|
|
context.mock_renderer,
|
|
context.directory_path,
|
|
recursive=False,
|
|
pattern="*.txt"
|
|
)
|
|
|
|
|
|
@then("the DirectoryTemplateLoader should be initialized with custom settings")
|
|
def step_verify_directory_loader_custom_init(context):
|
|
"""Verify DirectoryTemplateLoader custom initialization."""
|
|
assert context.loader is not None
|
|
assert context.loader.renderer == context.mock_renderer
|
|
assert context.loader.directory_path == context.directory_path
|
|
|
|
|
|
@then("the recursive flag should be false")
|
|
def step_verify_recursive_false(context):
|
|
"""Verify recursive flag is false."""
|
|
assert context.loader.recursive is False
|
|
|
|
|
|
@then('the pattern should be "*.txt"')
|
|
def step_verify_pattern_txt(context):
|
|
"""Verify pattern is *.txt."""
|
|
assert context.loader.pattern == "*.txt"
|
|
|
|
|
|
@given("I have a temporary directory with template files")
|
|
def step_temp_directory_with_files(context):
|
|
"""Create temporary directory with template files."""
|
|
context.directory_path = Path(tempfile.mkdtemp())
|
|
context.temp_dirs.append(str(context.directory_path))
|
|
|
|
# Create template files
|
|
temp_files = []
|
|
for i in range(2):
|
|
temp_file = context.directory_path / f"template{i+1}.j2"
|
|
with open(temp_file, "w") as f:
|
|
f.write(f"Template {i+1} content: {{{{ variable{i+1} }}}}")
|
|
temp_files.append(str(temp_file))
|
|
|
|
context.temp_files.extend(temp_files)
|
|
|
|
|
|
@when("I create and use DirectoryTemplateLoader to load templates")
|
|
def step_use_directory_loader(context):
|
|
"""Use DirectoryTemplateLoader to load templates."""
|
|
try:
|
|
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("the templates should be loaded from directory")
|
|
def step_verify_templates_loaded_from_directory(context):
|
|
"""Verify templates loaded from directory."""
|
|
assert context.error is None
|
|
assert context.mock_renderer.register_template.called
|
|
|
|
|
|
@then("the templates should be registered with correct names")
|
|
def step_verify_correct_template_names(context):
|
|
"""Verify templates registered with correct names."""
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
assert len(calls) > 0
|
|
|
|
# Verify template names are derived correctly
|
|
for call in calls:
|
|
template_name = call[0][0]
|
|
assert isinstance(template_name, str)
|
|
assert len(template_name) > 0
|
|
|
|
|
|
@then("the template names should use relative paths")
|
|
def step_verify_relative_path_names(context):
|
|
"""Verify template names use relative paths."""
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
for call in calls:
|
|
template_name = call[0][0]
|
|
# Should not contain absolute path elements
|
|
assert not template_name.startswith("/")
|
|
|
|
|
|
@given("I have a temporary directory with nested template files")
|
|
def step_temp_directory_nested_files(context):
|
|
"""Create temporary directory with nested template files."""
|
|
context.directory_path = Path(tempfile.mkdtemp())
|
|
context.temp_dirs.append(str(context.directory_path))
|
|
|
|
# Create root level file
|
|
root_file = context.directory_path / "root.j2"
|
|
with open(root_file, "w") as f:
|
|
f.write("Root template content")
|
|
context.temp_files.append(str(root_file))
|
|
|
|
# Create nested directory and file
|
|
nested_dir = context.directory_path / "nested"
|
|
nested_dir.mkdir()
|
|
nested_file = nested_dir / "nested.j2"
|
|
with open(nested_file, "w") as f:
|
|
f.write("Nested template content")
|
|
context.temp_files.append(str(nested_file))
|
|
|
|
|
|
@when("I create and use DirectoryTemplateLoader with non-recursive setting")
|
|
def step_use_directory_loader_non_recursive(context):
|
|
"""Use DirectoryTemplateLoader with non-recursive setting."""
|
|
try:
|
|
context.loader = DirectoryTemplateLoader(
|
|
context.mock_renderer,
|
|
context.directory_path,
|
|
recursive=False
|
|
)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("only templates from root directory should be loaded")
|
|
def step_verify_only_root_templates(context):
|
|
"""Verify only root templates loaded."""
|
|
assert context.error is None
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
|
|
# Should only have root template, not nested
|
|
assert len(calls) == 1
|
|
template_name = calls[0][0][0]
|
|
assert template_name == "root"
|
|
|
|
|
|
@then("nested templates should not be loaded")
|
|
def step_verify_nested_templates_not_loaded(context):
|
|
"""Verify nested templates not loaded."""
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
template_names = [call[0][0] for call in calls]
|
|
|
|
# Should not contain nested template names
|
|
for name in template_names:
|
|
assert "nested" not in name or "/" not in name
|
|
|
|
|
|
@given("I have a temporary directory with mixed file types")
|
|
def step_temp_directory_mixed_files(context):
|
|
"""Create temporary directory with mixed file types."""
|
|
context.directory_path = Path(tempfile.mkdtemp())
|
|
context.temp_dirs.append(str(context.directory_path))
|
|
|
|
# Create .j2 file
|
|
j2_file = context.directory_path / "template.j2"
|
|
with open(j2_file, "w") as f:
|
|
f.write("J2 template content")
|
|
context.temp_files.append(str(j2_file))
|
|
|
|
# Create .txt file
|
|
txt_file = context.directory_path / "template.txt"
|
|
with open(txt_file, "w") as f:
|
|
f.write("TXT template content")
|
|
context.temp_files.append(str(txt_file))
|
|
|
|
# Create .html file
|
|
html_file = context.directory_path / "template.html"
|
|
with open(html_file, "w") as f:
|
|
f.write("HTML template content")
|
|
context.temp_files.append(str(html_file))
|
|
|
|
|
|
@when("I create and use DirectoryTemplateLoader with custom pattern")
|
|
def step_use_directory_loader_custom_pattern(context):
|
|
"""Use DirectoryTemplateLoader with custom pattern."""
|
|
try:
|
|
context.loader = DirectoryTemplateLoader(
|
|
context.mock_renderer,
|
|
context.directory_path,
|
|
pattern="*.txt"
|
|
)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("only matching files should be loaded")
|
|
def step_verify_only_matching_files(context):
|
|
"""Verify only matching files loaded."""
|
|
assert context.error is None
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
|
|
# Should only have txt template
|
|
assert len(calls) == 1
|
|
template_name = calls[0][0][0]
|
|
assert template_name == "template"
|
|
|
|
|
|
@then("non-matching files should be ignored")
|
|
def step_verify_non_matching_ignored(context):
|
|
"""Verify non-matching files ignored."""
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
|
|
# Should not have j2 or html templates
|
|
template_names = [call[0][0] for call in calls]
|
|
assert len(template_names) == 1
|
|
assert "template" in template_names
|
|
|
|
|
|
@given("I have a non-existent directory path")
|
|
def step_non_existent_directory_path(context):
|
|
"""Create non-existent directory path."""
|
|
context.directory_path = Path("/non/existent/directory")
|
|
|
|
|
|
@when("I create and use DirectoryTemplateLoader with non-existent directory")
|
|
def step_use_directory_loader_non_existent(context):
|
|
"""Use DirectoryTemplateLoader with non-existent directory."""
|
|
try:
|
|
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then('the template directory not found error should be raised')
|
|
def step_verify_directory_not_found_error(context):
|
|
"""Verify error mentions directory not found."""
|
|
assert "Template directory not found" in str(context.error)
|
|
|
|
|
|
@given("I have a file path instead of directory")
|
|
def step_file_instead_of_directory(context):
|
|
"""Create file path instead of directory."""
|
|
temp = tempfile.NamedTemporaryFile(delete=False)
|
|
temp.write(b"content")
|
|
temp.close()
|
|
|
|
context.temp_files.append(temp.name)
|
|
context.directory_path = Path(temp.name)
|
|
|
|
|
|
@when("I create and use DirectoryTemplateLoader with file path")
|
|
def step_use_directory_loader_with_file(context):
|
|
"""Use DirectoryTemplateLoader with file path."""
|
|
try:
|
|
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then('the not a directory error should be raised')
|
|
def step_verify_not_directory_error(context):
|
|
"""Verify error mentions not a directory."""
|
|
assert "Not a directory" in str(context.error)
|
|
|
|
|
|
@given("I have a directory with unreadable template file")
|
|
def step_directory_with_unreadable_file(context):
|
|
"""Create directory with unreadable template file."""
|
|
context.directory_path = Path(tempfile.mkdtemp())
|
|
context.temp_dirs.append(str(context.directory_path))
|
|
|
|
# Create unreadable file
|
|
temp_file = context.directory_path / "template.j2"
|
|
with open(temp_file, "w") as f:
|
|
f.write("content")
|
|
|
|
# Make file unreadable
|
|
os.chmod(temp_file, 0o000)
|
|
context.temp_files.append(str(temp_file))
|
|
|
|
|
|
@when("I create and use DirectoryTemplateLoader with problematic directory")
|
|
def step_use_directory_loader_problematic(context):
|
|
"""Use DirectoryTemplateLoader with problematic directory."""
|
|
try:
|
|
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@given("I have a valid config dictionary")
|
|
def step_valid_config_dictionary(context):
|
|
"""Create valid config dictionary."""
|
|
context.template_config = {
|
|
"templates": {
|
|
"template1": "Template 1 content: {{ var1 }}",
|
|
"template2": "Template 2 content: {{ var2 }}"
|
|
}
|
|
}
|
|
|
|
|
|
@when("I create a ConfigTemplateLoader instance")
|
|
def step_create_config_loader(context):
|
|
"""Create ConfigTemplateLoader instance."""
|
|
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
|
|
|
|
|
|
@then("the ConfigTemplateLoader should be initialized correctly")
|
|
def step_verify_config_loader_init(context):
|
|
"""Verify ConfigTemplateLoader initialization."""
|
|
assert context.loader is not None
|
|
assert context.loader.renderer == context.mock_renderer
|
|
assert context.loader.config == context.template_config
|
|
|
|
|
|
@then("the config should be stored")
|
|
def step_verify_config_stored(context):
|
|
"""Verify config is stored."""
|
|
assert hasattr(context.loader, "config")
|
|
assert context.loader.config == context.template_config
|
|
|
|
|
|
@given("I have a config with string templates")
|
|
def step_config_with_string_templates(context):
|
|
"""Create config with string templates."""
|
|
context.template_config = {
|
|
"templates": {
|
|
"string_template1": "String template 1: {{ var1 }}",
|
|
"string_template2": "String template 2: {{ var2 }}"
|
|
}
|
|
}
|
|
|
|
|
|
@when("I create and use ConfigTemplateLoader to load templates")
|
|
def step_use_config_loader(context):
|
|
"""Use ConfigTemplateLoader to load templates."""
|
|
try:
|
|
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("the string templates should be loaded")
|
|
def step_verify_string_templates_loaded(context):
|
|
"""Verify string templates loaded."""
|
|
assert context.error is None
|
|
assert context.mock_renderer.register_template.call_count == 2
|
|
|
|
|
|
@then("the string templates should be registered with correct names")
|
|
def step_verify_config_template_names(context):
|
|
"""Verify templates registered with correct names."""
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
template_names = [call[0][0] for call in calls]
|
|
|
|
assert "string_template1" in template_names
|
|
assert "string_template2" in template_names
|
|
|
|
|
|
@given("I have a config with dict templates containing content")
|
|
def step_config_with_dict_templates(context):
|
|
"""Create config with dict templates."""
|
|
context.template_config = {
|
|
"templates": {
|
|
"dict_template1": {
|
|
"content": "Dict template 1: {{ var1 }}",
|
|
"metadata": {"type": "dict"}
|
|
},
|
|
"dict_template2": {
|
|
"content": "Dict template 2: {{ var2 }}",
|
|
"metadata": {"type": "dict"}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@when("I create and use ConfigTemplateLoader to load dict templates")
|
|
def step_use_config_loader_dict(context):
|
|
"""Use ConfigTemplateLoader to load dict templates."""
|
|
try:
|
|
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("the dict templates should be loaded")
|
|
def step_verify_dict_templates_loaded(context):
|
|
"""Verify dict templates loaded."""
|
|
assert context.error is None
|
|
assert context.mock_renderer.register_template.call_count == 2
|
|
|
|
|
|
@then("only the content should be registered")
|
|
def step_verify_only_content_registered(context):
|
|
"""Verify only content is registered."""
|
|
calls = context.mock_renderer.register_template.call_args_list
|
|
|
|
for call in calls:
|
|
template_content = call[0][1] # Second argument is content
|
|
assert "Dict template" in template_content
|
|
assert "{{ var" in template_content
|
|
|
|
|
|
@given("I have an empty config dictionary")
|
|
def step_empty_config_dictionary(context):
|
|
"""Create empty config dictionary."""
|
|
context.template_config = {}
|
|
|
|
|
|
@when("I create and use ConfigTemplateLoader with empty config")
|
|
def step_use_config_loader_empty(context):
|
|
"""Use ConfigTemplateLoader with empty config."""
|
|
try:
|
|
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("no templates should be loaded")
|
|
def step_verify_no_templates_loaded(context):
|
|
"""Verify no templates loaded."""
|
|
assert context.error is None
|
|
assert context.mock_renderer.register_template.call_count == 0
|
|
|
|
|
|
@then("no errors should occur")
|
|
def step_verify_no_errors(context):
|
|
"""Verify no errors occurred."""
|
|
assert context.error is None
|
|
|
|
|
|
@given("I have a config without templates section for loaders")
|
|
def step_config_without_templates(context):
|
|
"""Create config without templates section."""
|
|
context.template_config = {
|
|
"other_section": {
|
|
"key": "value"
|
|
}
|
|
}
|
|
|
|
|
|
@when("I create and use ConfigTemplateLoader with config without templates")
|
|
def step_use_config_loader_no_templates(context):
|
|
"""Use ConfigTemplateLoader with config without templates."""
|
|
try:
|
|
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@given("I have a config with invalid template definition")
|
|
def step_config_with_invalid_template(context):
|
|
"""Create config with invalid template definition."""
|
|
context.template_config = {
|
|
"templates": {
|
|
"valid_template": "Valid content",
|
|
"invalid_template": ["invalid", "list", "format"]
|
|
}
|
|
}
|
|
|
|
|
|
@when("I create and use ConfigTemplateLoader with invalid config")
|
|
def step_use_config_loader_invalid(context):
|
|
"""Use ConfigTemplateLoader with invalid config."""
|
|
try:
|
|
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then('the invalid template definition error should be raised')
|
|
def step_verify_invalid_template_error(context):
|
|
"""Verify error mentions invalid template definition."""
|
|
assert "Invalid template definition" in str(context.error)
|
|
|
|
|
|
@given("I have a config that will cause processing exception")
|
|
def step_config_causing_exception(context):
|
|
"""Create config that will cause processing exception."""
|
|
# Create a mock renderer that raises an exception
|
|
context.mock_renderer.register_template.side_effect = Exception("Mock exception")
|
|
context.template_config = {
|
|
"templates": {
|
|
"template1": "Content"
|
|
}
|
|
}
|
|
|
|
|
|
@when("I create and use ConfigTemplateLoader with problematic config")
|
|
def step_use_config_loader_problematic(context):
|
|
"""Use ConfigTemplateLoader with problematic config."""
|
|
try:
|
|
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
|
|
context.loader.load()
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then('the failed to load from configuration error should be raised')
|
|
def step_verify_config_load_error(context):
|
|
"""Verify error mentions failed to load from configuration."""
|
|
assert "Failed to load templates from configuration" in str(context.error)
|
|
|
|
|
|
@given("I have a temporary file with content")
|
|
def step_temp_file_with_content(context):
|
|
"""Create temporary file with content."""
|
|
temp = tempfile.NamedTemporaryFile(mode="w", delete=False)
|
|
context.template_content = "Test file content: {{ variable }}"
|
|
temp.write(context.template_content)
|
|
temp.close()
|
|
|
|
context.temp_files.append(temp.name)
|
|
context.file_path = temp.name
|
|
|
|
|
|
@when("I call load_from_file with the file path")
|
|
def step_call_load_from_file(context):
|
|
"""Call load_from_file function."""
|
|
try:
|
|
context.result = load_from_file(context.file_path)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("the file content should be returned")
|
|
def step_verify_file_content_returned(context):
|
|
"""Verify file content is returned."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
assert isinstance(context.result, str)
|
|
|
|
|
|
@then("the content should match the original")
|
|
def step_verify_content_matches(context):
|
|
"""Verify content matches original."""
|
|
assert context.result == context.template_content
|
|
|
|
|
|
@given("I have a non-existent file path for load_from_file")
|
|
def step_non_existent_file_load_from_file(context):
|
|
"""Create non-existent file path for load_from_file."""
|
|
context.file_path = "/non/existent/file.txt"
|
|
|
|
|
|
@when("I call load_from_file with non-existent path")
|
|
def step_call_load_from_file_non_existent(context):
|
|
"""Call load_from_file with non-existent path."""
|
|
try:
|
|
context.result = load_from_file(context.file_path)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("None should be returned from load_from_file")
|
|
def step_verify_none_returned(context):
|
|
"""Verify None is returned."""
|
|
assert context.error is None
|
|
assert context.result is None
|
|
|
|
|
|
@given("I have an unreadable file for load_from_file")
|
|
def step_unreadable_file_load_from_file(context):
|
|
"""Create unreadable file for load_from_file."""
|
|
temp = tempfile.NamedTemporaryFile(mode="w", delete=False)
|
|
temp.write("content")
|
|
temp.close()
|
|
|
|
# Make file unreadable
|
|
os.chmod(temp.name, 0o000)
|
|
|
|
context.temp_files.append(temp.name)
|
|
context.file_path = temp.name
|
|
|
|
|
|
@when("I call load_from_file with unreadable file")
|
|
def step_call_load_from_file_unreadable(context):
|
|
"""Call load_from_file with unreadable file."""
|
|
try:
|
|
context.result = load_from_file(context.file_path)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@given("I have a template string for load_from_string")
|
|
def step_template_string(context):
|
|
"""Create template string."""
|
|
context.template_content = "Template string content: {{ variable }}"
|
|
|
|
|
|
@when("I call load_from_string with the template string")
|
|
def step_call_load_from_string(context):
|
|
"""Call load_from_string function."""
|
|
try:
|
|
context.result = load_from_string(context.template_content)
|
|
except Exception as e:
|
|
context.error = e
|
|
|
|
|
|
@then("the same string should be returned")
|
|
def step_verify_same_string_returned(context):
|
|
"""Verify same string is returned."""
|
|
assert context.error is None
|
|
assert context.result is not None
|
|
|
|
|
|
@then("the returned string should be identical to input")
|
|
def step_verify_identical_string(context):
|
|
"""Verify returned string is identical."""
|
|
assert context.result == context.template_content
|
|
assert context.result is context.template_content # Should be same object
|
|
|
|
|
|
def cleanup_test_files(context):
|
|
"""Clean up temporary files and directories."""
|
|
# Clean up temp files
|
|
for temp_file in getattr(context, 'temp_files', []):
|
|
try:
|
|
if os.path.exists(temp_file):
|
|
# Restore permissions before deletion
|
|
os.chmod(temp_file, 0o644)
|
|
os.unlink(temp_file)
|
|
except (OSError, PermissionError):
|
|
pass
|
|
|
|
# Clean up temp directories
|
|
for temp_dir in getattr(context, 'temp_dirs', []):
|
|
try:
|
|
if os.path.exists(temp_dir):
|
|
# Restore permissions for all files in directory
|
|
for root, dirs, files in os.walk(temp_dir):
|
|
for d in dirs:
|
|
try:
|
|
os.chmod(os.path.join(root, d), 0o755)
|
|
except (OSError, PermissionError):
|
|
pass
|
|
for f in files:
|
|
try:
|
|
os.chmod(os.path.join(root, f), 0o644)
|
|
except (OSError, PermissionError):
|
|
pass
|
|
|
|
import shutil
|
|
shutil.rmtree(temp_dir)
|
|
except (OSError, PermissionError):
|
|
pass
|
|
|
|
|
|
# Register cleanup function
|
|
def after_scenario(context, scenario):
|
|
"""Clean up after each scenario."""
|
|
cleanup_test_files(context) |