diff --git a/.github/workflows/generator.yml b/.github/workflows/generator.yml index d11ac3b3..2709ab6d 100644 --- a/.github/workflows/generator.yml +++ b/.github/workflows/generator.yml @@ -11,19 +11,14 @@ env: jobs: Build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install - run: | - cd flatdata-generator - # runtime requirements - pip install -r requirements.txt - # CI requirements - pip install nose pylint + - name: Dependencies + uses: astral-sh/setup-uv@v6 - name: Run tests run: | cd flatdata-generator - python -m nose + uv run --with pytest pytest -v pip install . flatdata-generator --help \ No newline at end of file diff --git a/.github/workflows/py.yml b/.github/workflows/py.yml index c63056ea..685671d8 100644 --- a/.github/workflows/py.yml +++ b/.github/workflows/py.yml @@ -11,20 +11,15 @@ env: jobs: Build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Install - run: | - pip install ./flatdata-generator - cd flatdata-py - # runtime requirements - pip install -r requirements.txt - # CI requirements - pip install nose pylint + - name: Dependencies + uses: astral-sh/setup-uv@v6 - name: Run tests run: | cd flatdata-py - python -m nose + uv run --with pytest --with ../flatdata-generator pytest -v pip install . - flatdata-inspector --help \ No newline at end of file + flatdata-inspector --help + diff --git a/flatdata-cpp/ci/Dockerfile b/flatdata-cpp/ci/Dockerfile index 225d62b6..ef051f06 100644 --- a/flatdata-cpp/ci/Dockerfile +++ b/flatdata-cpp/ci/Dockerfile @@ -16,7 +16,7 @@ RUN apk --no-cache add \ breathe \ sphinx \ jinja2 \ - nose \ + pytest \ pandas \ pyparsing diff --git a/flatdata-generator/pyproject.toml b/flatdata-generator/pyproject.toml index f83f8e19..05ddfdae 100644 --- a/flatdata-generator/pyproject.toml +++ b/flatdata-generator/pyproject.toml @@ -33,3 +33,9 @@ include = [ [tool.hatch.build.targets.wheel] packages = ["flatdata"] + +[tool.pytest.ini_options] +testpaths = [ "tests" ] +python_files = [ "test_*.py" ] +python_classes = [ "Test*" ] +python_functions = [ "test_*" ] diff --git a/flatdata-generator/tests/generators/test_cpp_generator.py b/flatdata-generator/tests/generators/test_cpp_generator.py index 0ec25fe9..b95b8219 100644 --- a/flatdata-generator/tests/generators/test_cpp_generator.py +++ b/flatdata-generator/tests/generators/test_cpp_generator.py @@ -1,13 +1,15 @@ ''' - Copyright (c) 2019 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import glob +import pytest from flatdata.generator.generators.cpp import CppGenerator from .assertions import generate_and_assert_in from .schemas import schemas_and_expectations + def generate_and_compare(test_case): with open(test_case[0], 'r') as test_file: test = test_file.read() @@ -19,6 +21,12 @@ def generate_and_compare(test_case): generate_and_assert_in(test, CppGenerator, *expectations) -def test_against_expectations(): +def get_test_cases(): + test_cases = [] for x in schemas_and_expectations(generator='cpp', extension='h'): - yield generate_and_compare, x + test_cases.append(x) + return test_cases + +@pytest.mark.parametrize("case", get_test_cases()) +def test_against_expectations(case): + generate_and_compare(case) diff --git a/flatdata-generator/tests/generators/test_dot_generator.py b/flatdata-generator/tests/generators/test_dot_generator.py index f1f1bc2a..6480bd53 100644 --- a/flatdata-generator/tests/generators/test_dot_generator.py +++ b/flatdata-generator/tests/generators/test_dot_generator.py @@ -1,13 +1,15 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import glob +import pytest from flatdata.generator.generators.dot import DotGenerator from .assertions import generate_and_assert_in from .schemas import schemas_and_expectations + def test_structures_outside_of_archives_are_not_represented(): unexpected_lines = [ "_n_S" @@ -31,6 +33,12 @@ def generate_and_compare(test_case): generate_and_assert_in(test, DotGenerator, *expectations) -def test_against_expectations(): +def get_test_cases(): + test_cases = [] for x in schemas_and_expectations(generator='dot', extension='dot'): - yield generate_and_compare, x \ No newline at end of file + test_cases.append(x) + return test_cases + +@pytest.mark.parametrize("case", get_test_cases()) +def test_against_expectations(case): + generate_and_compare(case) \ No newline at end of file diff --git a/flatdata-generator/tests/generators/test_flatdata_generator.py b/flatdata-generator/tests/generators/test_flatdata_generator.py index ffc9272d..ad28aa67 100644 --- a/flatdata-generator/tests/generators/test_flatdata_generator.py +++ b/flatdata-generator/tests/generators/test_flatdata_generator.py @@ -1,13 +1,14 @@ ''' - Copyright (c) 2018 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' -from nose.tools import assert_equal +import pytest from flatdata.generator.generators.flatdata import FlatdataGenerator from flatdata.generator.tree.builder import build_ast from .schemas import schemas_and_expectations + def generate_and_compare(test_case): with open(test_case[0], 'r') as test_file: test = test_file.read() @@ -15,13 +16,18 @@ def generate_and_compare(test_case): expectation = expectation_file.read() tree = build_ast(definition=test) contents = FlatdataGenerator().render(tree) - assert_equal.__self__.maxDiff = None - assert_equal(expectation, contents, test_case) + assert expectation == contents + +def get_test_cases(): + test_cases = [] + for x in schemas_and_expectations(generator='flatdata', extension='flatdata'): + test_cases.append(x) + return test_cases -def test_against_expectations(): - for i in schemas_and_expectations(generator='flatdata', extension='flatdata'): - yield generate_and_compare, i +@pytest.mark.parametrize("case", get_test_cases()) +def test_against_expectations(case): + generate_and_compare(case) -def test_normalization_is_fixed_point(): - for i in schemas_and_expectations(generator='flatdata', extension='flatdata'): - yield generate_and_compare, (i[1], i[1]) +@pytest.mark.parametrize("case", get_test_cases()) +def test_normalization_is_fixed_point(case): + generate_and_compare((case[1], case[1])) diff --git a/flatdata-generator/tests/generators/test_go_generator.py b/flatdata-generator/tests/generators/test_go_generator.py index aed9485c..23c71d4b 100644 --- a/flatdata-generator/tests/generators/test_go_generator.py +++ b/flatdata-generator/tests/generators/test_go_generator.py @@ -1,15 +1,14 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import glob +import pytest from flatdata.generator.generators.go import GoGenerator from .assertions import generate_and_assert_in from .schemas import schemas_and_expectations -from nose.plugins.skip import SkipTest - def generate_and_compare(test_case): with open(test_case[0], 'r') as test_file: @@ -24,13 +23,18 @@ def generate_and_compare(test_case): def skip(test_case): - raise SkipTest("Test %s is skipped" % test_case[0]) - + raise pytest.skip("Test %s is skipped" % test_case[0]) -def test_against_expectations(): +def get_test_cases(): + test_cases = [] for x in schemas_and_expectations(generator='go', extension='go'): - # Go does not yet support namespaces, enums, ranges, or constants, skip those tests - if "enums" not in x[0] and "constants" not in x[0] and "namespaces" not in x[0] and "ranges" not in x[0]: - yield generate_and_compare, x - else: - yield skip, x + test_cases.append(x) + return test_cases + +@pytest.mark.parametrize("test_case", get_test_cases()) +def test_against_expectations(test_case): + # Go does not yet support namespaces, enums, ranges, or constants, skip those tests + if "enums" not in test_case[0] and "constants" not in test_case[0] and "namespaces" not in test_case[0] and "ranges" not in test_case[0]: + generate_and_compare(test_case) + else: + skip(test_case) diff --git a/flatdata-generator/tests/generators/test_python_generator.py b/flatdata-generator/tests/generators/test_python_generator.py index 26e563fe..c0840cdf 100644 --- a/flatdata-generator/tests/generators/test_python_generator.py +++ b/flatdata-generator/tests/generators/test_python_generator.py @@ -1,14 +1,14 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import glob +import pytest from flatdata.generator.generators.python import PythonGenerator from .assertions import generate_and_assert_in from .schemas import schemas_and_expectations -from nose.plugins.skip import SkipTest def generate_and_compare(test_case): with open(test_case[0], 'r') as test_file: @@ -22,12 +22,18 @@ def generate_and_compare(test_case): generate_and_assert_in(test, PythonGenerator, *expectations) def skip(test_case): - raise SkipTest("Test %s is skipped" % test_case[0]) + raise pytest.skip("Test %s is skipped" % test_case[0]) -def test_against_expectations(): +def get_test_cases(): + test_cases = [] for x in schemas_and_expectations(generator='py', extension='py'): - # Python does not yet support enums or constants, skip those tests - if "enums" not in x[0] and "constants" not in x[0]: - yield generate_and_compare, x - else: - yield skip, x \ No newline at end of file + test_cases.append(x) + return test_cases + +@pytest.mark.parametrize("test_case", get_test_cases()) +def test_against_expectations(test_case): + # Python does not yet support enums or constants, skip those tests + if "enums" not in test_case[0] and "constants" not in test_case[0]: + generate_and_compare(test_case) + else: + skip(test_case) \ No newline at end of file diff --git a/flatdata-generator/tests/generators/test_rust_generator.py b/flatdata-generator/tests/generators/test_rust_generator.py index 08bee924..a59531e5 100644 --- a/flatdata-generator/tests/generators/test_rust_generator.py +++ b/flatdata-generator/tests/generators/test_rust_generator.py @@ -1,30 +1,30 @@ ''' - Copyright (c) 2019 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import glob -from nose.tools import eq_ +import pytest from flatdata.generator.generators.rust import RustGenerator from .assertions import generate_and_assert_in from .schemas import schemas_and_expectations def test_format_numeric_literals(): - eq_(RustGenerator._format_numeric_literal(1), "1") - eq_(RustGenerator._format_numeric_literal(123), "123") - eq_(RustGenerator._format_numeric_literal(-123), "-123") - eq_(RustGenerator._format_numeric_literal(1), "1") - eq_(RustGenerator._format_numeric_literal(10), "10") - eq_(RustGenerator._format_numeric_literal(100), "100") - eq_(RustGenerator._format_numeric_literal(1000), "1_000") - eq_(RustGenerator._format_numeric_literal(10000), "10_000") - eq_(RustGenerator._format_numeric_literal(100000), "100_000") - eq_(RustGenerator._format_numeric_literal(1000000), "1_000_000") - eq_(RustGenerator._format_numeric_literal(-1000000), "-1_000_000") - eq_(RustGenerator._format_numeric_literal(2147483647), "2_147_483_647") - eq_(RustGenerator._format_numeric_literal("hello"), "hello") - eq_(RustGenerator._format_numeric_literal("hello1234"), "hello1234") - eq_(RustGenerator._format_numeric_literal("1234hello"), "1234hello") + assert RustGenerator._format_numeric_literal(1) == "1" + assert RustGenerator._format_numeric_literal(123) == "123" + assert RustGenerator._format_numeric_literal(-123) == "-123" + assert RustGenerator._format_numeric_literal(1) == "1" + assert RustGenerator._format_numeric_literal(10) == "10" + assert RustGenerator._format_numeric_literal(100) == "100" + assert RustGenerator._format_numeric_literal(1000) == "1_000" + assert RustGenerator._format_numeric_literal(10000) == "10_000" + assert RustGenerator._format_numeric_literal(100000) == "100_000" + assert RustGenerator._format_numeric_literal(1000000) == "1_000_000" + assert RustGenerator._format_numeric_literal(-1000000) == "-1_000_000" + assert RustGenerator._format_numeric_literal(2147483647) == "2_147_483_647" + assert RustGenerator._format_numeric_literal("hello") == "hello" + assert RustGenerator._format_numeric_literal("hello1234") == "hello1234" + assert RustGenerator._format_numeric_literal("1234hello") == "1234hello" def generate_and_compare(test_case): with open(test_case[0], 'r') as test_file: @@ -37,6 +37,12 @@ def generate_and_compare(test_case): generate_and_assert_in(test, RustGenerator, *expectations) -def test_against_expectations(): +def get_test_cases(): + test_cases = [] for x in schemas_and_expectations(generator='rust', extension='rs'): - yield generate_and_compare, x + test_cases.append(x) + return test_cases + +@pytest.mark.parametrize("test_case", get_test_cases()) +def test_against_expectations(test_case): + generate_and_compare(test_case) diff --git a/flatdata-generator/tests/tree/test_node.py b/flatdata-generator/tests/tree/test_node.py index 2c18d734..3b1356f1 100644 --- a/flatdata-generator/tests/tree/test_node.py +++ b/flatdata-generator/tests/tree/test_node.py @@ -1,37 +1,37 @@ import sys +import pytest sys.path.insert(0, "..") from flatdata.generator.tree.nodes.node import Node from flatdata.generator.tree.errors import SymbolRedefinition -from nose.tools import assert_equal, assert_is_none, assert_raises def test_nodes_are_named(): v = Node(name="abc") - assert_equal("abc", v.name) + assert "abc" == v.name def test_insertion_returns_parent_node(): n = Node("foo") - assert_equal(n, n.insert(Node("Bar"))) + assert n == n.insert(Node("Bar")) def test_find_child_returns_child_if_found(): n = Node("foo") s = Node("Bar") n.insert(s) - assert_equal("Bar", n.find_relative("Bar").name) + assert "Bar" == n.find_relative("Bar").name def test_find_child_throws_if_not_found(): n = Node("foo") - assert_raises(RuntimeError, n.find_relative, "Bar") + pytest.raises(RuntimeError, n.find_relative, "Bar") def test_set_name_resets_the_node_name(): n = Node("foo") n.set_name("bar") - assert_equal("bar", n.name) + assert "bar" == n.name def test_erase_removes_node_from_the_tree_and_clears_its_parent(): @@ -39,43 +39,43 @@ def test_erase_removes_node_from_the_tree_and_clears_its_parent(): s = Node("Bar") n.insert(s) n.erase("Bar") - assert_raises(RuntimeError, n.find_relative, "Bar") - assert_is_none(s.parent) + pytest.raises(RuntimeError, n.find_relative, "Bar") + assert s.parent == None def test_insertion_works_with_lookup(): n = Node("foo") s = Node("Bar") n.insert(s) - assert_equal("Bar", n.find("foo.Bar").name) + assert "Bar" == n.find("foo.Bar").name def test_lookup_of_nonexistent_symbol_throws(): n = Node("foo") s = Node("Bar") n.insert(s) - assert_raises(RuntimeError, n.find, "baz") + pytest.raises(RuntimeError, n.find, "baz") def test_insertion_of_symbol_with_duplicate_name_trows(): n = Node("foo") s = Node("Bar") n.insert(s) - assert_raises(SymbolRedefinition, n.insert, Node("Bar")) + pytest.raises(SymbolRedefinition, n.insert, Node("Bar")) def test_get_with_default_returns_value_if_found(): n = Node("foo") s = Node("Bar") n.insert(s) - assert_equal(s, n.get("foo.Bar", None)) + assert s == n.get("foo.Bar", None) def test_get_with_default_returns_default_if_not_found(): n = Node("foo") s = Node("Bar") n.insert(s) - assert_is_none(n.get("foo.Baz", None)) + assert n.get("foo.Baz", None) is None def test_reparanting_of_symbol_trows(): @@ -83,41 +83,41 @@ def test_reparanting_of_symbol_trows(): s = Node("Baz") n.insert(s) a = Node("bar") - assert_raises(RuntimeError, a.insert, s) + pytest.raises(RuntimeError, a.insert, s) def test_insertion_returns_self(): n = Node("n") - assert_equal(n, n.insert(Node("S"))) + assert n == n.insert(Node("S")) def test_lookup_by_path(): root = Node("foo") root.insert(Node("bar").insert(Node("baz").insert(Node("Dig")))) - assert_equal("Dig", root.find("foo.bar.baz.Dig").name) + assert "Dig" == root.find("foo.bar.baz.Dig").name def test_node_is_looked_up_by_its_path(): root = Node("foo") s = Node("Dig") root.insert(Node("bar").insert(Node("baz").insert(s))) - assert_equal(s, root.find(s.path)) + assert s == root.find(s.path) def test_children_returns_children(): n = Node("foo") s = Node("Bar") n.insert(s) - assert_equal([s], n.children) + assert [s] == n.children def test_path_of_detached_node_is_just_its_name(): root = Node("foo") - assert_equal("foo", root.path) + assert "foo" == root.path def test_path_contains_fully_path_with(): root = Node("foo") s = Node("Dig") root.insert(Node("bar").insert(Node("baz").insert(s))) - assert_equal("foo.bar.baz.Dig", s.path) + assert "foo.bar.baz.Dig" == s.path diff --git a/flatdata-generator/tests/tree/test_node_tree_builder.py b/flatdata-generator/tests/tree/test_node_tree_builder.py index d74528fa..5bf2a733 100644 --- a/flatdata-generator/tests/tree/test_node_tree_builder.py +++ b/flatdata-generator/tests/tree/test_node_tree_builder.py @@ -1,10 +1,9 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import sys - -from nose.tools import assert_equal, assert_equals, assert_false, assert_in, assert_is_instance, assert_raises, assert_true +import pytest sys.path.insert(0, "..") import flatdata.generator.tree.nodes.trivial as nodes @@ -18,79 +17,79 @@ def check_constant(c, typename, value): - assert_is_instance(c, nodes.Constant) - assert_equals(typename, c.type.name) - assert_is_instance(c.type, BasicType) - assert_equals(value, c.value) + assert isinstance(c, nodes.Constant) + assert typename == c.type.name + assert isinstance(c.type, BasicType) + assert value == c.value def check_field(f, typename, width, offset): - assert_is_instance(f, nodes.Field) - assert_is_instance(f.type, BasicType) - assert_equal(typename, f.type.name) - assert_equal(offset, f.offset) - assert_equal(width, f.type.width) + assert isinstance(f, nodes.Field) + assert isinstance(f.type, BasicType) + assert typename == f.type.name + assert offset == f.offset + assert width == f.type.width def check_struct(s, size_in_bits, size_in_bytes): - assert_is_instance(s, nodes.Structure) - assert_equal(size_in_bits, s.size_in_bits) - assert_equal(size_in_bytes, s.size_in_bytes) + assert isinstance(s, nodes.Structure) + assert size_in_bits == s.size_in_bits + assert size_in_bytes == s.size_in_bytes def check_explicit_reference(r, source_type, source_field, destination): - assert_in("explicit_reference", r) + assert "explicit_reference" in r ref = r.explicit_reference - assert_equal(source_type, ref.source_type) - assert_equal(source_field, ref.source_field) - assert_equal(destination, ref.destination) + assert source_type == ref.source_type + assert source_field == ref.source_field + assert destination == ref.destination def check_bound_resource(b, name, refnames): - assert_is_instance(b, resources.BoundResource) - assert_equal(len(refnames), len(b.children)) - assert_equal(name, b.name) + assert isinstance(b, resources.BoundResource) + assert len(refnames) == len(b.children) + assert name == b.name for i, ref in enumerate(refnames): refnode = b.children[i] - assert_is_instance(refnode, refs.ResourceReference) - assert_equal(ref, refnode.target) + assert isinstance(refnode, refs.ResourceReference) + assert ref == refnode.target def test_empty_schema_returns_none(): tree = _build_node_tree("") - assert_equal(set(), tree.symbols()) + assert set() == tree.symbols() def test_empty_schema_with_namespace_parsed_correctly(): tree = _build_node_tree("namespace foobar{}") root = tree.root - assert_is_instance(root, Root) - assert_is_instance(root.find(".foobar"), nodes.Namespace) + assert isinstance(root, Root) + assert isinstance(root.find(".foobar"), nodes.Namespace) def test_empty_schema_with_nested_namespace_parsed_correctly(): tree = _build_node_tree("namespace foo.bar.baz{}") for path, name in [(".foo", "foo"), (".foo.bar", "bar"), (".foo.bar.baz", "baz")]: node = tree.find(path) - assert_is_instance(node, nodes.Namespace) - assert_equal(name, node.name) - assert_equal(path, node.path) + assert isinstance(node, nodes.Namespace) + assert name == node.name + assert path == node.path def test_structure_without_namespace_trows(): - with assert_raises(ParsingError): + with pytest.raises(ParsingError): _build_node_tree("struct A { item : u32 : 16; }") def test_archive_without_namespace_raises(): - with assert_raises(ParsingError): + with pytest.raises(ParsingError): _build_node_tree("archive A { item : type; }") def test_constants_are_placed_on_final_namespace(): tree = _build_node_tree("""namespace a.b{ const i8 foo = 17;}""") - assert_equal({".a", ".a.b", ".a.b.foo"}, tree.symbols()) - assert_is_instance(tree.find(".a.b.foo"), nodes.Constant) + assert {".a", ".a.b", ".a.b.foo"} == tree.symbols() + assert isinstance(tree.find(".a.b.foo"), nodes.Constant) def test_constants_are_parsed(): @@ -101,7 +100,7 @@ def test_constants_are_parsed(): const u32 bar2 = 19; } """) - assert_equal({".foo", ".foo.bar", ".foo.foo", ".foo.foo2", ".foo.bar2"}, tree.symbols()) + assert {".foo", ".foo.bar", ".foo.foo", ".foo.foo2", ".foo.bar2"} == tree.symbols() check_constant(tree.find(".foo.foo"), "i8", -17) check_constant(tree.find(".foo.bar"), "u16", 0x42) check_constant(tree.find(".foo.foo2"), "i16", -0x20) @@ -109,7 +108,7 @@ def test_constants_are_parsed(): def test_duplicate_constants_raise_syntax_error(): - with assert_raises(SymbolRedefinition): + with pytest.raises(SymbolRedefinition): _build_node_tree("""namespace a{ const i8 foo = 17; const u16 foo = 0x42; @@ -117,7 +116,7 @@ def test_duplicate_constants_raise_syntax_error(): """) def constant_size_check(): - with assert_raises(InvalidConstantValueError): + with pytest.raises(InvalidConstantValueError): _build_node_tree("""namespace a{ const i8 foo = 128; } @@ -132,7 +131,7 @@ def test_single_structure_is_parsed_correctly(): } """) _compute_structure_sizes(tree) - assert_equal({".foo", ".foo.Bar", ".foo.Bar.fieldB", ".foo.Bar.fieldA"}, tree.symbols()) + assert {".foo", ".foo.Bar", ".foo.Bar.fieldB", ".foo.Bar.fieldA"} == tree.symbols() check_struct(tree.find(".foo.Bar"), 35, 5) check_field(tree.find(".foo.Bar.fieldA"), "u8", 2, 0) @@ -140,7 +139,7 @@ def test_single_structure_is_parsed_correctly(): def test_duplicate_structures_raise_syntax_error(): - with assert_raises(SymbolRedefinition): + with pytest.raises(SymbolRedefinition): _build_node_tree("""namespace a{ struct Foo { f : u8 : 2; } struct Foo { d : u32 : 32; } @@ -159,23 +158,12 @@ def test_two_structures_are_parsed_correctly(): } """) _compute_structure_sizes(tree) - assert_equal({".foo", ".foo.Baz", ".foo.Baz.fieldB", ".foo.Bar", ".foo.Bar.fieldA"}, - tree.symbols()) + assert {".foo", ".foo.Baz", ".foo.Baz.fieldB", ".foo.Bar", ".foo.Bar.fieldA"} == tree.symbols() check_struct(tree.find(".foo.Bar"), 2, 1) check_struct(tree.find(".foo.Baz"), 17, 3) - -def test_implicit_field_widths_are_set_correctly(): - def __test(typename, width): - tree = _build_node_tree("""namespace n{ - struct s { - f : %s; - } - } - """ % typename) - _compute_structure_sizes(tree) - check_field(tree.find('.n.s.f'), typename, width, 0) - +def get_test_cases_implicit_field_widths_are_set_correctly(): + test_cases = [] for typename, width in [ ('bool', 1), ('u8', 8), @@ -187,10 +175,37 @@ def __test(typename, width): ('u64', 64), ('i64', 64) ]: - yield __test, typename, width + test_cases.append((typename, width)) + return test_cases + +@pytest.mark.parametrize("test_case", get_test_cases_implicit_field_widths_are_set_correctly()) +def test_implicit_field_widths_are_set_correctly(test_case): + def __test(typename, width): + tree = _build_node_tree("""namespace n{ + struct s { + f : %s; + } + } + """ % typename) + _compute_structure_sizes(tree) + check_field(tree.find('.n.s.f'), typename, width, 0) + + __test(test_case[0], test_case[1]) -def test_archives_resources_references_are_populated(): +def get_test_cases_archives_resources_references_are_populated(): + test_cases = [] + for values in [ + ("T", {".foo.A.resourceA.@T"}), + ("vector< bar.T >", {".foo.A.resourceA.@bar@T"}), + ("multivector< 33, T, foo.T, bar.baz.Boo >", + {".foo.A.resourceA.@T", ".foo.A.resourceA.@foo@T", ".foo.A.resourceA.@bar@baz@Boo"}) + ]: + test_cases.append(values) + return test_cases + +@pytest.mark.parametrize("test_case", get_test_cases_archives_resources_references_are_populated()) +def test_archives_resources_references_are_populated(test_case): def __test(schema, references): tree = _build_node_tree("""namespace foo{ archive A { @@ -198,18 +213,12 @@ def __test(schema, references): } } """ % schema) - assert_equal({".foo", ".foo.A", ".foo.A.resourceA"}.union(references), tree.symbols()) + assert {".foo", ".foo.A", ".foo.A.resourceA"}.union(references) == tree.symbols() for r in references: - assert_is_instance(tree.find(r), refs.TypeReference) + assert isinstance(tree.find(r), refs.TypeReference) - for values in [ - ("T", {".foo.A.resourceA.@T"}), - ("vector< bar.T >", {".foo.A.resourceA.@bar@T"}), - ("multivector< 33, T, foo.T, bar.baz.Boo >", - {".foo.A.resourceA.@T", ".foo.A.resourceA.@foo@T", ".foo.A.resourceA.@bar@baz@Boo"}) - ]: - yield __test, values[0], values[1] + __test(test_case[0], test_case[1]) def test_archives_archive_resources_references_are_populated(): @@ -219,9 +228,8 @@ def test_archives_archive_resources_references_are_populated(): } } """) - assert_equal({".foo", ".foo.A", ".foo.A.resourceA", ".foo.A.resourceA.@baz@B"}, - tree.symbols()) - assert_is_instance(tree.find(".foo.A.resourceA.@baz@B"), refs.TypeReference) + assert {".foo", ".foo.A", ".foo.A.resourceA", ".foo.A.resourceA.@baz@B"} == tree.symbols() + assert isinstance(tree.find(".foo.A.resourceA.@baz@B"), refs.TypeReference) def test_multi_vector_builtin_types_are_correct(): @@ -232,12 +240,12 @@ def test_multi_vector_builtin_types_are_correct(): } """) res = tree.find(".foo.A.resourceA") - assert_equal(33, res.width) - assert_equal(1, len(res.builtins)) + assert 33 == res.width + assert 1 == len(res.builtins) index_type = res.builtins[0] _compute_structure_sizes(index_type) - assert_equal({"IndexType33", "IndexType33.value"}, index_type.symbols()) + assert {"IndexType33", "IndexType33.value"} == index_type.symbols() check_struct(index_type, 33, 5) check_field(index_type.find("IndexType33.value"), "u64", 33, 0) @@ -252,7 +260,7 @@ def test_explicit_reference_decoration_spawns_all_the_right_references(): } """) - assert_equal({".foo", + assert {".foo", ".foo.X", ".foo.X.resourceA", ".foo.X.resourceA.@A", @@ -264,21 +272,20 @@ def test_explicit_reference_decoration_spawns_all_the_right_references(): '.foo.X.resourceA.er_A_refB_resourceB.@A', '.foo.X.resourceA.er_A_refB_resourceB.@A@refB', '.foo.X.resourceA.er_A_refB_resourceB.@resourceB' - }, - tree.symbols()) + } == tree.symbols() r = tree.find(".foo.X.resourceA") - assert_equal(2, len(r.decorations)) + assert 2 == len(r.decorations) check_explicit_reference(r.decorations[0], "A", "refB", "resourceB") check_explicit_reference(r.decorations[1], "A", "refC", "resourceC") - assert_is_instance(tree.find(".foo.X.resourceA.er_A_refB_resourceB.@A@refB"), + assert isinstance(tree.find(".foo.X.resourceA.er_A_refB_resourceB.@A@refB"), refs.FieldReference) - assert_is_instance(tree.find(".foo.X.resourceA.er_A_refB_resourceB.@resourceB"), + assert isinstance(tree.find(".foo.X.resourceA.er_A_refB_resourceB.@resourceB"), refs.ResourceReference) - assert_is_instance(tree.find(".foo.X.resourceA.er_A_refC_resourceC.@A@refC"), + assert isinstance(tree.find(".foo.X.resourceA.er_A_refC_resourceC.@A@refC"), refs.FieldReference) - assert_is_instance(tree.find(".foo.X.resourceA.er_A_refC_resourceC.@resourceC"), + assert isinstance(tree.find(".foo.X.resourceA.er_A_refC_resourceC.@resourceC"), refs.ResourceReference) @@ -292,9 +299,9 @@ def test_optional_decoration(): """) r = tree.find(".foo.A.resourceA") - assert_equal(1, len(r.decorations)) - assert_in("optional", r.decorations[0]) - assert_true(r.optional) + assert 1 == len(r.decorations) + assert "optional" in r.decorations[0] + assert r.optional def test_no_optional_decoration(): @@ -306,8 +313,8 @@ def test_no_optional_decoration(): """) r = tree.find(".foo.A.resourceA") - assert_equal(0, len(r.decorations)) - assert_false(r.optional) + assert 0 == len(r.decorations) + assert not r.optional def test_implicit_references_are_represented_correctly(): @@ -349,11 +356,10 @@ def test_multiple_archives_can_be_defined(): } """) - assert_equal({".foo", ".foo.S", ".foo.S.x", ".foo.A", ".foo.A.resource1", ".foo.A.resource1.@S", + assert {".foo", ".foo.S", ".foo.S.x", ".foo.A", ".foo.A.resource1", ".foo.A.resource1.@S", ".foo.F", ".foo.F.x", ".foo.B", ".foo.B.resource0", ".foo.B.resource0.@F", ".foo.B.resource1", - ".foo.B.resource1.@S"}, - tree.symbols()) + ".foo.B.resource1.@S"} == tree.symbols() def test_namespace_merging_works_for_separate_namespaces(): @@ -370,9 +376,8 @@ def test_namespace_merging_works_for_separate_namespaces(): } """) - assert_equal({'.n1', '.n1.A', '.n1.A.refN1', - '.n2', '.n2.A', '.n2.A.refN2'}, - tree.symbols()) + assert {'.n1', '.n1.A', '.n1.A.refN1', + '.n2', '.n2.A', '.n2.A.refN2'} == tree.symbols() def test_namespace_merging_works_for_nested_namespaces(): @@ -389,9 +394,8 @@ def test_namespace_merging_works_for_nested_namespaces(): } """) - assert_equal({'.n1', '.n1.A', '.n1.A.refN1', - '.n1.n2', '.n1.n2.A', '.n1.n2.A.refN2'}, - tree.symbols()) + assert {'.n1', '.n1.A', '.n1.A.refN1', + '.n1.n2', '.n1.n2.A', '.n1.n2.A.refN2'} == tree.symbols() def test_namespace_merging_works_for_same_namespaces_with_different_symbols(): @@ -408,13 +412,12 @@ def test_namespace_merging_works_for_same_namespaces_with_different_symbols(): } """) - assert_equal({'.n1', '.n1.n2', + assert {'.n1', '.n1.n2', '.n1.n2.A', '.n1.n2.A.refN1', - '.n1.n2.B', '.n1.n2.B.refN2'}, - tree.symbols()) + '.n1.n2.B', '.n1.n2.B.refN2'} == tree.symbols() def test_exceeding_field_width_results_in_an_error(): - with assert_raises(InvalidWidthError): + with pytest.raises(InvalidWidthError): _build_node_tree(""" namespace n { struct A { @@ -423,7 +426,7 @@ def test_exceeding_field_width_results_in_an_error(): } """) def test_signed_enum_value_in_unsigned_enum(): - with assert_raises(InvalidSignError): + with pytest.raises(InvalidSignError): _build_node_tree(""" namespace n { enum A : u16 : 1 { @@ -432,7 +435,7 @@ def test_signed_enum_value_in_unsigned_enum(): } """) def test_not_enough_implicit_bits_for_enum_value(): - with assert_raises(InvalidEnumValueError): + with pytest.raises(InvalidEnumValueError): _build_node_tree(""" namespace n { enum A : u8 : 8 { @@ -441,7 +444,7 @@ def test_not_enough_implicit_bits_for_enum_value(): } """) def test_not_enough_explicit_bits_for_enum_value(): - with assert_raises(InvalidEnumValueError): + with pytest.raises(InvalidEnumValueError): _build_node_tree(""" namespace n { enum A : u8 : 4 { @@ -450,7 +453,7 @@ def test_not_enough_explicit_bits_for_enum_value(): } """) def test_duplicate_enum_value(): - with assert_raises(DuplicateEnumValueError): + with pytest.raises(DuplicateEnumValueError): _build_node_tree(""" namespace n { enum A : u16 : 3 { @@ -461,7 +464,7 @@ def test_duplicate_enum_value(): } """) def test_not_enough_bits_in_enum_field(): - with assert_raises(InvalidEnumWidthError): + with pytest.raises(InvalidEnumWidthError): tree = _build_node_tree(""" namespace n { enum A : i16 : 8 { @@ -491,7 +494,7 @@ def test_enumeration(): _update_field_type_references(tree) _compute_structure_sizes(tree) - assert_equal({ + assert { ".n", ".n.A", ".n.A.VALUE_1", @@ -528,7 +531,6 @@ def test_enumeration(): '.n.A.UNKNOWN_VALUE_31', ".n.B", ".n.B.f1", - ".n.B.f1.@@n@A"}, - tree.symbols()) + ".n.B.f1.@@n@A"} == tree.symbols() check_struct(tree.find(".n.B"), 5, 1) diff --git a/flatdata-generator/tests/tree/test_references.py b/flatdata-generator/tests/tree/test_references.py index f15b6749..16305f47 100644 --- a/flatdata-generator/tests/tree/test_references.py +++ b/flatdata-generator/tests/tree/test_references.py @@ -1,14 +1,14 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import sys +import pytest sys.path.insert(0, "..") -from nose.tools import assert_equal, assert_raises import flatdata.generator.tree.nodes.references as refs def test_reference_name_is_at_prefixed_and_at_separated(): - assert_equal("@foo@bar@baz", refs.TypeReference(name="foo.bar.baz").name) + assert "@foo@bar@baz" == refs.TypeReference(name="foo.bar.baz").name diff --git a/flatdata-generator/tests/tree/test_resolver.py b/flatdata-generator/tests/tree/test_resolver.py index affa046e..bcffdc25 100644 --- a/flatdata-generator/tests/tree/test_resolver.py +++ b/flatdata-generator/tests/tree/test_resolver.py @@ -1,9 +1,10 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import sys +import pytest sys.path.insert(0, "..") import flatdata.generator.tree.nodes.trivial as nodes @@ -15,8 +16,6 @@ from flatdata.generator.tree.resolver import resolve_references import flatdata.generator.tree.errors as errors -from nose.tools import assert_equal, assert_is_instance, assert_raises - def _create_tree_resource_to_struct(actual, reference): root = Root().insert(nodes.Namespace(name="ns").insert(nodes.Structure(name=actual), @@ -71,16 +70,16 @@ def _assert_missing_symbol_is_thrown(root, message): try: resolve_references(root) except errors.MissingSymbol as e: - assert_equal(message, str(e)) + assert message == str(e) else: - assert_false(True, "MissingSymbol was not thrown") + assert False == "MissingSymbol was not thrown" def test_resource_to_struct_references_are_resolved_for_the_current_scope(): root = _create_tree_resource_to_struct(actual="Struct", reference="Struct") - assert_is_instance(root.find('.ns.Archive.resource.@Struct'), refs.StructureReference) + assert isinstance(root.find('.ns.Archive.resource.@Struct'), refs.StructureReference) resolve_references(root) - assert_is_instance(root.find('.ns.Archive.resource.@@ns@Struct'), refs.StructureReference) + assert isinstance(root.find('.ns.Archive.resource.@@ns@Struct'), refs.StructureReference) def test_resource_to_struct_references_throw_missing_symbol_if_no_name_found_in_current_scope(): @@ -98,14 +97,14 @@ def test_resource_to_struct_references_throw_missing_symbol_if_no_name_found_in_ def test_resource_to_struct_references_are_verified_if_global_path_is_specified(): root = _create_tree_resource_to_struct_with_extra_folding("Struct", ".ns.fold.Struct") - assert_is_instance(root.find('.ns.Archive.resource.@@ns@fold@Struct'), refs.StructureReference) + assert isinstance(root.find('.ns.Archive.resource.@@ns@fold@Struct'), refs.StructureReference) resolve_references(root) - assert_is_instance(root.find('.ns.Archive.resource.@@ns@fold@Struct'), refs.StructureReference) + assert isinstance(root.find('.ns.Archive.resource.@@ns@fold@Struct'), refs.StructureReference) def test_resource_references_are_verified_if_global_path_is_specified(): root = _create_tree_resource_to_struct_with_extra_folding("Strict", ".ns.fold.Struct") - assert_is_instance(root.find('.ns.Archive.resource.@@ns@fold@Struct'), refs.StructureReference) + assert isinstance(root.find('.ns.Archive.resource.@@ns@fold@Struct'), refs.StructureReference) try: import Levenshtein except ImportError: @@ -121,39 +120,39 @@ def test_resource_references_are_verified_if_global_path_is_specified(): def test_resource_to_archive_references_are_resolved(): root = _create_tree_resource_to_archive() - assert_is_instance(root.find('.ns.Archive.resource.@RefArchive'), refs.ArchiveReference) + assert isinstance(root.find('.ns.Archive.resource.@RefArchive'), refs.ArchiveReference) resolve_references(root) - assert_is_instance(root.find('.ns.Archive.resource.@@ns@RefArchive'), refs.ArchiveReference) + assert isinstance(root.find('.ns.Archive.resource.@@ns@RefArchive'), refs.ArchiveReference) def test_resource_to_field_references_are_resolved(): root = _create_tree_with_explicit_reference("Archive.resource2") - assert_is_instance(root.find('.ns.Archive.resource.@Struct@Field'), refs.FieldReference) + assert isinstance(root.find('.ns.Archive.resource.@Struct@Field'), refs.FieldReference) resolve_references(root) - assert_is_instance(root.find('.ns.Archive.resource.@@ns@Struct@Field'), refs.FieldReference) + assert isinstance(root.find('.ns.Archive.resource.@@ns@Struct@Field'), refs.FieldReference) def test_resource_to_resource_references_are_resolved_for_namespace_path(): root = _create_tree_with_explicit_reference("Archive.resource2") - assert_is_instance(root.find('.ns.Archive.resource.@Archive@resource2'), refs.ResourceReference) + assert isinstance(root.find('.ns.Archive.resource.@Archive@resource2'), refs.ResourceReference) resolve_references(root) - assert_is_instance(root.find('.ns.Archive.resource.@@ns@Archive@resource2'), + assert isinstance(root.find('.ns.Archive.resource.@@ns@Archive@resource2'), refs.ResourceReference) def test_resource_to_resource_references_are_resolved_for_parent_scope(): root = _create_tree_with_explicit_reference("resource2") - assert_is_instance(root.find('.ns.Archive.resource.@resource2'), refs.ResourceReference) + assert isinstance(root.find('.ns.Archive.resource.@resource2'), refs.ResourceReference) resolve_references(root) - assert_is_instance(root.find('.ns.Archive.resource.@@ns@Archive@resource2'), + assert isinstance(root.find('.ns.Archive.resource.@@ns@Archive@resource2'), refs.ResourceReference) def test_resolved_references_appear_in_original_order(): root = _create_tree_with_two_struct_references() resolve_references(root) - assert_equal("@@ns@S1", root.find('.ns.Archive.resource').children[0].name) - assert_equal("@@ns@S2", root.find('.ns.Archive.resource').children[1].name) + assert "@@ns@S1" == root.find('.ns.Archive.resource').children[0].name + assert "@@ns@S2" == root.find('.ns.Archive.resource').children[1].name def test_implicit_references_structure_is_resolved(): @@ -163,5 +162,5 @@ def test_implicit_references_structure_is_resolved(): refs.ResourceReference("A.r1"), refs.ResourceReference("A.r2"))))) resolve_references(root) - assert_equal("@@n@A@r1", root.find('.n.A.b').children[0].name) - assert_equal("@@n@A@r2", root.find('.n.A.b').children[1].name) + assert "@@n@A@r1" == root.find('.n.A.b').children[0].name + assert "@@n@A@r2" == root.find('.n.A.b').children[1].name diff --git a/flatdata-generator/tests/tree/test_schema_resolution.py b/flatdata-generator/tests/tree/test_schema_resolution.py index 9778d4b5..8bbe90b3 100644 --- a/flatdata-generator/tests/tree/test_schema_resolution.py +++ b/flatdata-generator/tests/tree/test_schema_resolution.py @@ -1,16 +1,16 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' + import sys +import pytest sys.path.insert(0, "..") from flatdata.generator.tree.syntax_tree import SyntaxTree from flatdata.generator.tree.builder import _build_node_tree, build_ast from flatdata.generator.tree.resolver import resolve_references -from nose.tools import assert_equal, assert_raises - def test_archive_member_schemas_references_dependent_types(): root = _build_node_tree("""namespace n{ @@ -25,8 +25,7 @@ def test_archive_member_schemas_references_dependent_types(): } """) resolve_references(root) - assert_equal(SyntaxTree.schema(root.find(".n.A.a")), - """namespace n { + assert SyntaxTree.schema(root.find(".n.A.a")) == """namespace n { struct T { t : u8 : 7; @@ -40,9 +39,9 @@ def test_archive_member_schemas_references_dependent_types(): } } -""") - assert_equal(SyntaxTree.schema(root.find(".n.A.b")), - """namespace n { +""" + + assert SyntaxTree.schema(root.find(".n.A.b")) == """namespace n { struct V { v : u8 : 7; @@ -56,9 +55,9 @@ def test_archive_member_schemas_references_dependent_types(): } } -""") - assert_equal(SyntaxTree.schema(root.find(".n.A.c")), - """namespace n { +""" + + assert SyntaxTree.schema(root.find(".n.A.c")) == """namespace n { struct U { u : u8 : 7; @@ -79,7 +78,7 @@ def test_archive_member_schemas_references_dependent_types(): } } -""") +""" def test_archive_schema_preserves_references(): @@ -111,7 +110,7 @@ def test_archive_schema_preserves_references(): } """ - assert_equal(SyntaxTree.schema(root.find(".foo.A")), expected) + assert SyntaxTree.schema(root.find(".foo.A")) == expected def test_schemas_are_not_duplicated_if_several_type_references_occur(): @@ -145,7 +144,7 @@ def test_schemas_are_not_duplicated_if_several_type_references_occur(): """ actual = SyntaxTree.schema(root.find(".foo.A")) - assert_equal(actual, expected) + assert actual == expected def test_archive_schemas_include_constants(): @@ -178,4 +177,4 @@ def test_archive_schemas_include_constants(): """ actual = SyntaxTree.schema(root.find(".foo.A")) - assert_equal(actual, expected) + assert actual == expected diff --git a/flatdata-generator/tests/tree/test_syntax_tree.py b/flatdata-generator/tests/tree/test_syntax_tree.py index ee85fbe9..882f5650 100644 --- a/flatdata-generator/tests/tree/test_syntax_tree.py +++ b/flatdata-generator/tests/tree/test_syntax_tree.py @@ -1,11 +1,10 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import sys - -from nose.tools import assert_equal, assert_raises +import pytest sys.path.insert(0, "..") from flatdata.generator.tree.syntax_tree import SyntaxTree @@ -55,11 +54,11 @@ def _check_traversal_order(tree, traversal, expected_paths, **kwargs): nodes.append(node) attrs.append(attr) expected_nodes = [tree.find(n) for n in expected_paths] - assert_equal(expected_paths, [n.path for n in nodes]) - assert_equal(expected_nodes, [n for n in nodes]) + assert expected_paths == [n.path for n in nodes] + assert expected_nodes == [n for n in nodes] for arg, value in kwargs.items(): - assert_equal(value, [getattr(v, arg) for v in attrs]) + assert value == [getattr(v, arg) for v in attrs] def test_bfs_traversal_basic_ordering(): @@ -109,20 +108,17 @@ def test_bfs_traversal_expands_type_references(): def test_dfs_traversal_reports_cyclic_references(): - with assert_raises(CircularReferencing): + with pytest.raises(CircularReferencing): for _, _ in DfsTraversal(create_tree_with_cycle()).iterate(): pass def test_dfs_traversal_provides_topological_ordering(): - assert_equal( - [ + assert [ "ns.S0", "ns.A1", "ns.A0.R0", "ns.A0.R1", "ns.A0", "ns" - ], - [n.path for n, _ in - DfsTraversal(create_tree_with_topological_ordering()).dependency_order()]) + ] == [n.path for n, _ in DfsTraversal(create_tree_with_topological_ordering()).dependency_order()] diff --git a/flatdata-generator/tests/tree/test_syntax_tree_builder.py b/flatdata-generator/tests/tree/test_syntax_tree_builder.py index ccd025fa..d3199a79 100644 --- a/flatdata-generator/tests/tree/test_syntax_tree_builder.py +++ b/flatdata-generator/tests/tree/test_syntax_tree_builder.py @@ -1,11 +1,10 @@ ''' - Copyright (c) 2017 HERE Europe B.V. + Copyright (c) 2025 HERE Europe B.V. See the LICENSE file in the root of this project for license details. ''' import sys - -from nose.tools import assert_equal, assert_is_instance, assert_raises, assert_true +import pytest sys.path.insert(0, "..") from flatdata.generator.tree.errors import MissingSymbol, InvalidRangeName, InvalidRangeReference, \ @@ -21,17 +20,23 @@ FieldReference, ArchiveReference, BuiltinStructureReference, ConstantValueReference, \ EnumerationReference, InvalidValueReference -def test_validating_archive_with_no_structure_defined_raises_missing_symbol_error(): +def get_test_cases(): + test_cases = [] + for t in ["T", "vector< T >", "multivector< 33, V>"]: + test_cases.append(t) + return test_cases + +@pytest.mark.parametrize("test_case", get_test_cases()) +def test_validating_archive_with_no_structure_defined_raises_missing_symbol_error(test_case): def __test(resource_type): - with assert_raises(MissingSymbol): + with pytest.raises(MissingSymbol): build_ast( """namespace foo{ archive A { resourceA : %s; } }""" % resource_type) - for t in ["T", "vector< T >", "multivector< 33, V>"]: - yield __test, t + __test(test_case) def test_const_ref_with_mismatched_type(): - with assert_raises(InvalidConstReference): + with pytest.raises(InvalidConstReference): build_ast("""namespace foo{ const u32 FOO = 10; struct A { @@ -42,7 +47,7 @@ def test_const_ref_with_mismatched_type(): """) def test_const_ref_with_too_few_bits(): - with assert_raises(InvalidConstValueReference): + with pytest.raises(InvalidConstValueReference): build_ast("""namespace foo{ const u32 FOO = 16; struct A { @@ -53,7 +58,7 @@ def test_const_ref_with_too_few_bits(): """) def test_duplicate_optional(): - with assert_raises(DuplicateInvalidValueReference): + with pytest.raises(DuplicateInvalidValueReference): build_ast("""namespace foo{ const u32 FOO = 16; const u32 BAR = 16; @@ -66,7 +71,7 @@ def test_duplicate_optional(): """) def test_range_with_duplicate_name(): - with assert_raises(InvalidRangeName): + with pytest.raises(InvalidRangeName): build_ast("""namespace foo{ struct A { @range(ref_n) @@ -76,7 +81,7 @@ def test_range_with_duplicate_name(): """) def test_range_cannot_be_used_in_multivector(): - with assert_raises(InvalidRangeReference): + with pytest.raises(InvalidRangeReference): build_ast("""namespace foo{ struct A { @range(my_range) @@ -89,7 +94,7 @@ def test_range_cannot_be_used_in_multivector(): """) def test_range_cannot_be_used_in_struct_resource(): - with assert_raises(InvalidRangeReference): + with pytest.raises(InvalidRangeReference): build_ast("""namespace foo{ struct A { @range(my_range) @@ -102,7 +107,7 @@ def test_range_cannot_be_used_in_struct_resource(): """) def test_optional_range(): - with assert_raises(OptionalRange): + with pytest.raises(OptionalRange): build_ast("""namespace foo{ const u32 NO_EDGES_REF = 200; struct Node { @@ -128,7 +133,7 @@ def test_ranges_can_be_used_in_normally(): """) def test_explicit_reference_decoration_fails_when_unknown_type_is_referenced(): - with assert_raises(MissingSymbol): + with pytest.raises(MissingSymbol): build_ast("""namespace foo{ struct A { refB : u64 : 64; @@ -142,7 +147,7 @@ def test_explicit_reference_decoration_fails_when_unknown_type_is_referenced(): """) def test_explicit_reference_decoration_fails_when_unknown_field_is_referenced(): - with assert_raises(MissingSymbol): + with pytest.raises(MissingSymbol): build_ast("""namespace foo { struct A { refB : u64 : 64; @@ -157,7 +162,7 @@ def test_explicit_reference_decoration_fails_when_unknown_field_is_referenced(): def test_explicit_reference_decoration_fails_when_unknown_resource_is_referenced(): - with assert_raises(MissingSymbol): + with pytest.raises(MissingSymbol): build_ast("""namespace foo{ struct A { refB : u64 : 64; @@ -171,7 +176,7 @@ def test_explicit_reference_decoration_fails_when_unknown_resource_is_referenced def test_implicit_references_fail_on_unknown_resource(): - with assert_raises(MissingSymbol): + with pytest.raises(MissingSymbol): build_ast("""namespace foo{ struct A { refB : u64 : 64; @@ -193,12 +198,12 @@ def test_multi_vector_references_builtin_type(): } } """) - assert_equal({ + assert { ".n", ".n.T", ".n.T.t", ".n.A", ".n.A.r", ".n.A.r.@@n@T", ".n.A.r.@@n@_builtin@multivector@IndexType33", ".n._builtin", ".n._builtin.multivector", ".n._builtin.multivector.IndexType33", ".n._builtin.multivector.IndexType33.value" - }, tree.symbols()) + } == tree.symbols() def test_duplicate_multivector_builtin_types_are_not_produced(): @@ -210,13 +215,13 @@ def test_duplicate_multivector_builtin_types_are_not_produced(): } } """) - assert_equal({ + assert { ".n", ".n.T", ".n.T.t", ".n.A", ".n.A.r", ".n.A.r.@@n@T", ".n.A.r.@@n@_builtin@multivector@IndexType33", ".n.A.r2", ".n.A.r2.@@n@T", ".n.A.r2.@@n@_builtin@multivector@IndexType33", ".n._builtin", ".n._builtin.multivector", ".n._builtin.multivector.IndexType33", ".n._builtin.multivector.IndexType33.value" - }, tree.symbols()) + } == tree.symbols() TREE_WITH_ALL_FEATURES = """ @@ -273,8 +278,7 @@ def test_duplicate_multivector_builtin_types_are_not_produced(): def test_all_flatdata_features_look_as_expected_in_fully_built_tree(): tree = build_ast(TREE_WITH_ALL_FEATURES) - assert_equal.__self__.maxDiff = None - assert_equal({ + assert { '.ns': Namespace, '.ns.A0': Archive, '.ns.A0.@@ns@C': ConstantValueReference, @@ -350,14 +354,14 @@ def test_all_flatdata_features_look_as_expected_in_fully_built_tree(): '.ns._builtin.multivector': Namespace, '.ns._builtin.multivector.IndexType14': Structure, '.ns._builtin.multivector.IndexType14.value': Field, - }, tree.symbols(include_types=True)) + } == tree.symbols(include_types=True) def test_tree_with_all_features_schema_results_in_the_same_normalized_tree(): tree = build_ast(TREE_WITH_ALL_FEATURES) schema = tree.schema(tree.find('.ns.A1')) generated_tree = build_ast(schema) - assert_equal({ + assert { '.ns': Namespace, '.ns.A0': Archive, '.ns.A0.@@ns@C': ConstantValueReference, @@ -433,10 +437,23 @@ def test_tree_with_all_features_schema_results_in_the_same_normalized_tree(): '.ns._builtin.multivector': Namespace, '.ns._builtin.multivector.IndexType14': Structure, '.ns._builtin.multivector.IndexType14.value': Field, - }, generated_tree.symbols(include_types=True)) + } == generated_tree.symbols(include_types=True) +def get_test_cases_resource_types_are_populated_from_structure_references(): + test_cases = [] + for values in [ + ("T", res.Instance, {"referenced_structures": [".n.A.r.@@n@T"]}), + ("vector< T >", res.Vector, {"referenced_structures": [".n.A.r.@@n@T"]}), + ("multivector< 33, T>", res.Multivector, { + "referenced_structures": ['.n.A.r.@@n@_builtin@multivector@IndexType33', + '.n.A.r.@@n@T']}), + ("raw_data", res.RawData, {"referenced_structures": []}) + ]: + test_cases.append(values) + return test_cases -def test_resource_types_are_populated_from_structure_references(): +@pytest.mark.parametrize("test_case", get_test_cases_resource_types_are_populated_from_structure_references()) +def test_resource_types_are_populated_from_structure_references(test_case): def __test(schema, resource_type, properties): tree = build_ast("""namespace n{ struct T { @@ -449,23 +466,15 @@ def __test(schema, resource_type, properties): """ % schema) a = tree.find(".n.A") - assert_is_instance(a, Archive) + assert isinstance(a, Archive) r = a.find("A.r") - assert_is_instance(r, resource_type) + assert isinstance(r, resource_type) for k, values in properties.items(): - assert_true(hasattr(r, k)) - assert_equal([tree.find(v) for v in values], getattr(r, k)) + assert hasattr(r, k) + assert [tree.find(v) for v in values] == getattr(r, k) - for values in [ - ("T", res.Instance, {"referenced_structures": [".n.A.r.@@n@T"]}), - ("vector< T >", res.Vector, {"referenced_structures": [".n.A.r.@@n@T"]}), - ("multivector< 33, T>", res.Multivector, { - "referenced_structures": ['.n.A.r.@@n@_builtin@multivector@IndexType33', - '.n.A.r.@@n@T']}), - ("raw_data", res.RawData, {"referenced_structures": []}) - ]: - yield __test, values[0], values[1], values[2] + __test(test_case[0], test_case[1], test_case[2]) def test_constants_are_referred_from_every_archive(): @@ -489,7 +498,7 @@ def test_constants_are_referred_from_every_archive(): tree.find(".n.A.@@n@m@C") def test_explicit_reference_has_to_reference_struct_used_in_resource(): - with assert_raises(InvalidStructInExplicitReference): + with pytest.raises(InvalidStructInExplicitReference): build_ast(""" namespace prime { struct Factor { diff --git a/flatdata-py/README.md b/flatdata-py/README.md index 9d194c1d..d1579a9c 100644 --- a/flatdata-py/README.md +++ b/flatdata-py/README.md @@ -7,7 +7,7 @@ Python 3 implementation of [flatdata](https://github.com/heremaps/flatdata). ## Running the tests ```sh -python3 -m nose +python3 -m pytest ``` ## Basic usage diff --git a/flatdata-py/pyproject.toml b/flatdata-py/pyproject.toml index 94da4a24..be0a85e6 100644 --- a/flatdata-py/pyproject.toml +++ b/flatdata-py/pyproject.toml @@ -40,3 +40,9 @@ include = [ [tool.hatch.build.targets.wheel] packages = ["flatdata"] + +[tool.pytest.ini_options] +testpaths = [ "tests" ] +python_files = [ "test_*.py" ] +python_classes = [ "Test*" ] +python_functions = [ "test_*" ] diff --git a/flatdata-py/tests/test_archive_validation.py b/flatdata-py/tests/test_archive_validation.py index fd506fe5..6058bb27 100644 --- a/flatdata-py/tests/test_archive_validation.py +++ b/flatdata-py/tests/test_archive_validation.py @@ -2,10 +2,19 @@ from flatdata.lib.errors import CorruptArchiveError, SchemaMismatchError from common import DictResourceStorage, INSTANCE_TEST_SCHEMA, RESOURCE_PAYLOAD, ARCHIVE_SIGNATURE_PAYLOAD -from nose.tools import assert_raises +import pytest -def test_archive_does_not_open_on_signature_resource_or_schemas_missing(): +@pytest.mark.parametrize("case", [ + "missing_signature", + "corrupt_signature", + "missing_schema", + "corrupt_schema", + "missing_resource", + "missing_resource_schema", + "corrupt_resource_schema" +]) +def test_archive_does_not_open_on_signature_resource_or_schemas_missing(case): module = Engine(INSTANCE_TEST_SCHEMA).render_python_module() valid_data = { "Archive.archive": ARCHIVE_SIGNATURE_PAYLOAD, @@ -38,20 +47,19 @@ def test_archive_does_not_open_on_signature_resource_or_schemas_missing(): corrupt_resource_schema = valid_data.copy() corrupt_resource_schema["resource.schema"] = b"foo" - datasets = [ - (missing_signature, CorruptArchiveError), - (corrupt_signature, CorruptArchiveError), - (missing_schema, CorruptArchiveError), - (corrupt_schema, SchemaMismatchError), - (missing_resource, CorruptArchiveError), - (missing_resource_schema, CorruptArchiveError), - (corrupt_resource_schema, SchemaMismatchError), - ] - - def _test(index, data, error_type): - with assert_raises(error_type): + datasets = { + "missing_signature": (missing_signature, CorruptArchiveError), + "corrupt_signature": (corrupt_signature, CorruptArchiveError), + "missing_schema": (missing_schema, CorruptArchiveError), + "corrupt_schema": (corrupt_schema, SchemaMismatchError), + "missing_resource": (missing_resource, CorruptArchiveError), + "missing_resource_schema": (missing_resource_schema, CorruptArchiveError), + "corrupt_resource_schema": (corrupt_resource_schema, SchemaMismatchError), + } + + def _test(data, error_type): + with pytest.raises(error_type): module.backward_compatibility_Archive(DictResourceStorage(data)) - for index, payload in enumerate(datasets): - data, error_type = payload - yield _test, index, data, error_type + data, error_type = datasets[case] + _test(data, error_type) diff --git a/flatdata-py/tests/test_backward_compatibility.py b/flatdata-py/tests/test_backward_compatibility.py index 628c497a..269960a3 100644 --- a/flatdata-py/tests/test_backward_compatibility.py +++ b/flatdata-py/tests/test_backward_compatibility.py @@ -1,19 +1,19 @@ from flatdata.generator.engine import Engine from common import * -from nose.tools import eq_, assert_is_instance +import pytest def check_signed_struct(s): - eq_(-0x1, s.a) - eq_(0x01234567, s.b) - eq_(-0x28, s.c) - eq_(0, s.d) + assert -0x1 == s.a + assert 0x01234567 == s.b + assert -0x28 == s.c + assert 0 == s.d def check_simple_struct(s): - eq_(0xFFFFFFFF, s.a) - eq_(0xDEADBEEF, s.b) + assert 0xFFFFFFFF == s.a + assert 0xDEADBEEF == s.b def test_instance_reading(): @@ -39,7 +39,7 @@ def test_vector_reading(): } archive = module.backward_compatibility_Archive(DictResourceStorage(valid_data)) - eq_(2, len(archive.resource)) + assert 2 == len(archive.resource) check_signed_struct(archive.resource[0]) check_signed_struct(archive.resource[1]) @@ -56,24 +56,24 @@ def test_multivector_reading(): } archive = module.backward_compatibility_Archive(DictResourceStorage(valid_data)) - eq_(4, len(archive.resource)) + assert 4 == len(archive.resource) - eq_(2, len(archive.resource[0])) - assert_is_instance(archive.resource[0][0], module.backward_compatibility_SignedStruct) + assert 2 == len(archive.resource[0]) + assert isinstance(archive.resource[0][0], module.backward_compatibility_SignedStruct) check_signed_struct(archive.resource[0][0]) - assert_is_instance(archive.resource[0][1], module.backward_compatibility_SimpleStruct) + assert isinstance(archive.resource[0][1], module.backward_compatibility_SimpleStruct) check_simple_struct(archive.resource[0][1]) - eq_(0, len(archive.resource[1])) + assert 0 == len(archive.resource[1]) - eq_(2, len(archive.resource[2])) - assert_is_instance(archive.resource[2][0], module.backward_compatibility_SimpleStruct) + assert 2 == len(archive.resource[2]) + assert isinstance(archive.resource[2][0], module.backward_compatibility_SimpleStruct) check_simple_struct(archive.resource[2][0]) - assert_is_instance(archive.resource[2][1], module.backward_compatibility_SignedStruct) + assert isinstance(archive.resource[2][1], module.backward_compatibility_SignedStruct) check_signed_struct(archive.resource[2][1]) - eq_(1, len(archive.resource[3])) - assert_is_instance(archive.resource[3][0], module.backward_compatibility_SimpleStruct) + assert 1 == len(archive.resource[3]) + assert isinstance(archive.resource[3][0], module.backward_compatibility_SimpleStruct) check_simple_struct(archive.resource[3][0]) @@ -87,7 +87,7 @@ def test_raw_data_reading(): } archive = module.backward_compatibility_Archive(DictResourceStorage(valid_data)) - eq_(5, len(archive.resource)) - eq_(b"\xff", archive.resource[0]) - eq_(b"\xde", archive.resource[4]) - eq_(b"\xff\xef\xbe\xad\xde", archive.resource[0:5]) + assert 5 == len(archive.resource) + assert b"\xff" == archive.resource[0] + assert b"\xde" == archive.resource[4] + assert b"\xff\xef\xbe\xad\xde" == archive.resource[0:5] diff --git a/flatdata-py/tests/test_data_access.py b/flatdata-py/tests/test_data_access.py index f489f09a..86af3c57 100644 --- a/flatdata-py/tests/test_data_access.py +++ b/flatdata-py/tests/test_data_access.py @@ -1,4 +1,4 @@ -from nose.tools import assert_equal +import pytest from flatdata.lib.data_access import read_value, write_value @@ -9,7 +9,7 @@ def test_reader(): C++ originals. """ def _test_reader(buffer, offset, num_bits, is_signed, expected): - assert_equal(read_value(buffer, offset, num_bits, is_signed), expected) + assert read_value(buffer, offset, num_bits, is_signed) == expected _test_reader(b"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 8, 8, False, 1) _test_reader(b"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 8, 7, False, 1) @@ -1133,7 +1133,7 @@ def test_writer(): def _test_writer(buffer, offset, num_bits, is_signed, expected): bout = bytearray(len(buffer)) write_value(bout, offset, num_bits, is_signed, expected) - assert_equal(bout, buffer) + assert bout == buffer _test_writer(b"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 8, 8, False, 1) _test_writer(b"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 8, 7, False, 1) diff --git a/flatdata-py/tests/test_tar_resource_storage.py b/flatdata-py/tests/test_tar_resource_storage.py index 0cc6d081..08443282 100644 --- a/flatdata-py/tests/test_tar_resource_storage.py +++ b/flatdata-py/tests/test_tar_resource_storage.py @@ -2,17 +2,17 @@ from flatdata.generator.engine import Engine from flatdata.lib.tar_archive_resource_storage import TarArchiveResourceStorage -from nose.tools import eq_ +import pytest import tarfile import tempfile import os def check_signed_struct(s): - eq_(-0x1, s.a) - eq_(0x01234567, s.b) - eq_(-0x28, s.c) - eq_(0, s.d) + assert -0x1 == s.a + assert 0x01234567 == s.b + assert -0x28 == s.c + assert 0 == s.d def test_tar_resource_storage(): diff --git a/flatdata-rs/lib/src/multivector.rs b/flatdata-rs/lib/src/multivector.rs index 4446a738..5eb3e03f 100644 --- a/flatdata-rs/lib/src/multivector.rs +++ b/flatdata-rs/lib/src/multivector.rs @@ -130,7 +130,7 @@ where /// may fail due to different IO reasons. /// /// [`flush`]: #method.flush - pub fn grow(&mut self) -> io::Result<::ItemMut> { + pub fn grow(&mut self) -> io::Result<>::ItemMut> { if self.data.len() > 1024 * 1024 * 32 { self.flush()?; } diff --git a/flatdata-rs/lib/src/test/test_generated.rs b/flatdata-rs/lib/src/test/test_generated.rs index d6fe29e8..14dd6548 100644 --- a/flatdata-rs/lib/src/test/test_generated.rs +++ b/flatdata-rs/lib/src/test/test_generated.rs @@ -524,7 +524,7 @@ impl XBuilder { /// [`data`]: struct.X.html#method.data /// [`ExternalVector::close`]: flatdata/struct.ExternalVector.html#method.close #[inline] - pub fn start_data(&self) -> ::std::io::Result> { + pub fn start_data(&self) -> ::std::io::Result> { crate::create_external_vector(&*self.storage, "data", schema::x::resources::DATA) } @@ -623,7 +623,7 @@ impl YBuilder { /// [`data`]: struct.Y.html#method.data /// [`ExternalVector::close`]: flatdata/struct.ExternalVector.html#method.close #[inline] - pub fn start_data(&self) -> ::std::io::Result> { + pub fn start_data(&self) -> ::std::io::Result> { crate::create_external_vector(&*self.storage, "data", schema::y::resources::DATA) } @@ -767,7 +767,7 @@ impl Z { } #[inline] - pub fn ab(&self) -> &crate::MultiArrayView { + pub fn ab(&self) -> &crate::MultiArrayView<'_, Ab> { &self.ab } @@ -843,7 +843,7 @@ impl ZBuilder { /// [`ab`]: struct.Z.html#method.ab /// [`MultiVector::close`]: flatdata/struct.MultiVector.html#method.close #[inline] - pub fn start_ab(&self) -> ::std::io::Result> { + pub fn start_ab(&self) -> ::std::io::Result> { crate::create_multi_vector(&*self.storage, "ab", schema::z::resources::AB) } @@ -873,7 +873,7 @@ impl W { } #[inline] - pub fn blob(&self) -> crate::RawData { + pub fn blob(&self) -> crate::RawData<'_> { self.blob }