Skip to content

Commit d056b9b

Browse files
committed
[fdiff.diff] add handling for unified diff URL request exceptions, non-200 response code status
1 parent 9162979 commit d056b9b

File tree

2 files changed

+84
-8
lines changed

2 files changed

+84
-8
lines changed

lib/fdiff/diff.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
from fontTools.ttLib import TTFont
66

7+
from fdiff.exceptions import AIOError
78
from fdiff.remote import (
89
_get_filepath_from_url,
910
create_async_get_request_session_and_run,
1011
)
11-
from fdiff.utils import get_file_modtime
1212
from fdiff.thirdparty.fdifflib import unified_diff
13+
from fdiff.utils import get_file_modtime
1314

1415

1516
def u_diff(
@@ -18,8 +19,8 @@ def u_diff(
1819
"""Performs a unified diff on a TTX serialized data format dump of font binary data using
1920
a modified version of the Python standard libary difflib module.
2021
21-
filepath_a: (string) pre-file path
22-
filepath_b: (string) post-file path
22+
filepath_a: (string) pre-file local file path or URL path
23+
filepath_b: (string) post-file local file path or URL path
2324
context_lines: (int) number of context lines to include in the diff (default=3)
2425
include_tables: (list of str) Python list of OpenType tables to include in the diff
2526
exclude_tables: (list of str) Python list of OpentType tables to exclude from the diff
@@ -29,7 +30,10 @@ def u_diff(
2930
3031
:returns: Generator of ordered diff line strings that include newline line endings
3132
:raises: KeyError if include_tables or exclude_tables includes a mis-specified table
32-
that is not included in filepath_a OR filepath_b"""
33+
that is not included in filepath_a OR filepath_b
34+
:raises: fdiff.exceptions.AIOError if exception raised during execution of async I/O
35+
GET request for URL or file write
36+
:raises: fdiff.exceptions.AIOError if GET request to URL returned non-200 response status code"""
3337
with tempfile.TemporaryDirectory() as tmpdirname:
3438
# define the file paths with either local file requests
3539
# or pulls of remote files based on the command line request
@@ -62,12 +66,14 @@ def u_diff(
6266
if task.exception():
6367
# raise exception here to notify calling code that something
6468
# did not work
65-
# TODO: handle exceptions
66-
pass
69+
raise AIOError(f"{task.exception()}")
6770
elif task.result().http_status != 200:
68-
# TODO: handle non-200 HTTP response status codes + file write fails
69-
pass
71+
# handle non-200 HTTP response status codes + file write fails
72+
raise AIOError(
73+
f"failed to pull '{task.result().url}' with HTTP status code {task.result().http_status}"
74+
)
7075

76+
# instantiate left and right fontTools.ttLib.TTFont objects
7177
tt_left = TTFont(prepath)
7278
tt_right = TTFont(postpath)
7379

tests/test_diff.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44

55
from fdiff.diff import u_diff
6+
from fdiff.exceptions import AIOError
67

78
ROBOTO_BEFORE_PATH = os.path.join("tests", "testfiles", "Roboto-Regular.subset1.ttf")
89
ROBOTO_AFTER_PATH = os.path.join("tests", "testfiles", "Roboto-Regular.subset2.ttf")
@@ -13,6 +14,11 @@
1314
ROBOTO_UDIFF_HEADPOSTONLY_EXPECTED_PATH = os.path.join("tests", "testfiles", "roboto_udiff_headpostonly_expected.txt")
1415
ROBOTO_UDIFF_EXCLUDE_HEADPOST_EXPECTED_PATH = os.path.join("tests", "testfiles", "roboto_udiff_ex_headpost_expected.txt")
1516

17+
ROBOTO_BEFORE_URL = "https://github.com/source-foundry/fdiff/raw/master/tests/testfiles/Roboto-Regular.subset1.ttf"
18+
ROBOTO_AFTER_URL = "https://github.com/source-foundry/fdiff/raw/master/tests/testfiles/Roboto-Regular.subset2.ttf"
19+
20+
URL_404 = "https://httpbin.org/status/404"
21+
1622
# Setup: define the expected diff text for unified diff
1723
with open(ROBOTO_UDIFF_EXPECTED_PATH, "r") as robo_udiff:
1824
ROBOTO_UDIFF_EXPECTED = robo_udiff.read()
@@ -141,3 +147,67 @@ def test_unified_diff_include_with_bad_table_definition():
141147
def test_unified_diff_exclude_with_bad_table_definition():
142148
with pytest.raises(KeyError):
143149
u_diff(ROBOTO_BEFORE_PATH, ROBOTO_AFTER_PATH, exclude_tables=["bogus"])
150+
151+
152+
def test_unified_diff_remote_fonts():
153+
res = u_diff(ROBOTO_BEFORE_URL, ROBOTO_AFTER_URL)
154+
res_string = "".join(res)
155+
res_string_list = res_string.split("\n")
156+
expected_string_list = ROBOTO_UDIFF_EXPECTED.split("\n")
157+
158+
# have to handle the tests for the top two file path lines
159+
# differently than the rest of the comparisons
160+
for x, line in enumerate(res_string_list):
161+
# treat top two lines of the diff as comparison of first 10 chars only
162+
if x == 0:
163+
assert line[0:9] == "--- https"
164+
elif x == 1:
165+
assert line[0:9] == "+++ https"
166+
else:
167+
assert line == expected_string_list[x]
168+
169+
170+
def test_unified_diff_remote_and_local_fonts():
171+
res = u_diff(ROBOTO_BEFORE_URL, ROBOTO_AFTER_PATH)
172+
res_string = "".join(res)
173+
res_string_list = res_string.split("\n")
174+
expected_string_list = ROBOTO_UDIFF_EXPECTED.split("\n")
175+
176+
# have to handle the tests for the top two file path lines
177+
# differently than the rest of the comparisons
178+
for x, line in enumerate(res_string_list):
179+
# treat top two lines of the diff as comparison of first 10 chars only
180+
if x == 0:
181+
assert line[0:9] == "--- https"
182+
elif x == 1:
183+
assert line[0:9] == expected_string_list[x][0:9]
184+
else:
185+
assert line == expected_string_list[x]
186+
187+
188+
def test_unified_diff_local_and_remote_fonts():
189+
res = u_diff(ROBOTO_BEFORE_PATH, ROBOTO_AFTER_URL)
190+
res_string = "".join(res)
191+
res_string_list = res_string.split("\n")
192+
expected_string_list = ROBOTO_UDIFF_EXPECTED.split("\n")
193+
194+
# have to handle the tests for the top two file path lines
195+
# differently than the rest of the comparisons
196+
for x, line in enumerate(res_string_list):
197+
# treat top two lines of the diff as comparison of first 10 chars only
198+
if x == 0:
199+
assert line[0:9] == expected_string_list[x][0:9]
200+
elif x == 1:
201+
assert line[0:9] == "+++ https"
202+
else:
203+
assert line == expected_string_list[x]
204+
205+
206+
def test_unified_diff_remote_404_first_file():
207+
with pytest.raises(AIOError):
208+
u_diff(URL_404, ROBOTO_AFTER_URL)
209+
210+
211+
def test_unified_diff_remote_404_second_file():
212+
with pytest.raises(AIOError):
213+
u_diff(ROBOTO_BEFORE_URL, URL_404)

0 commit comments

Comments
 (0)