|
4 | 4 | import pytest |
5 | 5 |
|
6 | 6 | from yarl import URL |
| 7 | +from yarl._path import normalize_path |
7 | 8 |
|
8 | 9 | _WHATWG_C0_CONTROL_OR_SPACE = ( |
9 | 10 | "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10" |
@@ -994,6 +995,91 @@ def test_div_with_dots() -> None: |
994 | 995 | assert url.raw_path == "/path/to" |
995 | 996 |
|
996 | 997 |
|
| 998 | +# relative_to |
| 999 | + |
| 1000 | + |
| 1001 | +@pytest.mark.parametrize( |
| 1002 | + ("target", "base", "expected"), |
| 1003 | + [ |
| 1004 | + ("http://example.com/path/to", "http://example.com/", "path/to"), |
| 1005 | + ("http://example.com/path/to", "http://example.com/spam", "../path/to"), |
| 1006 | + ("http://example.com/path/to", "http://example.com/spam/", "../path/to"), |
| 1007 | + ("http://example.com/this/is/a/test", "http://example.com/this/", "is/a/test"), |
| 1008 | + ( |
| 1009 | + "http://example.com/this/./is/a/test", |
| 1010 | + "http://example.com/this/", |
| 1011 | + "is/a/test", |
| 1012 | + ), |
| 1013 | + ( |
| 1014 | + "http://example.com/////path/////to", |
| 1015 | + "http://example.com/////spam", |
| 1016 | + "../path/////to", |
| 1017 | + ), |
| 1018 | + ( |
| 1019 | + "http://example.com////path/////to", |
| 1020 | + "http://example.com/////spam", |
| 1021 | + "../../path/////to", |
| 1022 | + ), |
| 1023 | + ( |
| 1024 | + "http://example.com/this/is/../a//test", |
| 1025 | + "http://example.com/this/", |
| 1026 | + "a//test", |
| 1027 | + ), |
| 1028 | + ("http://example.com/", "http://example.com/", "."), |
| 1029 | + ("http://example.com", "http://example.com", "."), |
| 1030 | + ("http://example.com/", "http://example.com", "."), |
| 1031 | + ("http://example.com", "http://example.com/", "."), |
| 1032 | + ("//example.com", "//example.com", "."), |
| 1033 | + ("/path/to", "/spam/", "../path/to"), |
| 1034 | + ("path/to", "spam/", "../path/to"), |
| 1035 | + ( |
| 1036 | + "http://example.com/path/to//", |
| 1037 | + "http://example.com/path/to", |
| 1038 | + ".//", |
| 1039 | + ), |
| 1040 | + ( |
| 1041 | + "http://example.com/path/to//", |
| 1042 | + "http://example.com/path/to/", |
| 1043 | + ".//", |
| 1044 | + ), |
| 1045 | + ("path/../to", "path/", "../to"), |
| 1046 | + ("path/..", ".", "../path/.."), |
| 1047 | + ("path/../replace/me", "path/../replace", "me"), |
| 1048 | + ("path/../replace/me", "path/../replace/", "me"), |
| 1049 | + ("path/to", "spam", "../path/to"), |
| 1050 | + ("..", ".", "../.."), |
| 1051 | + (".", "..", "../."), |
| 1052 | + ], |
| 1053 | +) |
| 1054 | +def test_relative_to(target: str, base: str, expected: str) -> None: |
| 1055 | + # test the input data |
| 1056 | + target_url = URL(target) |
| 1057 | + base_url = URL(base) |
| 1058 | + assert normalize_path(target_url.path) == normalize_path((base_url / expected).path) |
| 1059 | + # test the function itself |
| 1060 | + expected_url = URL(expected) |
| 1061 | + relative_url = target_url.relative_to(base_url) |
| 1062 | + assert relative_url == expected_url |
| 1063 | + |
| 1064 | + |
| 1065 | +def test_relative_to_a_non_url() -> None: |
| 1066 | + expected_error_msg = r"^other should be URL$" |
| 1067 | + with pytest.raises(TypeError, match=expected_error_msg): |
| 1068 | + URL("https://example.com/path/to").relative_to("http://example.com/") |
| 1069 | + |
| 1070 | + |
| 1071 | +def test_relative_to_with_different_schemes() -> None: |
| 1072 | + expected_error_msg = r"^Both URLs should have the same scheme$" |
| 1073 | + with pytest.raises(ValueError, match=expected_error_msg): |
| 1074 | + URL("http://example.com/").relative_to(URL("https://example.com/")) |
| 1075 | + |
| 1076 | + |
| 1077 | +def test_relative_to_with_different_netlocs() -> None: |
| 1078 | + expected_error_msg = r"^Both URLs should have the same netloc$" |
| 1079 | + with pytest.raises(ValueError, match=expected_error_msg): |
| 1080 | + URL("https://spam.com/").relative_to(URL("https://ham.com/")) |
| 1081 | + |
| 1082 | + |
997 | 1083 | # joinpath |
998 | 1084 |
|
999 | 1085 |
|
|
0 commit comments