Files
AnyPS5/tools/tests/test_pr_overlap_pages.py
T

95 lines
3.9 KiB
Python

import json
import sys
import threading
import unittest
from pathlib import Path
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import pr_overlap
URL = "repos/owner/project/pulls?state=open&base=main&per_page=100"
def pull(number):
return {"number": number, "user": {"login": f"author{number}"}, "head": {"sha": f"sha{number}"}, "body": None}
def response(numbers, last=None, newline="\r\n"):
headers = ["HTTP/2.0 200 OK", "Content-Type: application/json; charset=utf-8"]
if last:
headers.append(f'Link: <https://api.github.com/repositories/1/pulls?state=open&base=main&per_page=100&page=2>; rel="next", '
f'<https://api.github.com/repositories/1/pulls?state=open&base=main&per_page=100&page={last}>; rel="last"')
return newline.join(headers) + newline + newline + json.dumps([pull(n) for n in numbers])
class ServedPages:
def __init__(self, pages, last):
self.pages = pages
self.last = last
self.requested = []
self.lock = threading.Lock()
def __call__(self, *args):
self.assertion(args)
number = int(args[2].rsplit("&page=", 1)[1])
with self.lock:
self.requested.append(number)
return response(self.pages.get(number, []), self.last if number == 1 else None)
@staticmethod
def assertion(args):
if args[:2] != ("api", "--include") or not args[2].startswith(URL + "&page="):
raise AssertionError(f"unexpected gh call {args}")
class ParallelPageTests(unittest.TestCase):
def open_prs(self, served):
with patch.object(pr_overlap, "REPO", "owner/project", create=True), \
patch.object(pr_overlap, "gh", side_effect=served), \
patch.object(pr_overlap, "progress"):
return pr_overlap.open_prs("main")
def test_every_page_named_by_the_last_link_is_fetched(self):
pages = {1: range(1, 101), 2: range(101, 201), 3: range(201, 251)}
served = ServedPages(pages, last=3)
found = self.open_prs(served)
self.assertEqual(set(found), set(range(1, 251)))
self.assertCountEqual(served.requested, [1, 2, 3])
self.assertEqual(found[250], {"ref": "refs/pr/250", "sha": "sha250", "author": "author250", "depends": set()})
def test_a_single_page_needs_one_request(self):
served = ServedPages({1: range(1, 43)}, last=None)
self.assertEqual(set(self.open_prs(served)), set(range(1, 43)))
self.assertEqual(served.requested, [1])
def test_a_full_last_page_is_followed_by_the_next_one(self):
pages = {1: range(1, 101), 2: range(101, 201), 3: range(201, 202)}
served = ServedPages(pages, last=2)
self.assertEqual(set(self.open_prs(served)), set(range(1, 202)))
self.assertEqual(sorted(served.requested), [1, 2, 3])
def test_a_full_last_page_followed_by_an_empty_one_stops(self):
served = ServedPages({1: range(1, 101), 2: range(101, 201)}, last=2)
self.assertEqual(set(self.open_prs(served)), set(range(1, 201)))
self.assertEqual(sorted(served.requested), [1, 2, 3])
def test_a_pull_request_shifted_onto_two_pages_is_kept_once(self):
served = ServedPages({1: range(1, 101), 2: range(100, 150)}, last=2)
found = self.open_prs(served)
self.assertEqual(len(found), 149)
def test_headers_with_plain_newlines_are_split_from_the_body(self):
with patch.object(pr_overlap, "gh", return_value=response(range(1, 3), newline="\n")):
head, body = pr_overlap.page(URL + "&page=1")
self.assertTrue(head.startswith("HTTP/2.0 200 OK"))
self.assertEqual(body, json.dumps([pull(1), pull(2)]))
def test_a_non_array_page_is_rejected(self):
with self.assertRaisesRegex(ValueError, "non-array page"):
pr_overlap.json_pages('{"message": "Not Found"}')
if __name__ == "__main__":
unittest.main()