Skip to content

Commit 0abd69a

Browse files
authored
Merge pull request #532 from stickperson/three-dot-comparison
2 parents 1d7560e + 7a1270c commit 0abd69a

File tree

6 files changed

+154
-110
lines changed

6 files changed

+154
-110
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ jobs:
116116
contents: write
117117
steps:
118118
- uses: actions/checkout@v4
119+
with:
120+
# New lines are discovered by running a three-dot notation diff on base_ref...head. They must share a common
121+
# ancestor. Setting fetch-depth to 1000 here should ensure that.
122+
fetch-depth: 1000
119123

120124
- name: Install everything, run the tests, produce the .coverage file
121125
run: make test # This is the part where you put your own test command
@@ -205,6 +209,8 @@ jobs:
205209
contents: write
206210
steps:
207211
- uses: actions/checkout@v4
212+
with:
213+
fetch-depth: 1000
208214

209215
- name: Install everything, run the tests, produce the .coverage file
210216
run: make test # This is the part where you put your own test command
@@ -247,6 +253,8 @@ jobs:
247253
248254
steps:
249255
- uses: actions/checkout@v4
256+
with:
257+
fetch-depth: 1000
250258
251259
- name: Set up Python
252260
id: setup-python
@@ -284,6 +292,8 @@ jobs:
284292
contents: write
285293
steps:
286294
- uses: actions/checkout@v4
295+
with:
296+
fetch-depth: 1000
287297

288298
- uses: actions/download-artifact@v4
289299
id: download

coverage_comment/coverage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def get_added_lines(
293293
# don't merge chunks. This means the headers that describe line number
294294
# are always enough to derive what line numbers were added.
295295
git.fetch("origin", base_ref, "--depth=1000")
296-
diff = git.diff("--unified=0", "FETCH_HEAD", "--", ".")
296+
diff = git.diff("--unified=0", "FETCH_HEAD...HEAD")
297297
return parse_diff_output(diff)
298298

299299

tests/integration/conftest.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from __future__ import annotations
2+
3+
import os
4+
import pathlib
5+
import subprocess
6+
import uuid
7+
8+
import pytest
9+
10+
11+
@pytest.fixture
12+
def in_integration_env(integration_env, integration_dir):
13+
curdir = os.getcwd()
14+
os.chdir(integration_dir)
15+
yield integration_dir
16+
os.chdir(curdir)
17+
18+
19+
@pytest.fixture
20+
def integration_dir(tmp_path: pathlib.Path):
21+
test_dir = tmp_path / "integration_test"
22+
test_dir.mkdir()
23+
return test_dir
24+
25+
26+
@pytest.fixture
27+
def file_path(integration_dir):
28+
return integration_dir / "foo.py"
29+
30+
31+
@pytest.fixture
32+
def write_file(file_path):
33+
def _(*variables):
34+
content = "import os"
35+
for i, var in enumerate(variables):
36+
content += f"""\nif os.environ.get("{var}"):\n {i}\n"""
37+
file_path.write_text(content, encoding="utf8")
38+
39+
return _
40+
41+
42+
@pytest.fixture
43+
def run_coverage(file_path, integration_dir):
44+
def _(*variables):
45+
subprocess.check_call(
46+
["coverage", "run", "--parallel", file_path.name],
47+
cwd=integration_dir,
48+
env=os.environ | dict.fromkeys(variables, "1"),
49+
)
50+
51+
return _
52+
53+
54+
@pytest.fixture
55+
def commit(integration_dir):
56+
def _():
57+
subprocess.check_call(
58+
["git", "add", "."],
59+
cwd=integration_dir,
60+
)
61+
subprocess.check_call(
62+
["git", "commit", "-m", str(uuid.uuid4())],
63+
cwd=integration_dir,
64+
env={
65+
"GIT_AUTHOR_NAME": "foo",
66+
"GIT_AUTHOR_EMAIL": "foo",
67+
"GIT_COMMITTER_NAME": "foo",
68+
"GIT_COMMITTER_EMAIL": "foo",
69+
"GIT_CONFIG_GLOBAL": "/dev/null",
70+
"GIT_CONFIG_SYSTEM": "/dev/null",
71+
},
72+
)
73+
74+
return _
75+
76+
77+
@pytest.fixture
78+
def integration_env(integration_dir, write_file, run_coverage, commit, request):
79+
subprocess.check_call(["git", "init", "-b", "main"], cwd=integration_dir)
80+
# diff coverage reads the "origin/{...}" branch so we simulate an origin remote
81+
subprocess.check_call(["git", "remote", "add", "origin", "."], cwd=integration_dir)
82+
write_file("A", "B")
83+
commit()
84+
85+
add_branch_mark = request.node.get_closest_marker("add_branches")
86+
for additional_branch in add_branch_mark.args if add_branch_mark else []:
87+
subprocess.check_call(
88+
["git", "switch", "-c", additional_branch],
89+
cwd=integration_dir,
90+
)
91+
92+
subprocess.check_call(
93+
["git", "switch", "-c", "branch"],
94+
cwd=integration_dir,
95+
)
96+
97+
write_file("A", "B", "C", "D")
98+
commit()
99+
100+
run_coverage("A", "C")
101+
subprocess.check_call(["git", "fetch", "origin"], cwd=integration_dir)

tests/integration/test_coverage.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from __future__ import annotations
2+
3+
import subprocess
4+
5+
from coverage_comment import coverage
6+
from coverage_comment import subprocess as subprocess_module
7+
8+
9+
def test_get_added_lines(
10+
commit, file_path, integration_dir, in_integration_env, write_file
11+
):
12+
"""
13+
Lines added in the base_ref should not appear as added in HEAD
14+
"""
15+
git = subprocess_module.Git()
16+
relative_file_path = file_path.relative_to(integration_dir)
17+
18+
assert coverage.get_added_lines(git, "main") == {
19+
relative_file_path: list(range(7, 13)) # Line numbers start at 1
20+
}
21+
22+
subprocess.check_call(["git", "switch", "main"], cwd=integration_dir)
23+
write_file("E", "F")
24+
commit()
25+
subprocess.check_call(["git", "push", "origin", "main"], cwd=integration_dir)
26+
subprocess.check_call(["git", "switch", "branch"], cwd=integration_dir)
27+
28+
assert coverage.get_added_lines(git, "main") == {
29+
relative_file_path: list(range(7, 13)) # Line numbers start at 1
30+
}

tests/integration/test_main.py

Lines changed: 9 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,12 @@
11
from __future__ import annotations
22

33
import json
4-
import os
54
import pathlib
6-
import subprocess
7-
import uuid
85

96
import pytest
107

118
from coverage_comment import main
129

13-
14-
@pytest.fixture
15-
def in_integration_env(integration_env, integration_dir):
16-
curdir = os.getcwd()
17-
os.chdir(integration_dir)
18-
yield integration_dir
19-
os.chdir(curdir)
20-
21-
22-
@pytest.fixture
23-
def integration_dir(tmp_path: pathlib.Path):
24-
test_dir = tmp_path / "integration_test"
25-
test_dir.mkdir()
26-
return test_dir
27-
28-
29-
@pytest.fixture
30-
def file_path(integration_dir):
31-
return integration_dir / "foo.py"
32-
33-
34-
@pytest.fixture
35-
def write_file(file_path):
36-
def _(*variables):
37-
content = "import os"
38-
for i, var in enumerate(variables):
39-
content += f"""\nif os.environ.get("{var}"):\n {i}\n"""
40-
file_path.write_text(content, encoding="utf8")
41-
42-
return _
43-
44-
45-
@pytest.fixture
46-
def run_coverage(file_path, integration_dir):
47-
def _(*variables):
48-
subprocess.check_call(
49-
["coverage", "run", "--parallel", file_path.name],
50-
cwd=integration_dir,
51-
env=os.environ | dict.fromkeys(variables, "1"),
52-
)
53-
54-
return _
55-
56-
5710
DIFF_STDOUT = """diff --git a/foo.py b/foo.py
5811
index 6c08c94..b65c612 100644
5912
--- a/foo.py
@@ -68,56 +21,6 @@ def _(*variables):
6821
"""
6922

7023

71-
@pytest.fixture
72-
def commit(integration_dir):
73-
def _():
74-
subprocess.check_call(
75-
["git", "add", "."],
76-
cwd=integration_dir,
77-
)
78-
subprocess.check_call(
79-
["git", "commit", "-m", str(uuid.uuid4())],
80-
cwd=integration_dir,
81-
env={
82-
"GIT_AUTHOR_NAME": "foo",
83-
"GIT_AUTHOR_EMAIL": "foo",
84-
"GIT_COMMITTER_NAME": "foo",
85-
"GIT_COMMITTER_EMAIL": "foo",
86-
"GIT_CONFIG_GLOBAL": "/dev/null",
87-
"GIT_CONFIG_SYSTEM": "/dev/null",
88-
},
89-
)
90-
91-
return _
92-
93-
94-
@pytest.fixture
95-
def integration_env(integration_dir, write_file, run_coverage, commit, request):
96-
subprocess.check_call(["git", "init", "-b", "main"], cwd=integration_dir)
97-
# diff coverage reads the "origin/{...}" branch so we simulate an origin remote
98-
subprocess.check_call(["git", "remote", "add", "origin", "."], cwd=integration_dir)
99-
write_file("A", "B")
100-
commit()
101-
102-
add_branch_mark = request.node.get_closest_marker("add_branches")
103-
for additional_branch in add_branch_mark.args if add_branch_mark else []:
104-
subprocess.check_call(
105-
["git", "switch", "-c", additional_branch],
106-
cwd=integration_dir,
107-
)
108-
109-
subprocess.check_call(
110-
["git", "switch", "-c", "branch"],
111-
cwd=integration_dir,
112-
)
113-
114-
write_file("A", "B", "C", "D")
115-
commit()
116-
117-
run_coverage("A", "C")
118-
subprocess.check_call(["git", "fetch", "origin"], cwd=integration_dir)
119-
120-
12124
def test_action__invalid_event_name(session, push_config, in_integration_env, get_logs):
12225
session.register("GET", "/repos/py-cov-action/foobar")(
12326
json={"default_branch": "main", "visibility": "public"}
@@ -172,7 +75,7 @@ def checker(payload):
17275
)(status_code=403)
17376

17477
git.register("git fetch origin main --depth=1000")()
175-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
78+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
17679

17780
result = main.action(
17881
config=pull_request_config(
@@ -253,7 +156,7 @@ def checker(payload):
253156
)(status_code=403)
254157

255158
git.register("git fetch origin foo --depth=1000")(stdout=DIFF_STDOUT)
256-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
159+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
257160

258161
result = main.action(
259162
config=pull_request_config(
@@ -300,7 +203,7 @@ def test_action__pull_request__post_comment(
300203
session.register("GET", "/repos/py-cov-action/foobar/issues/2/comments")(json=[])
301204

302205
git.register("git fetch origin main --depth=1000")()
303-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
206+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
304207

305208
comment = None
306209

@@ -347,7 +250,7 @@ def test_action__push__non_default_branch(
347250
json={"default_branch": "main", "visibility": "public"}
348251
)
349252
git.register("git fetch origin main --depth=1000")(stdout=DIFF_STDOUT)
350-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
253+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
351254

352255
payload = json.dumps({"coverage": 30.00})
353256
# There is an existing badge in this test, allowing to test the coverage evolution
@@ -436,7 +339,7 @@ def test_action__push__non_default_branch__no_pr(
436339
json={"default_branch": "main", "visibility": "public"}
437340
)
438341
git.register("git fetch origin main --depth=1000")(stdout=DIFF_STDOUT)
439-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
342+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
440343

441344
payload = json.dumps({"coverage": 30.00})
442345
# There is an existing badge in this test, allowing to test the coverage evolution
@@ -500,7 +403,7 @@ def test_action__pull_request__force_store_comment(
500403
)(text=payload, headers={"content-type": "application/vnd.github.raw+json"})
501404

502405
git.register("git fetch origin main --depth=1000")()
503-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
406+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
504407

505408
result = main.action(
506409
config=pull_request_config(FORCE_WORKFLOW_RUN=True, GITHUB_OUTPUT=output_file),
@@ -531,7 +434,7 @@ def test_action__pull_request__post_comment__no_marker(
531434
)(status_code=404)
532435

533436
git.register("git fetch origin main --depth=1000")()
534-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
437+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
535438

536439
result = main.action(
537440
config=pull_request_config(COMMENT_TEMPLATE="""foo"""),
@@ -556,7 +459,7 @@ def test_action__pull_request__annotations(
556459
)(status_code=404)
557460

558461
git.register("git fetch origin main --depth=1000")()
559-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
462+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
560463

561464
# Who am I
562465
session.register("GET", "/user")(json={"login": "foo"})
@@ -598,7 +501,7 @@ def test_action__pull_request__post_comment__template_error(
598501
)(status_code=404)
599502

600503
git.register("git fetch origin main --depth=1000")()
601-
git.register("git diff --unified=0 FETCH_HEAD -- .")(stdout=DIFF_STDOUT)
504+
git.register("git diff --unified=0 FETCH_HEAD...HEAD")(stdout=DIFF_STDOUT)
602505

603506
result = main.action(
604507
config=pull_request_config(COMMENT_TEMPLATE="""{%"""),

0 commit comments

Comments
 (0)