33import datetime
44
55import pandas as pd
6+ import pytest
67
7- from github_activity .github_activity import generate_activity_md
8+ from github_activity .github_activity import generate_activity_md , get_activity
89
910
10- def _pr_row (number , title , closed_at , labels = None , created_at = None , merge_oid = None ):
11+ def _pr_row (number , title , closed_at ):
1112 return {
1213 "id" : f"PR_{ number } " ,
1314 "title" : title ,
@@ -22,98 +23,109 @@ def _pr_row(number, title, closed_at, labels=None, created_at=None, merge_oid=No
2223 "committers" : ["manics" ],
2324 "reviewers" : [],
2425 "comments" : {"edges" : []},
25- "labels" : labels or [],
26+ "labels" : [],
2627 "closedAt" : closed_at ,
27- "createdAt" : created_at or "2022-08-20T10:00:00Z" ,
28- "mergeCommit" : {"oid" : merge_oid or f"sha{ number } " },
28+ "createdAt" : "2022-08-20T10:00:00Z" ,
29+ "mergeCommit" : {"oid" : f"sha{ number } " },
2930 "baseRefName" : "master" ,
3031 }
3132
3233
33- def _activity_frame (rows , since_dt , until_dt , since_is_git_ref , until_is_git_ref = False ):
34- data = pd .DataFrame (rows )
35- data .since_dt = since_dt
36- data .until_dt = until_dt
37- data .since_dt_str = f"{ since_dt :%Y-%m-%dT%H:%M:%SZ} "
38- data .until_dt_str = f"{ until_dt :%Y-%m-%dT%H:%M:%SZ} "
39- data .since_is_git_ref = since_is_git_ref
40- data .until_is_git_ref = until_is_git_ref
41- data .attrs ["bot_users" ] = set ()
42- return data
34+ def _mock_get_activity_dependencies (
35+ monkeypatch ,
36+ rows ,
37+ since_dt ,
38+ until_dt ,
39+ since_is_git_ref ,
40+ ):
41+ datetime_results = iter (
42+ [
43+ (since_dt , since_is_git_ref ),
44+ (until_dt , False ),
45+ ]
46+ )
47+ monkeypatch .setattr (
48+ "github_activity.github_activity._get_datetime_and_type" ,
49+ lambda * args , ** kwargs : next (datetime_results ),
50+ )
51+ monkeypatch .setattr (
52+ "github_activity.github_activity._validate_repository_exists" ,
53+ lambda * args , ** kwargs : None ,
54+ )
4355
56+ class FakeGitHubGraphQlQuery :
57+ def __init__ (self , * args , ** kwargs ):
58+ self .data = pd .DataFrame (rows )
59+ self .data .attrs ["bot_users" ] = set ()
4460
45- def test_git_ref_since_excludes_pr_closed_at_tag (monkeypatch ):
46- """A PR whose merge commit is the --since tag must not appear in the changelog.
61+ request = lambda self : None # noqa: E731
4762
48- GitHub compare `tag...HEAD` is exclusive of the tag. Matching that window
49- means a PR closed at the tagged commit's timestamp belongs to the previous
50- release. Regression for executablebooks/github-activity#79.
51- """
52- since_dt = datetime .datetime (2022 , 8 , 21 , 13 , 29 , 31 , tzinfo = datetime .timezone .utc )
53- until_dt = datetime .datetime (2022 , 11 , 15 , 19 , 11 , 20 , tzinfo = datetime .timezone .utc )
54- data = _activity_frame (
55- [
56- _pr_row (
57- 72 ,
58- "Earlier same-day PR" ,
59- "2022-08-21T10:00:00Z" ,
60- labels = ["bug" ],
61- ),
62- _pr_row (
63- 73 ,
64- "Calico 3.24.0 (3.23 manifest URL is broken)" ,
65- "2022-08-21T13:29:31Z" ,
66- labels = ["bug" ],
67- merge_oid = "d3c165a02b1c75b6e551da97970eecb401269750" ,
68- ),
69- _pr_row (
70- 74 ,
71- "Add RELEASE.md" ,
72- "2022-08-21T15:22:38Z" ,
73- ),
74- ],
75- since_dt ,
76- until_dt ,
77- since_is_git_ref = True ,
78- until_is_git_ref = True ,
79- )
8063 monkeypatch .setattr (
81- "github_activity.github_activity.get_activity" , lambda * args , ** kwargs : data
64+ "github_activity.github_activity.GitHubGraphQlQuery" ,
65+ FakeGitHubGraphQlQuery ,
8266 )
8367
84- md = generate_activity_md (
68+
69+ @pytest .mark .parametrize ("api" , [get_activity , generate_activity_md ])
70+ @pytest .mark .parametrize (
71+ "since,since_dt,since_is_git_ref,expected" ,
72+ [
73+ ("v3.0.5" , "2022-08-21T13:29:31+00:00" , True , [74 ]),
74+ ("2022-08-21" , "2022-08-21T00:00:00+00:00" , False , [73 , 74 ]),
75+ ],
76+ ids = ["git-ref-exclusive" , "date-inclusive" ],
77+ )
78+ def test_activity_window (monkeypatch , api , since , since_dt , since_is_git_ref , expected ):
79+ """Both APIs exclude a git-ref boundary but include a date boundary (#79)."""
80+ since_dt = datetime .datetime .fromisoformat (since_dt )
81+ until_dt = datetime .datetime (2022 , 11 , 15 , 19 , 11 , 20 , tzinfo = datetime .timezone .utc )
82+ rows = [
83+ _pr_row (
84+ number ,
85+ title ,
86+ f"{ since_dt + datetime .timedelta (hours = offset ):%Y-%m-%dT%H:%M:%SZ} " ,
87+ )
88+ for number , title , offset in [
89+ (72 , "Closed before boundary" , - 1 ),
90+ (73 , "Closed at boundary" , 0 ),
91+ (74 , "Closed after boundary" , 1 ),
92+ ]
93+ ]
94+ _mock_get_activity_dependencies (
95+ monkeypatch , rows , since_dt , until_dt , since_is_git_ref
96+ )
97+
98+ result = api (
8599 target = "jupyterhub/action-k3s-helm" ,
86- since = "v3.0.5" ,
87- until = "v3.0.6" ,
100+ since = since ,
101+ until = "2022-11-15T19:11:20Z" ,
102+ auth = "test-token" ,
88103 )
89104
90- assert "[#73]" not in md
91- assert "[#72]" not in md
92- assert "[#74]" in md
105+ if api is get_activity :
106+ assert result ["number" ].tolist () == expected
107+ else :
108+ for number in [72 , 73 , 74 ]:
109+ assert (f"[#{ number } ]" in result ) == (number in expected )
93110
94111
95- def test_date_since_still_includes_prs_at_window_start (monkeypatch ):
96- """A calendar-date --since remains inclusive of activity at that instant."""
97- since_dt = datetime .datetime (2022 , 8 , 21 , 0 , 0 , 0 , tzinfo = datetime .timezone .utc )
98- until_dt = datetime .datetime (2022 , 8 , 22 , 0 , 0 , 0 , tzinfo = datetime .timezone .utc )
99- data = _activity_frame (
100- [
101- _pr_row (73 , "Closed at start of since date" , "2022-08-21T00:00:00Z" ),
102- _pr_row (74 , "Closed later the same day" , "2022-08-21T15:22:38Z" ),
103- ],
104- since_dt ,
105- until_dt ,
106- since_is_git_ref = False ,
107- )
108- monkeypatch .setattr (
109- "github_activity.github_activity.get_activity" , lambda * args , ** kwargs : data
112+ @pytest .mark .parametrize ("api" , [get_activity , generate_activity_md ])
113+ def test_empty_activity (monkeypatch , api ):
114+ """Empty searches return an empty frame or the intended Markdown error."""
115+ since_dt = datetime .datetime (2022 , 8 , 21 , tzinfo = datetime .timezone .utc )
116+ until_dt = datetime .datetime (2022 , 8 , 22 , tzinfo = datetime .timezone .utc )
117+ _mock_get_activity_dependencies (
118+ monkeypatch , [], since_dt , until_dt , since_is_git_ref = False
110119 )
111-
112- md = generate_activity_md (
120+ kwargs = dict (
113121 target = "jupyterhub/action-k3s-helm" ,
114122 since = "2022-08-21" ,
115123 until = "2022-08-22" ,
124+ auth = "test-token" ,
116125 )
117126
118- assert "[#73]" in md
119- assert "[#74]" in md
127+ if api is get_activity :
128+ assert api (** kwargs ).empty
129+ else :
130+ with pytest .raises (ValueError , match = "No activity found" ):
131+ api (** kwargs )
0 commit comments