diff options
| author | Árni Dagur <arni@dagur.eu> | 2020-07-27 20:35:50 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-27 20:35:50 +0000 |
| commit | 25684535e85a8bbb05b65b0da2304273d1d90ca0 (patch) | |
| tree | aad63588ac9eafe99ddd0d3ed847a3726d947271 /tests | |
| parent | dc35e6044c249261dfc46eff831d5885a993eb0f (diff) | |
Update upstream library to 0.3.0, respond to API changes (#10)
* Update upstream library to 0.3.0, respond to API changes
* Change pypi publishing criteria in CI
* Create test to make sure the version numbers are the same everywhere
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_engine.py | 48 | ||||
| -rw-r--r-- | tests/test_typestubs.py | 53 | ||||
| -rw-r--r-- | tests/test_version_numbers.py | 28 |
3 files changed, 116 insertions, 13 deletions
diff --git a/tests/test_engine.py b/tests/test_engine.py index 28e25e6..a3d2898 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py | |||
| @@ -1,40 +1,62 @@ | |||
| 1 | import adblock | 1 | import adblock |
| 2 | import pytest | 2 | import pytest |
| 3 | 3 | ||
| 4 | SMALL_FILTER_LIST = """ | ||
| 5 | ||wikipedia.org^ | ||
| 6 | ||old.reddit.com^ | ||
| 7 | ||lobste.rs^ | ||
| 8 | """ | ||
| 4 | 9 | ||
| 5 | def test_engine_arguments(): | 10 | |
| 6 | # None of these should panic | 11 | def empty_engine(): |
| 7 | adblock.Engine() | 12 | return adblock.Engine(adblock.FilterSet()) |
| 8 | adblock.Engine([]) | 13 | |
| 9 | adblock.Engine(network_filters=None) | 14 | |
| 10 | adblock.Engine(network_filters=[]) | 15 | def test_engine_creation_and_blocking(): |
| 11 | adblock.Engine(load_network=False, load_cosmetic=True, debug=False) | 16 | filter_set = adblock.FilterSet(debug=True) |
| 12 | adblock.Engine(debug=True) | 17 | filter_set.add_filter_list(SMALL_FILTER_LIST) |
| 18 | engine = adblock.Engine(filter_set=filter_set) | ||
| 19 | |||
| 20 | blocker_result_wikipedia = engine.check_network_urls( | ||
| 21 | url="https://wikipedia.org/img.png", | ||
| 22 | source_url="https://google.com/", | ||
| 23 | request_type="image", | ||
| 24 | ) | ||
| 25 | assert isinstance(blocker_result_wikipedia, adblock.BlockerResult) | ||
| 26 | assert blocker_result_wikipedia.matched | ||
| 27 | |||
| 28 | blocker_result_facebook = engine.check_network_urls( | ||
| 29 | "https://facebook.com/directory/img.png", | ||
| 30 | "https://old.reddit.com/r/all", | ||
| 31 | "image", | ||
| 32 | ) | ||
| 33 | assert isinstance(blocker_result_facebook, adblock.BlockerResult) | ||
| 34 | assert not blocker_result_facebook.matched | ||
| 13 | 35 | ||
| 14 | 36 | ||
| 15 | def test_serde_file(tmpdir): | 37 | def test_serde_file(tmpdir): |
| 16 | path = str(tmpdir / "cache.dat") | 38 | path = str(tmpdir / "cache.dat") |
| 17 | 39 | ||
| 18 | engine0 = adblock.Engine() | 40 | engine0 = empty_engine() |
| 19 | with pytest.raises(FileNotFoundError): | 41 | with pytest.raises(FileNotFoundError): |
| 20 | # We haven't created the cache.dat file, so we should get an exception | 42 | # We haven't created the cache.dat file, so we should get an exception |
| 21 | # when attempting to deserialize. | 43 | # when attempting to deserialize. |
| 22 | engine0.deserialize_from_file(path) | 44 | engine0.deserialize_from_file(path) |
| 23 | 45 | ||
| 24 | engine1 = adblock.Engine() | 46 | engine1 = empty_engine() |
| 25 | serialization_result = engine1.serialize_to_file(path) | 47 | serialization_result = engine1.serialize_to_file(path) |
| 26 | assert serialization_result is None | 48 | assert serialization_result is None |
| 27 | 49 | ||
| 28 | engine2 = adblock.Engine() | 50 | engine2 = empty_engine() |
| 29 | deserialization_result = engine2.deserialize_from_file(path) | 51 | deserialization_result = engine2.deserialize_from_file(path) |
| 30 | assert deserialization_result is None | 52 | assert deserialization_result is None |
| 31 | 53 | ||
| 32 | 54 | ||
| 33 | def test_serde(): | 55 | def test_serde(): |
| 34 | engine = adblock.Engine() | 56 | engine = empty_engine() |
| 35 | serialization_result = engine.serialize() | 57 | serialization_result = engine.serialize() |
| 36 | assert isinstance(serialization_result, bytes) | 58 | assert isinstance(serialization_result, bytes) |
| 37 | 59 | ||
| 38 | engine2 = adblock.Engine() | 60 | engine2 = empty_engine() |
| 39 | deserialization_result = engine2.deserialize(serialization_result) | 61 | deserialization_result = engine2.deserialize(serialization_result) |
| 40 | assert deserialization_result is None | 62 | assert deserialization_result is None |
diff --git a/tests/test_typestubs.py b/tests/test_typestubs.py new file mode 100644 index 0000000..6a8d75f --- /dev/null +++ b/tests/test_typestubs.py | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | import ast | ||
| 2 | import re | ||
| 3 | |||
| 4 | |||
| 5 | def read_stubfile(): | ||
| 6 | with open("adblock/adblock.pyi", encoding="utf-8") as file: | ||
| 7 | node = ast.parse(file.read()) | ||
| 8 | return node | ||
| 9 | |||
| 10 | |||
| 11 | def get_functions_and_methods(node): | ||
| 12 | functions = [n for n in node.body if isinstance(n, ast.FunctionDef)] | ||
| 13 | classes = [n for n in node.body if isinstance(n, ast.ClassDef)] | ||
| 14 | |||
| 15 | methods = {} | ||
| 16 | for c in classes: | ||
| 17 | methods[c.name] = [n for n in c.body if isinstance(n, ast.FunctionDef)] | ||
| 18 | |||
| 19 | return functions, methods | ||
| 20 | |||
| 21 | |||
| 22 | def pattern_exists_in_file(filename, regex): | ||
| 23 | """ | ||
| 24 | Checks if the given regex is present in the given file | ||
| 25 | """ | ||
| 26 | with open(filename, "r", encoding="utf-8") as f: | ||
| 27 | for line in f: | ||
| 28 | if re.search(regex, line): | ||
| 29 | return True | ||
| 30 | return False | ||
| 31 | |||
| 32 | |||
| 33 | def test_functions_and_methods_exist_in_rust(): | ||
| 34 | """ | ||
| 35 | Check that for each of the functions and methods present in the Python | ||
| 36 | typestub file, there is a line in `src/lib.rs` containing a matching | ||
| 37 | definition. Since we're doing a naive grep search, without access to the | ||
| 38 | Rust AST, there may be false negatives. | ||
| 39 | """ | ||
| 40 | stubfile_node = read_stubfile() | ||
| 41 | functions, methods = get_functions_and_methods(stubfile_node) | ||
| 42 | |||
| 43 | methods_flattened = [] | ||
| 44 | for class_methods in methods.values(): | ||
| 45 | methods_flattened += class_methods | ||
| 46 | |||
| 47 | for f in functions + methods_flattened: | ||
| 48 | if f.name.startswith("__"): | ||
| 49 | # Skip dunder methods since their names are the same for every | ||
| 50 | # class, making the test not particularly useful. They are also not | ||
| 51 | # marked `pub` in Rust. | ||
| 52 | continue | ||
| 53 | assert pattern_exists_in_file("src/lib.rs", r"pub fn {}".format(f.name)) | ||
diff --git a/tests/test_version_numbers.py b/tests/test_version_numbers.py new file mode 100644 index 0000000..6519ffa --- /dev/null +++ b/tests/test_version_numbers.py | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | import toml | ||
| 2 | import adblock | ||
| 3 | |||
| 4 | |||
| 5 | def get_version_value_poetry(): | ||
| 6 | with open("pyproject.toml", encoding="utf-8") as f: | ||
| 7 | pyproject_toml = toml.loads(f.read()) | ||
| 8 | return pyproject_toml["tool"]["poetry"]["version"] | ||
| 9 | |||
| 10 | |||
| 11 | def get_version_value_cargo(): | ||
| 12 | with open("Cargo.toml", encoding="utf-8") as f: | ||
| 13 | cargo_toml = toml.loads(f.read()) | ||
| 14 | return cargo_toml["package"]["version"] | ||
| 15 | |||
| 16 | |||
| 17 | def test_version_numbers_all_same(): | ||
| 18 | """ | ||
| 19 | Makes sure that `pyproject.toml` and `Cargo.toml` contain the same version | ||
| 20 | number as the one attached to the `adblock` module. | ||
| 21 | """ | ||
| 22 | cargo_version = get_version_value_cargo() | ||
| 23 | poetry_version = get_version_value_poetry() | ||
| 24 | module_version = adblock.__version__ | ||
| 25 | |||
| 26 | assert cargo_version == poetry_version | ||
| 27 | assert poetry_version == module_version | ||
| 28 | assert cargo_version == module_version | ||
