From 25684535e85a8bbb05b65b0da2304273d1d90ca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81rni=20Dagur?= Date: Mon, 27 Jul 2020 20:35:50 +0000 Subject: 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 --- tests/test_engine.py | 48 ++++++++++++++++++++++++++++----------- tests/test_typestubs.py | 53 +++++++++++++++++++++++++++++++++++++++++++ tests/test_version_numbers.py | 28 +++++++++++++++++++++++ 3 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 tests/test_typestubs.py create mode 100644 tests/test_version_numbers.py (limited to 'tests') 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 @@ import adblock import pytest +SMALL_FILTER_LIST = """ +||wikipedia.org^ +||old.reddit.com^ +||lobste.rs^ +""" -def test_engine_arguments(): - # None of these should panic - adblock.Engine() - adblock.Engine([]) - adblock.Engine(network_filters=None) - adblock.Engine(network_filters=[]) - adblock.Engine(load_network=False, load_cosmetic=True, debug=False) - adblock.Engine(debug=True) + +def empty_engine(): + return adblock.Engine(adblock.FilterSet()) + + +def test_engine_creation_and_blocking(): + filter_set = adblock.FilterSet(debug=True) + filter_set.add_filter_list(SMALL_FILTER_LIST) + engine = adblock.Engine(filter_set=filter_set) + + blocker_result_wikipedia = engine.check_network_urls( + url="https://wikipedia.org/img.png", + source_url="https://google.com/", + request_type="image", + ) + assert isinstance(blocker_result_wikipedia, adblock.BlockerResult) + assert blocker_result_wikipedia.matched + + blocker_result_facebook = engine.check_network_urls( + "https://facebook.com/directory/img.png", + "https://old.reddit.com/r/all", + "image", + ) + assert isinstance(blocker_result_facebook, adblock.BlockerResult) + assert not blocker_result_facebook.matched def test_serde_file(tmpdir): path = str(tmpdir / "cache.dat") - engine0 = adblock.Engine() + engine0 = empty_engine() with pytest.raises(FileNotFoundError): # We haven't created the cache.dat file, so we should get an exception # when attempting to deserialize. engine0.deserialize_from_file(path) - engine1 = adblock.Engine() + engine1 = empty_engine() serialization_result = engine1.serialize_to_file(path) assert serialization_result is None - engine2 = adblock.Engine() + engine2 = empty_engine() deserialization_result = engine2.deserialize_from_file(path) assert deserialization_result is None def test_serde(): - engine = adblock.Engine() + engine = empty_engine() serialization_result = engine.serialize() assert isinstance(serialization_result, bytes) - engine2 = adblock.Engine() + engine2 = empty_engine() deserialization_result = engine2.deserialize(serialization_result) 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 @@ +import ast +import re + + +def read_stubfile(): + with open("adblock/adblock.pyi", encoding="utf-8") as file: + node = ast.parse(file.read()) + return node + + +def get_functions_and_methods(node): + functions = [n for n in node.body if isinstance(n, ast.FunctionDef)] + classes = [n for n in node.body if isinstance(n, ast.ClassDef)] + + methods = {} + for c in classes: + methods[c.name] = [n for n in c.body if isinstance(n, ast.FunctionDef)] + + return functions, methods + + +def pattern_exists_in_file(filename, regex): + """ + Checks if the given regex is present in the given file + """ + with open(filename, "r", encoding="utf-8") as f: + for line in f: + if re.search(regex, line): + return True + return False + + +def test_functions_and_methods_exist_in_rust(): + """ + Check that for each of the functions and methods present in the Python + typestub file, there is a line in `src/lib.rs` containing a matching + definition. Since we're doing a naive grep search, without access to the + Rust AST, there may be false negatives. + """ + stubfile_node = read_stubfile() + functions, methods = get_functions_and_methods(stubfile_node) + + methods_flattened = [] + for class_methods in methods.values(): + methods_flattened += class_methods + + for f in functions + methods_flattened: + if f.name.startswith("__"): + # Skip dunder methods since their names are the same for every + # class, making the test not particularly useful. They are also not + # marked `pub` in Rust. + continue + 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 @@ +import toml +import adblock + + +def get_version_value_poetry(): + with open("pyproject.toml", encoding="utf-8") as f: + pyproject_toml = toml.loads(f.read()) + return pyproject_toml["tool"]["poetry"]["version"] + + +def get_version_value_cargo(): + with open("Cargo.toml", encoding="utf-8") as f: + cargo_toml = toml.loads(f.read()) + return cargo_toml["package"]["version"] + + +def test_version_numbers_all_same(): + """ + Makes sure that `pyproject.toml` and `Cargo.toml` contain the same version + number as the one attached to the `adblock` module. + """ + cargo_version = get_version_value_cargo() + poetry_version = get_version_value_poetry() + module_version = adblock.__version__ + + assert cargo_version == poetry_version + assert poetry_version == module_version + assert cargo_version == module_version -- cgit v1.2.3