"""Tests for template engine.""" from pathlib import Path import tempfile from src.confgen.template import TemplateEngine class TestTemplateEngine: """Tests for TemplateEngine.""" def setup_method(self): """Set up test fixtures.""" self.engine = TemplateEngine() def test_render_simple_template(self): """Test rendering a simple template with variables.""" template = "app_name: {{APP_NAME}}\nport: {{PORT}}" variables = {"APP_NAME": "myapp", "PORT": "8080"} result = self.engine.render(template, variables) assert "app_name: myapp" in result assert "port: 8080" in result def test_render_with_conditionals(self): """Test rendering template with conditionals.""" template = """ {% if DEBUG %} debug_mode: true {% endif %} app_name: {{APP_NAME}} """ variables = {"DEBUG": True, "APP_NAME": "myapp"} result = self.engine.render(template, variables) assert "debug_mode: true" in result assert "app_name: myapp" in result def test_render_with_loops(self): """Test rendering template with loops.""" template = """ services: {% for service in SERVICES %} - name: {{service.name}} port: {{service.port}} {% endfor %} """ variables = { "SERVICES": [ {"name": "web", "port": "80"}, {"name": "api", "port": "8080"}, ] } result = self.engine.render(template, variables) assert "- name: web" in result assert "- name: api" in result assert "port: 80" in result assert "port: 8080" in result def test_extract_variables(self): """Test extracting variables from template.""" template = """ app_name: {{APP_NAME}} database: host: {{DB_HOST}} port: {{DB_PORT}} """ variables = self.engine.extract_variables(template) assert "APP_NAME" in variables assert "DB_HOST" in variables assert "DB_PORT" in variables def test_extract_variables_ignores_env_vars(self): """Test that env variables are not extracted.""" template = """ password: {{env.SECRET_PASSWORD}} api_key: {{vault.SECRET_API_KEY}} """ variables = self.engine.extract_variables(template) assert len(variables) == 0 def test_render_file(self): """Test rendering a template file.""" with tempfile.NamedTemporaryFile( mode="w", suffix=".j2", delete=False ) as f: f.write("app_name: {{APP_NAME}}\nport: {{PORT}}") temp_path = f.name try: variables = {"APP_NAME": "testapp", "PORT": "3000"} result = self.engine.render_file(temp_path, variables) assert "app_name: testapp" in result assert "port: 3000" in result finally: Path(temp_path).unlink() def test_has_conditionals(self): """Test detecting conditionals in template.""" template_with_if = "{% if DEBUG %}debug{% endif %}" template_without_if = "app: {{APP_NAME}}" assert self.engine.has_conditionals(template_with_if) is True assert self.engine.has_conditionals(template_without_if) is False def test_has_loops(self): """Test detecting loops in template.""" template_with_for = "{% for item in ITEMS %}{{item}}{% endfor %}" template_without_for = "app: {{APP_NAME}}" assert self.engine.has_loops(template_with_for) is True assert self.engine.has_loops(template_without_for) is False def test_render_with_default_filters(self): """Test rendering with Jinja2 default filters.""" template = "host: {{HOST | default('localhost')}}" variables = {} result = self.engine.render(template, variables) assert "host: localhost" in result def test_render_with_upper_filter(self): """Test rendering with upper filter.""" template = "name: {{NAME | upper}}" variables = {"NAME": "myapp"} result = self.engine.render(template, variables) assert "name: MYAPP" in result