diff --git a/tests/autotests/cfpq_concrete_cases.py b/tests/autotests/cfpq_concrete_cases.py index 4d0f33d1d..9275b0b19 100644 --- a/tests/autotests/cfpq_concrete_cases.py +++ b/tests/autotests/cfpq_concrete_cases.py @@ -5,9 +5,9 @@ from pyformlang.rsa import RecursiveAutomaton -class TestCaseCFPQ: +class CaseCFPQ: """ - class that contains all information about test case + class that contains all information about test case for cfpq algorithms """ def __init__(self, graph: MultiDiGraph, query: CFG, actual_answer: set[tuple[int, int]], @@ -23,8 +23,8 @@ def check_answer_cfg(self, function: Callable[ set[tuple[int, int]], ]): """ - assertion function to algorithms with cfg - :param function: testing function (*hellings_based_cfpq* or *matrix_based_cfpq*) + assertion function for algorithms with cfg + :param function: the function under test (*hellings_based_cfpq* or *matrix_based_cfpq*) :return: assertion """ actual_res = function(self.query, self.graph, self.start_nodes, self.final_nodes) @@ -34,8 +34,8 @@ def check_answer_rsm(self, function: Callable[ [RecursiveAutomaton, MultiDiGraph, set[int], set[int]], set[tuple[int, int]] ], cfg_to_rsm: Callable[[CFG], RecursiveAutomaton]): """ - assertion function to algorithms with rsm - :param function: testing function (*tensor_based_cfpq* or *gll_based_cfpq*) + assertion function for algorithms with rsm + :param function: the function under test (*tensor_based_cfpq* or *gll_based_cfpq*) :param cfg_to_rsm: function that convert CFG to RecursiveAutomaton :return: assertion """ @@ -49,62 +49,62 @@ def __str__(self): CASES_CFPQ = [ - TestCaseCFPQ( + CaseCFPQ( point_graph, CFG.from_text("S -> a"), set() ), - TestCaseCFPQ( + CaseCFPQ( point_graph, CFG.from_text("S -> S a | $"), {(1, 1)} ), - TestCaseCFPQ( + CaseCFPQ( set_of_vertices_without_edges, CFG.from_text("S -> S a | $"), {(0, 0), (2, 2), (1, 1)} ), - TestCaseCFPQ( + CaseCFPQ( b_graph, CFG.from_text("S -> a"), set() ), - TestCaseCFPQ( + CaseCFPQ( b_graph, CFG.from_text("S -> b"), {(0, 1)} ), - TestCaseCFPQ( + CaseCFPQ( b_graph, CFG.from_text("S -> S b | $"), {(0, 1), (0, 0), (1, 1)} ), - TestCaseCFPQ( + CaseCFPQ( bbb_graph, CFG.from_text("S -> S b b | $"), {(0, 1), (0, 0), (0, 2), (1, 1), (1, 2), (1, 0), (2, 2), (2, 1), (2, 0)} ), - TestCaseCFPQ( + CaseCFPQ( bab_graph, CFG.from_text("S -> S a | S b | $"), {(0, 1), (0, 0), (0, 2), (1, 1), (1, 2), (1, 0), (2, 2), (2, 1), (2, 0)} ), - TestCaseCFPQ( + CaseCFPQ( baa_graph, CFG.from_text("S -> a S b | $"), {(0, 0), (1, 1), (1, 0)} ), - TestCaseCFPQ( + CaseCFPQ( baa_graph, CFG.from_text("S -> a S b | a b"), {(0, 0), (1, 0)} ), - TestCaseCFPQ( + CaseCFPQ( set_of_vertices_without_edges, CFG.from_text("S -> $"), {(0, 0), (2, 2), (1, 1)} ), - TestCaseCFPQ( + CaseCFPQ( aaa_graph, CFG.from_text("S -> a | S S"), {(0, 1), (0, 0), (0, 2), (1, 1), (1, 2), (1, 0), (2, 2), (2, 1), (2, 0)} diff --git a/tests/autotests/graphs.py b/tests/autotests/graphs.py index 3e400b89c..b100e55f5 100644 --- a/tests/autotests/graphs.py +++ b/tests/autotests/graphs.py @@ -38,4 +38,4 @@ (0, 1, {LABEL: 'a'}), (1, 2, {LABEL: 'a'}), (2, 0, {LABEL: 'a'}) -]) \ No newline at end of file +]) diff --git a/tests/autotests/rpq_concrete_cases.py b/tests/autotests/rpq_concrete_cases.py new file mode 100644 index 000000000..69c4b8615 --- /dev/null +++ b/tests/autotests/rpq_concrete_cases.py @@ -0,0 +1,86 @@ +from typing import Callable + +from graphs import * +from copy import copy +from helper import rpq_dict_to_set + + +class CaseRPQ: + """ + class that contains all information about test case for rpq algorithms + """ + + def __init__(self, graph: MultiDiGraph, regex: str, actual_answer: set[tuple[int, int]], + start_nodes: set[int] = None, final_nodes: set[int] = None): + self.graph = copy(graph) + self.regex = copy(regex) + self.expected_answer = copy(actual_answer) + self.start_nodes = copy(start_nodes) if start_nodes else graph.nodes + self.final_nodes = copy(final_nodes) if final_nodes else graph.nodes + + def check_answer_regex(self, function: Callable[[MultiDiGraph, set[int], set[int], str], list[tuple[int, int]]]): + """ + assertion function for algorithms with regex + :param function: the function under test (*tensor_based_rpq*) + :return: assertion + """ + assert set(function(self.graph, self.start_nodes, self.final_nodes, self.regex)) == self.expected_answer + + def check_answer_automata(self, function, fa, constraints_fa, ): + """ + assertion function for algorithms with automata + :param function: the function under test (*ms_bfs_based_rpq*) + :param fa: automata by graph + :param constraints_fa: automata by regex + :return: assertion + """ + assert rpq_dict_to_set(function(fa, constraints_fa)) == self.expected_answer + + def __str__(self): + return f"expected result: {self.expected_answer}\n" + \ + f"regex: {self.regex}" + \ + f"graph: {self.graph.edges(data=True)}" + + +CASES_RPQ = [ + CaseRPQ( + point_graph, + "a", + set() + ), + CaseRPQ( + point_graph, + "a*", + {(1, 1)} + ), + CaseRPQ( + set_of_vertices_without_edges, + "a*", + {(0, 0), (2, 2), (1, 1)} + ), + CaseRPQ( + b_graph, + "a", + set() + ), + CaseRPQ( + b_graph, + "b", + {(0, 1)} + ), + CaseRPQ( + b_graph, + "b*", + {(0, 1), (0, 0), (1, 1)} + ), + CaseRPQ( + bbb_graph, + "(b b)*", + {(0, 1), (0, 0), (0, 2), (1, 1), (1, 2), (1, 0), (2, 2), (2, 1), (2, 0)} + ), + CaseRPQ( + bab_graph, + "(a | b)*", + {(0, 1), (0, 0), (0, 2), (1, 1), (1, 2), (1, 0), (2, 2), (2, 1), (2, 0)} + ), +] diff --git a/tests/autotests/test_task03.py b/tests/autotests/test_task03.py index e970e4d2a..35e2040ab 100644 --- a/tests/autotests/test_task03.py +++ b/tests/autotests/test_task03.py @@ -8,11 +8,12 @@ import random import itertools from grammars_constants import REGEXES +from rpq_concrete_cases import CASES_RPQ, CaseRPQ # Fix import statements in try block to run tests try: from project.task2 import regex_to_dfa - from project.task3 import intersect_automata, AdjacencyMatrixFA + from project.task3 import intersect_automata, AdjacencyMatrixFA, tensor_based_rpq except ImportError: pytestmark = pytest.mark.skip("Task 3 is not ready to test!") @@ -38,7 +39,7 @@ def test(self, regex_str1: str, regex_str2: str) -> None: return word_parts = random.choice(all_word_parts) else: - index = random.randint(0, 2**9) + index = random.randint(0, 2 ** 9) word_parts = next(itertools.islice(words, index, None)) word = map(lambda x: x.value, word_parts) @@ -46,10 +47,7 @@ def test(self, regex_str1: str, regex_str2: str) -> None: assert intersect_fa.accepts(word) -def test_tensor_based_rpq_exists(): - try: - import project.task3 - - assert "tensor_based_rpq" in dir(project.task3) - except NameError: - assert False +class TestTensorBasedRPQ: + @pytest.mark.parametrize('case', CASES_RPQ) + def test_concrete_cases(self, case: CaseRPQ): + case.check_answer_regex(tensor_based_rpq) diff --git a/tests/autotests/test_task04.py b/tests/autotests/test_task04.py index 2b73fabde..590881239 100644 --- a/tests/autotests/test_task04.py +++ b/tests/autotests/test_task04.py @@ -7,6 +7,7 @@ import pytest from grammars_constants import REGEXES from helper import generate_rnd_start_and_final, rpq_dict_to_set +from rpq_concrete_cases import CASES_RPQ, CaseRPQ # Fix import statements in try block to run tests try: @@ -23,6 +24,12 @@ def query(request) -> str: class TestRPQ: + @pytest.mark.parametrize('case', CASES_RPQ) + def test_concrete_cases(self, case: CaseRPQ): + fa = AdjacencyMatrixFA(graph_to_nfa(case.graph, case.start_nodes, case.final_nodes)) + constraint_fa = AdjacencyMatrixFA(regex_to_dfa(case.regex)) + case.check_answer_automata(ms_bfs_based_rpq, fa, constraint_fa) + def test(self, graph, query) -> None: start_nodes, final_nodes = generate_rnd_start_and_final(graph.copy()) fa = AdjacencyMatrixFA( diff --git a/tests/autotests/test_task06.py b/tests/autotests/test_task06.py index 8647f7ac1..01b5339f5 100644 --- a/tests/autotests/test_task06.py +++ b/tests/autotests/test_task06.py @@ -5,7 +5,7 @@ import pytest from grammars_constants import REGEXP_CFG, GRAMMARS from rpq_template_test import rpq_cfpq_test, different_grammars_test -from cfpq_concrete_cases import TestCaseCFPQ, CASES_CFPQ +from cfpq_concrete_cases import CaseCFPQ, CASES_CFPQ # Fix import statements in try block to run tests try: @@ -16,7 +16,7 @@ class TestHellingBasedCFPQ: @pytest.mark.parametrize("case", CASES_CFPQ) - def test_concrete_cases(self, case: TestCaseCFPQ): + def test_concrete_cases(self, case: CaseCFPQ): case.check_answer_cfg(hellings_based_cfpq) @pytest.mark.parametrize("regex_str, cfg_list", REGEXP_CFG) diff --git a/tests/autotests/test_task07.py b/tests/autotests/test_task07.py index 638a63280..513ca5fe7 100644 --- a/tests/autotests/test_task07.py +++ b/tests/autotests/test_task07.py @@ -7,7 +7,7 @@ from grammars_constants import REGEXP_CFG, GRAMMARS, GRAMMARS_DIFFERENT from helper import generate_rnd_start_and_final from rpq_template_test import rpq_cfpq_test, different_grammars_test -from cfpq_concrete_cases import CASES_CFPQ, TestCaseCFPQ +from cfpq_concrete_cases import CASES_CFPQ, CaseCFPQ # Fix import statements in try block to run tests try: @@ -19,7 +19,7 @@ class TestMatrixBasedCFPQ: @pytest.mark.parametrize("case", CASES_CFPQ) - def test_concrete_cases(self, case: TestCaseCFPQ): + def test_concrete_cases(self, case: CaseCFPQ): case.check_answer_cfg(matrix_based_cfpq) @pytest.mark.parametrize("regex_str, cfg_list", REGEXP_CFG) diff --git a/tests/autotests/test_task08.py b/tests/autotests/test_task08.py index 53f49c4a1..2ca5a31a1 100644 --- a/tests/autotests/test_task08.py +++ b/tests/autotests/test_task08.py @@ -11,7 +11,7 @@ different_grammars_test, cfpq_algorithm_test, ) -from cfpq_concrete_cases import CASES_CFPQ, TestCaseCFPQ +from cfpq_concrete_cases import CASES_CFPQ, CaseCFPQ # Fix import statements in try block to run tests try: @@ -24,7 +24,7 @@ class TestTensorBasedCFPQ: @pytest.mark.parametrize("case", CASES_CFPQ) - def test_concrete_cases(self, case: TestCaseCFPQ): + def test_concrete_cases(self, case: CaseCFPQ): case.check_answer_rsm(tensor_based_cfpq, cfg_to_rsm) @pytest.mark.parametrize("regex_str, cfg_list", REGEXP_CFG) diff --git a/tests/autotests/test_task09.py b/tests/autotests/test_task09.py index 1c8c36c5c..6a5703c12 100644 --- a/tests/autotests/test_task09.py +++ b/tests/autotests/test_task09.py @@ -11,7 +11,7 @@ different_grammars_test, cfpq_algorithm_test, ) -from cfpq_concrete_cases import TestCaseCFPQ, CASES_CFPQ +from cfpq_concrete_cases import CaseCFPQ, CASES_CFPQ # Fix import statements in try block to run tests try: @@ -25,7 +25,7 @@ class TestGLLBasedCFPQ: @pytest.mark.parametrize("case", CASES_CFPQ) - def test_concrete_cases(self, case: TestCaseCFPQ): + def test_concrete_cases(self, case: CaseCFPQ): case.check_answer_rsm(gll_based_cfpq, cfg_to_rsm) @pytest.mark.parametrize("regex_str, cfg_list", REGEXP_CFG)