|
6 | 6 |
|
7 | 7 | # pyre-unsafe |
8 | 8 |
|
9 | | -import os |
10 | 9 | import random |
11 | 10 | import re |
12 | 11 | import shutil |
13 | 12 | import tempfile |
14 | 13 | import unittest |
15 | 14 | from dataclasses import dataclass, field |
16 | 15 | from datetime import datetime |
17 | | -from typing import Any, Dict, List |
| 16 | +from typing import Any, Dict, List, Optional |
18 | 17 | from unittest.mock import MagicMock, patch |
19 | 18 |
|
20 | 19 | import git |
|
35 | 34 | EmailBodyContext, |
36 | 35 | furnish_ci_email_body, |
37 | 36 | parse_pr_ref, |
| 37 | + prs_for_the_same_series, |
38 | 38 | same_series_different_target, |
39 | 39 | temporary_patch_file, |
40 | 40 | UPSTREAM_REMOTE_NAME, |
@@ -892,6 +892,43 @@ def test_same_series_different_target(self) -> None: |
892 | 892 | ) |
893 | 893 | ) |
894 | 894 |
|
| 895 | + def test_prs_for_the_same_series(self) -> None: |
| 896 | + def create_mock_pr(title: Optional[str], head_ref: str) -> MagicMock: |
| 897 | + pr = MagicMock() |
| 898 | + pr.title = title |
| 899 | + pr.head.ref = head_ref |
| 900 | + return pr |
| 901 | + |
| 902 | + with self.subTest("same_title_different_series"): |
| 903 | + # Title match should return True regardless of series |
| 904 | + pr1 = create_mock_pr("Fix memory leak", "series/123=>main") |
| 905 | + pr2 = create_mock_pr("Fix memory leak", "series/456=>bpf-next") |
| 906 | + self.assertTrue(prs_for_the_same_series(pr1, pr2)) |
| 907 | + |
| 908 | + with self.subTest("different_title_same_series_different_target"): |
| 909 | + # Same series, different target should return True regardless of title |
| 910 | + pr1 = create_mock_pr("Fix memory leak", "series/123=>main") |
| 911 | + pr2 = create_mock_pr("Different title", "series/123=>bpf-next") |
| 912 | + self.assertTrue(prs_for_the_same_series(pr1, pr2)) |
| 913 | + |
| 914 | + with self.subTest("different_title_different_series"): |
| 915 | + # No match |
| 916 | + pr1 = create_mock_pr("Fix memory leak", "series/123=>main") |
| 917 | + pr2 = create_mock_pr("Different title", "series/456=>main") |
| 918 | + self.assertFalse(prs_for_the_same_series(pr1, pr2)) |
| 919 | + |
| 920 | + with self.subTest("none_vs_string_title"): |
| 921 | + # None vs string title should not match |
| 922 | + pr1 = create_mock_pr(None, "series/123=>main") |
| 923 | + pr2 = create_mock_pr("Fix memory leak", "series/456=>bpf-next") |
| 924 | + self.assertFalse(prs_for_the_same_series(pr1, pr2)) |
| 925 | + |
| 926 | + with self.subTest("malformed_refs_no_match"): |
| 927 | + # Malformed refs with different titles should return False |
| 928 | + pr1 = create_mock_pr("Fix memory leak", "invalid-ref-format") |
| 929 | + pr2 = create_mock_pr("Different title", "also-invalid") |
| 930 | + self.assertFalse(prs_for_the_same_series(pr1, pr2)) |
| 931 | + |
895 | 932 |
|
896 | 933 | class TestGitSeriesAlreadyApplied(unittest.IsolatedAsyncioTestCase): |
897 | 934 | def setUp(self): |
|
0 commit comments