Skip to content

Commit db42ac2

Browse files
Copilotzkoppert
andcommitted
Fix label metrics overcounting bug and add comprehensive tests
Co-authored-by: zkoppert <[email protected]>
1 parent d3a08b8 commit db42ac2

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

labels.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,14 @@ def get_label_metrics(issue: github3.issues.Issue, labels: List[str]) -> dict:
8585
if label in labeled:
8686
# if the issue is closed, add the time from the issue creation to the closed_at time
8787
if issue.state == "closed":
88+
# Only add the final (closed_at - created_at) span if the label was still applied at closure.
89+
if label_last_event_type.get(label) != "labeled":
90+
continue
8891
label_metrics[label] += datetime.fromisoformat(
8992
issue.closed_at
9093
) - datetime.fromisoformat(issue.created_at)
9194
else:
92-
# skip label if last labeling event is 'unlabled' and issue is still open
95+
# skip label if last labeling event is 'unlabeled' and issue is still open
9396
if label_last_event_type[label] == "unlabeled":
9497
continue
9598

test_labels.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,69 @@ def test_get_label_metrics_closed_issue_labeled_past_closed_at(self):
9393
metrics = get_label_metrics(self.issue, labels)
9494
self.assertEqual(metrics["foo"], None)
9595

96+
def test_get_label_metrics_closed_issue_label_removed_before_closure(self):
97+
"""Test get_label_metrics for a closed issue where label was removed before closure"""
98+
# Create a mock issue that reproduces the problem scenario:
99+
# Issue created: day 0 (2021-01-01)
100+
# Label added: day 5 (2021-01-06)
101+
# Label removed: day 10 (2021-01-11)
102+
# Issue closed: day 15 (2021-01-16)
103+
# Expected duration: 5 days (from day 5 to day 10)
104+
105+
issue = MagicMock()
106+
issue.issue = MagicMock(spec=github3.issues.Issue)
107+
issue.created_at = "2021-01-01T00:00:00Z"
108+
issue.closed_at = "2021-01-16T00:00:00Z" # 15 days after creation
109+
issue.state = "closed"
110+
issue.issue.events.return_value = [
111+
MagicMock(
112+
event="labeled",
113+
label={"name": "test-label"},
114+
created_at=datetime(2021, 1, 6, tzinfo=pytz.UTC), # day 5
115+
),
116+
MagicMock(
117+
event="unlabeled",
118+
label={"name": "test-label"},
119+
created_at=datetime(2021, 1, 11, tzinfo=pytz.UTC), # day 10
120+
),
121+
]
122+
123+
labels = ["test-label"]
124+
metrics = get_label_metrics(issue, labels)
125+
126+
# Should be 5 days (from day 5 to day 10), not 15 days (full issue duration)
127+
expected_duration = timedelta(days=5)
128+
self.assertEqual(metrics["test-label"], expected_duration)
129+
130+
def test_get_label_metrics_closed_issue_label_remains_through_closure(self):
131+
"""Test get_label_metrics for a closed issue where label remains applied through closure"""
132+
# Test scenario where label is applied and never removed:
133+
# Issue created: day 0 (2021-01-01)
134+
# Label added: day 2 (2021-01-03)
135+
# Issue closed: day 10 (2021-01-11)
136+
# Expected duration: 10 days (from issue creation to closure)
137+
138+
issue = MagicMock()
139+
issue.issue = MagicMock(spec=github3.issues.Issue)
140+
issue.created_at = "2021-01-01T00:00:00Z"
141+
issue.closed_at = "2021-01-11T00:00:00Z" # 10 days after creation
142+
issue.state = "closed"
143+
issue.issue.events.return_value = [
144+
MagicMock(
145+
event="labeled",
146+
label={"name": "stays-applied"},
147+
created_at=datetime(2021, 1, 3, tzinfo=pytz.UTC), # day 2
148+
),
149+
# No unlabel event - label remains applied
150+
]
151+
152+
labels = ["stays-applied"]
153+
metrics = get_label_metrics(issue, labels)
154+
155+
# Should be 8 days (from day 2 when label was applied to day 10 when issue closed)
156+
expected_duration = timedelta(days=8)
157+
self.assertEqual(metrics["stays-applied"], expected_duration)
158+
96159

97160
class TestGetAverageTimeInLabels(unittest.TestCase):
98161
"""Unit tests for get_stats_time_in_labels"""

0 commit comments

Comments
 (0)