Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/sushi_dbt/models/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ models:
tests:
- less_than_amount:
amount: 1000
- greater_than_amount:
amount: 0
- name: ds
description: Date
- name: top_waiters
Expand Down
5 changes: 5 additions & 0 deletions examples/sushi_dbt/tests/generic/greater_than_amount.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{%- test greater_than_amount(model, column_name, amount) -%}
select *
from {{ model }}
where {{ column_name }} < {{ amount }}
{%- endtest -%}
13 changes: 9 additions & 4 deletions sqlmesh/dbt/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,12 +673,17 @@ def _node_base_config(node: ManifestNode) -> t.Dict[str, t.Any]:


def _convert_jinja_test_to_macro(test_jinja: str) -> str:
TEST_TAG_REGEX = r"\s*{%\s*test\s+"
ENDTEST_REGEX = r"{%\s*endtest\s*%}"
TEST_TAG_REGEX = r"\s*{%-?\s*test\s+"
ENDTEST_REGEX = r"{%-?\s*endtest\s*-?%}"

match = re.match(TEST_TAG_REGEX, test_jinja)
if not match:
# already a macro
return test_jinja

macro = "{% macro test_" + test_jinja[match.span()[-1] :]
return re.sub(ENDTEST_REGEX, "{% endmacro %}", macro)
test_tag = test_jinja[: match.span()[-1]]

macro_tag = re.sub(r"({%-?\s*)test\s+", r"\1macro test_", test_tag)
macro = macro_tag + test_jinja[match.span()[-1] :]

return re.sub(ENDTEST_REGEX, lambda m: m.group(0).replace("endtest", "endmacro"), macro)
44 changes: 43 additions & 1 deletion tests/dbt/test_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from sqlmesh.core.config import ModelDefaultsConfig
from sqlmesh.dbt.basemodel import Dependencies
from sqlmesh.dbt.context import DbtContext
from sqlmesh.dbt.manifest import ManifestHelper
from sqlmesh.dbt.manifest import ManifestHelper, _convert_jinja_test_to_macro
from sqlmesh.dbt.profile import Profile
from sqlmesh.dbt.builtin import Api, _relation_info_to_relation
from sqlmesh.dbt.util import DBT_VERSION
Expand Down Expand Up @@ -257,3 +257,45 @@ def test_top_level_dbt_adapter_macros():
customers_macros = helper.macros("customers")
assert not customers_macros["default__current_engine"].info.is_top_level
assert not customers_macros["duckdb__current_engine"].info.is_top_level


def test_convert_jinja_test_to_macro():
# Test block with whitespace trimming
test_input = """{%- test assert_positive(model, column_name) -%}
select * from {{ model }} where {{ column_name }} <= 0
{%- endtest -%}"""

expected_output = """{%- macro test_assert_positive(model, column_name) -%}
select * from {{ model }} where {{ column_name }} <= 0
{%- endmacro -%}"""

assert _convert_jinja_test_to_macro(test_input) == expected_output

# Test block without whitespace trimming
test_input_no_ws = """{% test assert_positive(model, column_name) %}
select * from {{ model }} where {{ column_name }} <= 0
{% endtest %}"""

expected_output_no_ws = """{% macro test_assert_positive(model, column_name) %}
select * from {{ model }} where {{ column_name }} <= 0
{% endmacro %}"""

assert _convert_jinja_test_to_macro(test_input_no_ws) == expected_output_no_ws

# Test block with mixed whitespace trimming
test_input_mixed = """{%- test complex_test(model, column_name='id') %}
select count(*) from {{ model }} where {{ column_name }} is null
{% endtest -%}"""

expected_output_mixed = """{%- macro test_complex_test(model, column_name='id') %}
select count(*) from {{ model }} where {{ column_name }} is null
{% endmacro -%}"""

assert _convert_jinja_test_to_macro(test_input_mixed) == expected_output_mixed

# Test already converted macro (should return unchanged)
macro_input = """{%- macro test_already_converted(model) -%}
select * from {{ model }}
{%- endmacro -%}"""

assert _convert_jinja_test_to_macro(macro_input) == macro_input