Skip to content

Commit add451d

Browse files
add tests
1 parent b65e7d9 commit add451d

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed

tests/core/test_selector_native.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import pytest
88
from pytest_mock.plugin import MockerFixture
9+
import subprocess
910

1011
from sqlmesh.core import dialect as d
1112
from sqlmesh.core.audit import StandaloneAudit
@@ -16,6 +17,7 @@
1617
from sqlmesh.core.snapshot import SnapshotChangeCategory
1718
from sqlmesh.utils import UniqueKeyDict
1819
from sqlmesh.utils.date import now_timestamp
20+
from sqlmesh.utils.git import GitClient
1921

2022

2123
@pytest.mark.parametrize(
@@ -634,6 +636,83 @@ def test_expand_git_selection(
634636
git_client_mock.list_untracked_files.assert_called_once()
635637

636638

639+
def test_expand_git_selection_integration(tmp_path: Path, mocker: MockerFixture):
640+
repo_path = tmp_path / "test_repo"
641+
repo_path.mkdir()
642+
subprocess.run(["git", "init"], cwd=repo_path, check=True, capture_output=True)
643+
644+
models: UniqueKeyDict[str, Model] = UniqueKeyDict("models")
645+
model_a_path = repo_path / "model_a.sql"
646+
model_a_path.write_text("SELECT 1 AS a")
647+
model_a = SqlModel(name="test_model_a", query=d.parse_one("SELECT 1 AS a"))
648+
model_a._path = model_a_path
649+
models[model_a.fqn] = model_a
650+
651+
model_b_path = repo_path / "model_b.sql"
652+
model_b_path.write_text("SELECT 2 AS b")
653+
model_b = SqlModel(name="test_model_b", query=d.parse_one("SELECT 2 AS b"))
654+
model_b._path = model_b_path
655+
models[model_b.fqn] = model_b
656+
657+
subprocess.run(["git", "add", "."], cwd=repo_path, check=True, capture_output=True)
658+
subprocess.run(
659+
["git", "commit", "-m", "Initial commit"],
660+
cwd=repo_path,
661+
check=True,
662+
capture_output=True,
663+
)
664+
665+
result = subprocess.run(
666+
["git", "branch", "--show-current"],
667+
cwd=repo_path,
668+
check=True,
669+
capture_output=True,
670+
text=True,
671+
)
672+
default_branch = result.stdout.strip()
673+
674+
# no changes should select nothing
675+
git_client = GitClient(repo_path)
676+
selector = NativeSelector(mocker.Mock(), models)
677+
selector._git_client = git_client
678+
assert selector.expand_model_selections([f"git:{default_branch}"]) == set()
679+
680+
# modify A but dont stage it, should be only selected
681+
model_a_path.write_text("SELECT 10 AS a")
682+
assert selector.expand_model_selections([f"git:{default_branch}"]) == {'"test_model_a"'}
683+
684+
# stage model A, should still select it (this is the bug fix)
685+
subprocess.run(["git", "add", "model_a.sql"], cwd=repo_path, check=True, capture_output=True)
686+
assert selector.expand_model_selections([f"git:{default_branch}"]) == {'"test_model_a"'}
687+
688+
# now add unstaged change to B and both should be selected
689+
model_b_path.write_text("SELECT 20 AS b")
690+
assert selector.expand_model_selections([f"git:{default_branch}"]) == {
691+
'"test_model_a"',
692+
'"test_model_b"',
693+
}
694+
695+
subprocess.run(
696+
["git", "checkout", "-b", "dev"],
697+
cwd=repo_path,
698+
check=True,
699+
capture_output=True,
700+
)
701+
702+
subprocess.run(
703+
["git", "commit", "-m", "Update model_a"],
704+
cwd=repo_path,
705+
check=True,
706+
capture_output=True,
707+
)
708+
709+
# now A is committed in the dev branch and B unstaged but should both be selected
710+
assert selector.expand_model_selections([f"git:{default_branch}"]) == {
711+
'"test_model_a"',
712+
'"test_model_b"',
713+
}
714+
715+
637716
def test_select_models_with_external_parent(mocker: MockerFixture):
638717
default_catalog = "test_catalog"
639718
added_model = SqlModel(

tests/utils/test_git_client.py

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import subprocess
2+
from pathlib import Path
3+
import pytest
4+
from sqlmesh.utils.git import GitClient
5+
6+
7+
@pytest.fixture
8+
def git_repo(tmp_path: Path) -> Path:
9+
repo_path = tmp_path / "test_repo"
10+
repo_path.mkdir()
11+
subprocess.run(["git", "init"], cwd=repo_path, check=True, capture_output=True)
12+
return repo_path
13+
14+
15+
def test_git_uncommitted_changes(git_repo: Path):
16+
git_client = GitClient(git_repo)
17+
18+
test_file = git_repo / "model.sql"
19+
test_file.write_text("SELECT 1 AS a")
20+
subprocess.run(["git", "add", "model.sql"], cwd=git_repo, check=True, capture_output=True)
21+
subprocess.run(
22+
["git", "commit", "-m", "onitial commit"],
23+
cwd=git_repo,
24+
check=True,
25+
capture_output=True,
26+
)
27+
assert git_client.list_uncommitted_changed_files() == []
28+
29+
# make an unstaged change and see that it is listed
30+
test_file.write_text("SELECT 2 AS a")
31+
uncommitted = git_client.list_uncommitted_changed_files()
32+
assert len(uncommitted) == 1
33+
assert uncommitted[0].name == "model.sql"
34+
35+
# stage the change and test that it is still detected
36+
subprocess.run(["git", "add", "model.sql"], cwd=git_repo, check=True, capture_output=True)
37+
uncommitted = git_client.list_uncommitted_changed_files()
38+
assert len(uncommitted) == 1
39+
assert uncommitted[0].name == "model.sql"
40+
41+
42+
def test_git_both_staged_and_unstaged_changes(git_repo: Path):
43+
git_client = GitClient(git_repo)
44+
45+
file1 = git_repo / "model1.sql"
46+
file2 = git_repo / "model2.sql"
47+
file1.write_text("SELECT 1")
48+
file2.write_text("SELECT 2")
49+
subprocess.run(["git", "add", "."], cwd=git_repo, check=True, capture_output=True)
50+
subprocess.run(
51+
["git", "commit", "-m", "onitial commit"],
52+
cwd=git_repo,
53+
check=True,
54+
capture_output=True,
55+
)
56+
57+
# stage file1
58+
file1.write_text("SELECT 10")
59+
subprocess.run(["git", "add", "model1.sql"], cwd=git_repo, check=True, capture_output=True)
60+
61+
# mdify file2 but don't stage it!
62+
file2.write_text("SELECT 20")
63+
64+
# both should be detected
65+
uncommitted = git_client.list_uncommitted_changed_files()
66+
assert len(uncommitted) == 2
67+
file_names = {f.name for f in uncommitted}
68+
assert file_names == {"model1.sql", "model2.sql"}
69+
70+
71+
def test_git_untracked_files(git_repo: Path):
72+
git_client = GitClient(git_repo)
73+
initial_file = git_repo / "initial.sql"
74+
initial_file.write_text("SELECT 0")
75+
subprocess.run(["git", "add", "initial.sql"], cwd=git_repo, check=True, capture_output=True)
76+
subprocess.run(
77+
["git", "commit", "-m", "onitial commit"],
78+
cwd=git_repo,
79+
check=True,
80+
capture_output=True,
81+
)
82+
83+
new_file = git_repo / "new_model.sql"
84+
new_file.write_text("SELECT 1")
85+
86+
# untracked file should not appear in uncommitted changes
87+
assert git_client.list_uncommitted_changed_files() == []
88+
89+
# but in untracked
90+
untracked = git_client.list_untracked_files()
91+
assert len(untracked) == 1
92+
assert untracked[0].name == "new_model.sql"
93+
94+
95+
def test_git_committed_changes(git_repo: Path):
96+
git_client = GitClient(git_repo)
97+
98+
test_file = git_repo / "model.sql"
99+
test_file.write_text("SELECT 1")
100+
subprocess.run(["git", "add", "model.sql"], cwd=git_repo, check=True, capture_output=True)
101+
subprocess.run(
102+
["git", "commit", "-m", "onitial commit"],
103+
cwd=git_repo,
104+
check=True,
105+
capture_output=True,
106+
)
107+
108+
result = subprocess.run(
109+
["git", "branch", "--show-current"],
110+
cwd=git_repo,
111+
check=True,
112+
capture_output=True,
113+
text=True,
114+
)
115+
default_branch = result.stdout.strip()
116+
117+
subprocess.run(
118+
["git", "checkout", "-b", "feature"],
119+
cwd=git_repo,
120+
check=True,
121+
capture_output=True,
122+
)
123+
124+
test_file.write_text("SELECT 2")
125+
subprocess.run(["git", "add", "model.sql"], cwd=git_repo, check=True, capture_output=True)
126+
subprocess.run(
127+
["git", "commit", "-m", "an update on feature bramch"],
128+
cwd=git_repo,
129+
check=True,
130+
capture_output=True,
131+
)
132+
133+
committed = git_client.list_committed_changed_files(target_branch=default_branch)
134+
assert len(committed) == 1
135+
assert committed[0].name == "model.sql"
136+
137+
assert git_client.list_uncommitted_changed_files() == []

0 commit comments

Comments
 (0)