Compare commits

...

6 Commits

Author SHA1 Message Date
VersusFacit
1c46fe2850 Pare down scope 2025-05-12 20:24:00 -07:00
VersusFacit
3e937c8c3d Remove unexplained code for now 2025-05-12 19:49:11 -07:00
VersusFacit
de9e7122d2 Successful TDD for injecting the sql header 2025-05-12 18:10:01 -07:00
VersusFacit
0f42592f25 We're intending to do both tests in this PR 2025-05-12 18:09:37 -07:00
Christophe Oudar
7241b679db Provide required missing context to resolve sql_header in unit tests 2025-05-12 17:54:33 -07:00
VersusFacit
948316597b Let's do the test first and TDD this issue. 2025-05-12 17:53:26 -07:00
3 changed files with 108 additions and 6 deletions

View File

@@ -0,0 +1,6 @@
kind: Fixes
body: Provide required missing context to resolve sql_header in unit tests.
time: 2025-03-27T00:27:11.364727+01:00
custom:
Author: Kayrnt versusfacit
Issue: "9775"

View File

@@ -10,7 +10,11 @@ from dbt import utils
from dbt.artifacts.resources import ModelConfig, UnitTestConfig, UnitTestFormat
from dbt.config import RuntimeConfig
from dbt.context.context_config import ContextConfig
from dbt.context.providers import generate_parse_exposure, get_rendered
from dbt.context.providers import (
generate_parse_exposure,
generate_runtime_unit_test_context,
get_rendered,
)
from dbt.contracts.files import FileHash, SchemaSourceFile
from dbt.contracts.graph.manifest import Manifest
from dbt.contracts.graph.model_config import UnitTestNodeConfig
@@ -100,12 +104,18 @@ class UnitTestManifestLoader:
overrides=test_case.overrides,
)
ctx = generate_parse_exposure(
unit_test_node, # type: ignore
self.root_project,
self.manifest,
test_case.package_name,
# Needed to support macro-based set_sql_header overrides of the sql_header node config
# option.
ctx = generate_runtime_unit_test_context(unit_test_node, self.root_project, self.manifest)
ctx.update(
generate_parse_exposure(
unit_test_node, # type: ignore
self.root_project,
self.manifest,
test_case.package_name,
)
)
get_rendered(unit_test_node.raw_code, ctx, unit_test_node, capture_macros=True)
# unit_test_node now has a populated refs/sources

View File

@@ -0,0 +1,86 @@
from pathlib import Path
import pytest
from dbt.tests.util import run_dbt
PROJECT_NAME = "sql_header_test"
UNITTEST_MODEL_NAME = "unittest_model"
# Why this and not some other database functionality?
# To keep it database agnostic since we support SQL on the
# the most generic create table macro"
HEADER_MARKER = "-- SQL_HEADER_INJECTION_TEST_MARKER"
UNITTEST_MODEL_SQL = f"""
{{{{ config(
materialized='table',
sql_header='{HEADER_MARKER}'
)}}}}
select 1 as id union all select 2 as id
"""
UNITTEST_MACRO_SQL_HEADER_MODEL_SQL = f"""
{{{{ config(
materialized='table',
)}}}}
{{% call set_sql_header(config) %}}
{HEADER_MARKER}
{{% endcall %}}
select 1 as id union all select 2 as id
"""
UNITTEST_SCHEMA_YML = f"""
unit_tests:
- name: test_sql_macro_header_injection
model: {UNITTEST_MODEL_NAME}
given: []
expect:
rows:
- {{id: 1}}
- {{id: 2}}
"""
class SQLHeaderInjectionBase:
@pytest.fixture(scope="class")
def project_config_update(self):
return {
"name": PROJECT_NAME,
}
def test_sql_header_is_injected(self, project):
results = run_dbt(["build"])
assert any(r.node.name == UNITTEST_MODEL_NAME for r in results)
compiled_model_path = (
project.project_root
/ Path("target")
/ Path("run")
/ Path(PROJECT_NAME)
/ Path("models")
/ Path(f"{UNITTEST_MODEL_NAME}.sql")
)
with open(compiled_model_path) as f:
assert any(
HEADER_MARKER in line for line in f
), "SQL header marker not found in compiled SQL."
class TestSQLHeaderConfigInjection(SQLHeaderInjectionBase):
@pytest.fixture(scope="class")
def models(self):
return {
f"{UNITTEST_MODEL_NAME}.sql": UNITTEST_MODEL_SQL,
"schema.yml": UNITTEST_SCHEMA_YML,
}
class TestSQLHeaderMacroInjection(SQLHeaderInjectionBase):
@pytest.fixture(scope="class")
def models(self):
return {
f"{UNITTEST_MODEL_NAME}.sql": UNITTEST_MACRO_SQL_HEADER_MODEL_SQL,
"schema.yml": UNITTEST_SCHEMA_YML,
}