From d4309eaa41e7f63eaf5bc63831a1ef1c5c990774 Mon Sep 17 00:00:00 2001 From: Mike Alfare Date: Thu, 24 Oct 2024 15:29:07 -0400 Subject: [PATCH] behavior flags take the default value when the project file is not loaded --- dbt/adapters/base/impl.py | 5 +- tests/unit/behavior_flag_tests/__init__.py | 0 .../test_behavior_flags.py | 0 .../behavior_flag_tests/test_empty_project.py | 87 +++++++++++++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 tests/unit/behavior_flag_tests/__init__.py rename tests/unit/{ => behavior_flag_tests}/test_behavior_flags.py (100%) create mode 100644 tests/unit/behavior_flag_tests/test_empty_project.py diff --git a/dbt/adapters/base/impl.py b/dbt/adapters/base/impl.py index f3788fe3..54ab7105 100644 --- a/dbt/adapters/base/impl.py +++ b/dbt/adapters/base/impl.py @@ -304,8 +304,9 @@ def behavior(self, flags: List[BehaviorFlag]) -> None: # we don't always get project flags, for example during `dbt debug` self._behavior = Behavior(flags, self.config.flags) except AttributeError: - # in that case, don't load any behavior to avoid unexpected defaults - self._behavior = Behavior([], {}) + # in that case, load behavior flags with their default values to avoid compilation errors + # this mimics not loading a project file, or not specifying flags in a project file + self._behavior = Behavior(flags, {}) @property def _behavior_flags(self) -> List[BehaviorFlag]: diff --git a/tests/unit/behavior_flag_tests/__init__.py b/tests/unit/behavior_flag_tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/test_behavior_flags.py b/tests/unit/behavior_flag_tests/test_behavior_flags.py similarity index 100% rename from tests/unit/test_behavior_flags.py rename to tests/unit/behavior_flag_tests/test_behavior_flags.py diff --git a/tests/unit/behavior_flag_tests/test_empty_project.py b/tests/unit/behavior_flag_tests/test_empty_project.py new file mode 100644 index 00000000..f9fd7a76 --- /dev/null +++ b/tests/unit/behavior_flag_tests/test_empty_project.py @@ -0,0 +1,87 @@ +from types import SimpleNamespace +from typing import Any, Dict, List + +from dbt_common.behavior_flags import BehaviorFlag +from dbt_common.exceptions import DbtBaseException +import pytest + +from dbt.adapters.contracts.connection import AdapterRequiredConfig, QueryComment + +from tests.unit.fixtures.credentials import CredentialsStub + + +@pytest.fixture +def flags() -> Dict[str, Any]: + return { + "unregistered_flag": True, + "default_false_user_false_flag": False, + "default_false_user_true_flag": True, + "default_true_user_false_flag": False, + "default_true_user_true_flag": True, + } + + +@pytest.fixture +def config(flags) -> AdapterRequiredConfig: + raw_config = { + "credentials": CredentialsStub("test_database", "test_schema"), + "profile_name": "test_profile", + "target_name": "test_target", + "threads": 4, + "project_name": "test_project", + "query_comment": QueryComment(), + "cli_vars": {}, + "target_path": "path/to/nowhere", + "log_cache_events": False, + } + return SimpleNamespace(**raw_config) + + +@pytest.fixture +def behavior_flags() -> List[BehaviorFlag]: + return [ + { + "name": "default_false_user_false_flag", + "default": False, + "docs_url": "https://docs.com", + }, + { + "name": "default_false_user_true_flag", + "default": False, + "description": "This is a false flag.", + }, + { + "name": "default_false_user_skip_flag", + "default": False, + "description": "This is a true flag.", + }, + { + "name": "default_true_user_false_flag", + "default": True, + "description": "This is fake news.", + }, + { + "name": "default_true_user_true_flag", + "default": True, + "docs_url": "https://moar.docs.com", + }, + { + "name": "default_true_user_skip_flag", + "default": True, + "description": "This is a true flag.", + }, + ] + + +def test_register_behavior_flags(adapter): + # make sure that users cannot add arbitrary flags to this collection + with pytest.raises(DbtBaseException): + assert adapter.behavior.unregistered_flag + + # check the values of the valid behavior flags + assert not adapter.behavior.default_false_user_false_flag + assert not adapter.behavior.default_false_user_true_flag + assert not adapter.behavior.default_false_user_skip_flag + assert adapter.behavior.default_true_user_false_flag + assert adapter.behavior.default_true_user_true_flag + assert adapter.behavior.default_true_user_skip_flag