@@ -657,6 +657,55 @@ def test_select_models_with_external_parent(mocker: MockerFixture):
657657 assert expanded_selections == {added_model .fqn }
658658
659659
660+ def test_select_models_local_tags_take_precedence_over_remote (
661+ mocker : MockerFixture , make_snapshot : t .Callable
662+ ) -> None :
663+ existing_model = SqlModel (
664+ name = "db.existing" ,
665+ query = d .parse_one ("SELECT 1 AS a" ),
666+ )
667+
668+ existing_snapshot = make_snapshot (existing_model )
669+ existing_snapshot .categorize_as (SnapshotChangeCategory .BREAKING )
670+
671+ env_name = "test_env"
672+
673+ state_reader_mock = mocker .Mock ()
674+ state_reader_mock .get_environment .return_value = Environment (
675+ name = env_name ,
676+ snapshots = [existing_snapshot .table_info ],
677+ start_at = "2023-01-01" ,
678+ end_at = "2023-02-01" ,
679+ plan_id = "test_plan_id" ,
680+ )
681+ state_reader_mock .get_snapshots .return_value = {
682+ existing_snapshot .snapshot_id : existing_snapshot
683+ }
684+
685+ local_models : UniqueKeyDict [str , Model ] = UniqueKeyDict ("models" )
686+ local_new = SqlModel (
687+ name = "db.new" ,
688+ tags = ["a" ],
689+ query = d .parse_one ("SELECT 1 as a" ),
690+ )
691+ local_existing = existing_model .copy (update = {"tags" : ["a" ]}) # type: ignore
692+ local_models [local_existing .fqn ] = local_existing
693+ local_models [local_new .fqn ] = local_new
694+
695+ selector = Selector (state_reader_mock , local_models )
696+
697+ selected = selector .select_models (["tag:a" ], env_name )
698+
699+ # both should get selected because they both now have the 'a' tag locally, even though one exists in remote state without the 'a' tag
700+ _assert_models_equal (
701+ selected ,
702+ {
703+ local_existing .fqn : local_existing ,
704+ local_new .fqn : local_new ,
705+ },
706+ )
707+
708+
660709def _assert_models_equal (actual : t .Dict [str , Model ], expected : t .Dict [str , Model ]) -> None :
661710 assert set (actual ) == set (expected )
662711 for name , model in actual .items ():
0 commit comments