diff --git a/.github/workflows/ci_extra.yml b/.github/workflows/ci_extra.yml new file mode 100644 index 0000000..fd63829 --- /dev/null +++ b/.github/workflows/ci_extra.yml @@ -0,0 +1,36 @@ +# This workflow is for any branch. It runs additional tests for several python versions. + +name: Build extra + +on: [push, pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.9", "3.10"] + + steps: + + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Lint with pylint + run: | + pylint pyformlang || true + - name: Lint with pycodestyle + run: | + pycodestyle pyformlang || true + - name: Test with pytest + run: | + pytest --showlocals -v pyformlang diff --git a/.github/workflows/ci_feature.yml b/.github/workflows/ci_feature.yml new file mode 100644 index 0000000..42f1165 --- /dev/null +++ b/.github/workflows/ci_feature.yml @@ -0,0 +1,51 @@ +# This workflow is for feature branches. It sets up python, lints with several analyzers, +# runs tests, collects test coverage and makes a coverage comment. + +name: Build feature + +on: + push: + branches-ignore: "master" + pull_request: + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.8"] + + steps: + + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + + - name: Lint with pylint + run: | + pylint pyformlang || true + - name: Lint with pycodestyle + run: | + pycodestyle pyformlang || true + - name: Test with pytest + run: | + pytest --showlocals -v pyformlang + + - name: Build coverage file + run: | + pytest pyformlang --junitxml=pytest.xml --cov=pyformlang | tee ./pytest-coverage.txt + - name: Make coverage comment + uses: MishaKav/pytest-coverage-comment@main + id: coverageComment + with: + pytest-coverage-path: ./pytest-coverage.txt + junitxml-path: ./pytest.xml + default-branch: master diff --git a/.github/workflows/python-package.yml b/.github/workflows/ci_master.yml similarity index 68% rename from .github/workflows/python-package.yml rename to .github/workflows/ci_master.yml index caf70a6..cc14bef 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/ci_master.yml @@ -1,9 +1,11 @@ -# This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions +# This workflow is for master branch only. It sets up python, lints with several analyzers, +# runs tests, collects test coverage, makes a coverage comment and creates a coverage badge. -name: Python package +name: Build master -on: [push, pull_request] +on: + push: + branches: "master" jobs: build: @@ -12,9 +14,10 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10"] + python-version: ["3.8"] steps: + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v3 @@ -23,8 +26,8 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - python -m pip install pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + pip install -r requirements.txt + - name: Lint with pylint run: | pylint pyformlang || true @@ -34,20 +37,19 @@ jobs: - name: Test with pytest run: | pytest --showlocals -v pyformlang + - name: Build coverage file - if: ${{ matrix.python-version == '3.8'}} run: | pytest pyformlang --junitxml=pytest.xml --cov=pyformlang | tee ./pytest-coverage.txt - - name: Pytest coverage comment - if: ${{ matrix.python-version == '3.8'}} + - name: Make coverage comment uses: MishaKav/pytest-coverage-comment@main id: coverageComment with: pytest-coverage-path: ./pytest-coverage.txt junitxml-path: ./pytest.xml default-branch: master + - name: Create coverage Badge - if: ${{ github.ref_name == 'master' && matrix.python-version == '3.8'}} uses: schneegans/dynamic-badges-action@v1.0.0 with: auth: ${{ secrets.GIST_SECRET }} diff --git a/pyformlang/cfg/tests/test_cfg.py b/pyformlang/cfg/tests/test_cfg.py index 9b9130e..5b7a17a 100644 --- a/pyformlang/cfg/tests/test_cfg.py +++ b/pyformlang/cfg/tests/test_cfg.py @@ -1,6 +1,6 @@ -""" Tests the CFG """ +""" Tests for the CFG """ -import unittest +import pytest from pyformlang import pda from pyformlang.cfg import Production, Variable, Terminal, CFG, Epsilon @@ -12,8 +12,8 @@ from pyformlang.regular_expression import Regex -class TestCFG(unittest.TestCase): - """ Tests the context free grammar """ +class TestCFG: + """ Tests for the context free grammar """ # pylint: disable=missing-function-docstring, too-many-public-methods @@ -23,18 +23,18 @@ def test_creation(self): terminal0 = Terminal("a") prod0 = Production(variable0, [terminal0, Terminal("A"), Variable(1)]) cfg = CFG({variable0}, {terminal0}, variable0, {prod0}) - self.assertIsNotNone(cfg) - self.assertEqual(len(cfg.variables), 2) - self.assertEqual(len(cfg.terminals), 2) - self.assertEqual(len(cfg.productions), 1) - self.assertTrue(cfg.is_empty()) + assert cfg is not None + assert len(cfg.variables) == 2 + assert len(cfg.terminals) == 2 + assert len(cfg.productions) == 1 + assert cfg.is_empty() cfg = CFG() - self.assertIsNotNone(cfg) - self.assertEqual(len(cfg.variables), 0) - self.assertEqual(len(cfg.terminals), 0) - self.assertEqual(len(cfg.productions), 0) - self.assertTrue(cfg.is_empty()) + assert cfg is not None + assert len(cfg.variables) == 0 + assert len(cfg.terminals) == 0 + assert len(cfg.productions) == 0 + assert cfg.is_empty() def test_generating_object(self): """ Test the finding of CFGObject """ @@ -48,21 +48,21 @@ def test_generating_object(self): prod2 = Production(var_a, [ter_b]) cfg = CFG({var_a, var_b, start}, {ter_a, ter_b}, start, {prod0, prod1, prod2}) - self.assertEqual(len(cfg.variables), 3) - self.assertEqual(len(cfg.terminals), 2) - self.assertEqual(len(cfg.productions), 3) - self.assertEqual(cfg.get_generating_symbols(), - {var_a, ter_a, ter_b, start}) + assert len(cfg.variables) == 3 + assert len(cfg.terminals) == 2 + assert len(cfg.productions) == 3 + assert cfg.get_generating_symbols() == \ + {var_a, ter_a, ter_b, start} prod3 = Production(var_b, [Epsilon()]) cfg = CFG({var_a, var_b, start}, {ter_a, ter_b}, start, {prod0, prod1, prod2, prod3}) - self.assertEqual(len(cfg.variables), 3) - self.assertEqual(len(cfg.terminals), 2) - self.assertEqual(len(cfg.productions), 4) - self.assertEqual(cfg.get_generating_symbols(), {var_a, var_b, ter_a, - ter_b, start}) + assert len(cfg.variables) == 3 + assert len(cfg.terminals) == 2 + assert len(cfg.productions) == 4 + assert cfg.get_generating_symbols() == \ + {var_a, var_b, ter_a, ter_b, start} def test_reachable_object(self): """ Test the finding of reachable objects """ @@ -81,8 +81,8 @@ def test_reachable_object(self): cfg = CFG({var_a, var_b, start, var_c}, {ter_a, ter_b, ter_c}, start, {prod0, prod1, prod2, prod3, prod4}) - self.assertEqual(cfg.get_reachable_symbols(), {var_a, ter_a, var_b, - ter_b, start}) + assert cfg.get_reachable_symbols() == \ + {var_a, ter_a, var_b, ter_b, start} def test_useless_removal(self): """ Test the removal of useless symbols """ @@ -97,10 +97,10 @@ def test_useless_removal(self): cfg = CFG({var_a, var_b, start}, {ter_a, ter_b}, start, {prod0, prod1, prod2}) new_cfg = cfg.remove_useless_symbols() - self.assertEqual(len(new_cfg.variables), 1) - self.assertEqual(len(new_cfg.terminals), 1) - self.assertEqual(len(new_cfg.productions), 1) - self.assertFalse(cfg.is_empty()) + assert len(new_cfg.variables) == 1 + assert len(new_cfg.terminals) == 1 + assert len(new_cfg.productions) == 1 + assert not cfg.is_empty() def test_nullable_object(self): """ Tests the finding of nullable objects """ @@ -117,8 +117,8 @@ def test_nullable_object(self): cfg = CFG({var_a, var_b, start}, {ter_a, ter_b}, start, {prod0, prod1, prod2, prod3, prod4}) - self.assertEqual(cfg.get_nullable_symbols(), - {var_a, var_b, start}) + assert cfg.get_nullable_symbols() == \ + {var_a, var_b, start} def test_remove_epsilon(self): """ Tests the removal of epsilon """ @@ -136,11 +136,11 @@ def test_remove_epsilon(self): {ter_a, ter_b}, start, {prod0, prod1, prod2, prod3, prod4}) new_cfg = cfg.remove_epsilon() - self.assertEqual(len(new_cfg.variables), 3) - self.assertEqual(len(new_cfg.terminals), 2) - self.assertEqual(len(set(new_cfg.productions)), 9) - self.assertEqual(len(new_cfg.get_nullable_symbols()), 0) - self.assertFalse(cfg.is_empty()) + assert len(new_cfg.variables) == 3 + assert len(new_cfg.terminals) == 2 + assert len(set(new_cfg.productions)) == 9 + assert len(new_cfg.get_nullable_symbols()) == 0 + assert not cfg.is_empty() def test_unit_pair(self): """ Test the finding of unit pairs """ @@ -174,19 +174,19 @@ def test_unit_pair(self): ter_par_close, ter_mult, ter_plus}, var_e, productions) - self.assertEqual(cfg.get_unit_pairs(), - {(var_e, var_e), - (var_e, var_t), - (var_e, var_f), - (var_e, var_i), - (var_t, var_t), - (var_t, var_f), - (var_t, var_i), - (var_f, var_f), - (var_f, var_i), - (var_i, var_i)}) + assert cfg.get_unit_pairs() == \ + {(var_e, var_e), + (var_e, var_t), + (var_e, var_f), + (var_e, var_i), + (var_t, var_t), + (var_t, var_f), + (var_t, var_i), + (var_f, var_f), + (var_f, var_i), + (var_i, var_i)} new_cfg = cfg.eliminate_unit_productions() - self.assertEqual(len(set(new_cfg.productions)), 30) + assert len(set(new_cfg.productions)) == 30 def test_cnf(self): """ Tests the conversion to CNF form """ @@ -221,20 +221,20 @@ def test_cnf(self): var_e, productions) new_cfg = cfg.to_normal_form() - self.assertEqual(len(new_cfg.variables), 15) - self.assertEqual(len(new_cfg.terminals), 8) - self.assertEqual(len(new_cfg.productions), 41) - self.assertFalse(cfg.is_empty()) + assert len(new_cfg.variables) == 15 + assert len(new_cfg.terminals) == 8 + assert len(new_cfg.productions) == 41 + assert not cfg.is_empty() new_cfg2 = cfg.to_normal_form() - self.assertEqual(new_cfg, new_cfg2) + assert new_cfg == new_cfg2 cfg2 = CFG(start_symbol=var_e, productions={Production(var_e, [var_t])}) new_cfg = cfg2.to_normal_form() - self.assertEqual(len(new_cfg.variables), 1) - self.assertEqual(len(new_cfg.terminals), 0) - self.assertEqual(len(new_cfg.productions), 0) - self.assertTrue(cfg2.is_empty()) + assert len(new_cfg.variables) == 1 + assert len(new_cfg.terminals) == 0 + assert len(new_cfg.productions) == 0 + assert cfg2.is_empty() def test_substitution(self): """ Tests substitutions in a CFG """ @@ -245,12 +245,11 @@ def test_substitution(self): prod1 = Production(var_s, []) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) new_cfg = cfg.substitute({ter_a: cfg}) - self.assertEqual(len(new_cfg.variables), 2) - self.assertEqual(len(new_cfg.terminals), 2) - self.assertEqual(len(new_cfg.productions), 4) - self.assertFalse(new_cfg.is_empty()) - self.assertTrue( - new_cfg.contains([ter_a, ter_b, ter_a, ter_b, ter_b, ter_b])) + assert len(new_cfg.variables) == 2 + assert len(new_cfg.terminals) == 2 + assert len(new_cfg.productions) == 4 + assert not new_cfg.is_empty() + assert new_cfg.contains([ter_a, ter_b, ter_a, ter_b, ter_b, ter_b]) def test_union(self): """ Tests the union of two cfg """ @@ -261,11 +260,11 @@ def test_union(self): prod1 = Production(var_s, []) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) new_cfg = cfg | cfg - self.assertEqual(len(new_cfg.variables), 3) - self.assertEqual(len(new_cfg.terminals), 2) - self.assertEqual(len(new_cfg.productions), 6) - self.assertFalse(new_cfg.is_empty()) - self.assertTrue(new_cfg.contains([ter_a, ter_a, ter_b, ter_b])) + assert len(new_cfg.variables) == 3 + assert len(new_cfg.terminals) == 2 + assert len(new_cfg.productions) == 6 + assert not new_cfg.is_empty() + assert new_cfg.contains([ter_a, ter_a, ter_b, ter_b]) def test_concatenation(self): """ Tests the concatenation of two cfg """ @@ -276,12 +275,11 @@ def test_concatenation(self): prod1 = Production(var_s, []) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) new_cfg = cfg + cfg - self.assertEqual(len(new_cfg.variables), 3) - self.assertEqual(len(new_cfg.terminals), 2) - self.assertEqual(len(new_cfg.productions), 5) - self.assertFalse(new_cfg.is_empty()) - self.assertTrue( - new_cfg.contains([ter_a, ter_a, ter_b, ter_b, ter_a, ter_b])) + assert len(new_cfg.variables) == 3 + assert len(new_cfg.terminals) == 2 + assert len(new_cfg.productions) == 5 + assert not new_cfg.is_empty() + assert new_cfg.contains([ter_a, ter_a, ter_b, ter_b, ter_a, ter_b]) def test_closure(self): """ Tests the closure of a cfg """ @@ -293,13 +291,13 @@ def test_closure(self): prod1 = Production(var_s, [ter_c]) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) new_cfg = cfg.get_closure() - self.assertEqual(len(new_cfg.variables), 2) - self.assertEqual(len(new_cfg.terminals), 3) - self.assertEqual(len(new_cfg.productions), 5) - self.assertFalse(new_cfg.is_empty()) - self.assertTrue(new_cfg.contains([])) - self.assertTrue(new_cfg.contains([ter_a, ter_a, ter_c, ter_b, ter_b, - ter_a, ter_c, ter_b])) + assert len(new_cfg.variables) == 2 + assert len(new_cfg.terminals) == 3 + assert len(new_cfg.productions) == 5 + assert not new_cfg.is_empty() + assert new_cfg.contains([]) + assert new_cfg.contains( + [ter_a, ter_a, ter_c, ter_b, ter_b, ter_a, ter_c, ter_b]) def test_pos_closure(self): """ Tests the closure of a cfg """ @@ -311,13 +309,13 @@ def test_pos_closure(self): prod1 = Production(var_s, [ter_c]) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) new_cfg = cfg.get_positive_closure() - self.assertEqual(len(new_cfg.variables), 3) - self.assertEqual(len(new_cfg.terminals), 3) - self.assertEqual(len(new_cfg.productions), 6) - self.assertFalse(new_cfg.is_empty()) - self.assertFalse(new_cfg.contains([])) - self.assertTrue(new_cfg.contains([ter_a, ter_a, ter_c, ter_b, ter_b, - ter_a, ter_c, ter_b])) + assert len(new_cfg.variables) == 3 + assert len(new_cfg.terminals) == 3 + assert len(new_cfg.productions) == 6 + assert not new_cfg.is_empty() + assert not new_cfg.contains([]) + assert new_cfg.contains( + [ter_a, ter_a, ter_c, ter_b, ter_b, ter_a, ter_c, ter_b]) def test_reverse(self): """ Test the reversal of a CFG """ @@ -328,11 +326,10 @@ def test_reverse(self): prod1 = Production(var_s, []) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) new_cfg = ~cfg - self.assertEqual(len(new_cfg.variables), 1) - self.assertEqual(len(new_cfg.terminals), 2) - self.assertEqual(len(new_cfg.productions), 2) - self.assertFalse(not new_cfg) - self.assertTrue(new_cfg.contains([ter_b, ter_b, ter_a, ter_a])) + assert len(new_cfg.variables) == 1 + assert len(new_cfg.terminals) == 2 + assert len(new_cfg.productions) == 2 + assert new_cfg.contains([ter_b, ter_b, ter_a, ter_a]) def test_emptiness(self): """ Tests the emptiness of a CFG """ @@ -343,7 +340,7 @@ def test_emptiness(self): prod0 = Production(var_s, [ter_a, var_s, ter_b]) prod1 = Production(var_s, []) cfg = CFG({var_s}, {ter_a, ter_b}, var_s, {prod0, prod1}) - self.assertFalse(cfg.is_empty()) + assert not cfg.is_empty() def test_membership(self): """ Tests the membership of a CFG """ @@ -361,18 +358,18 @@ def test_membership(self): prod5 = Production(var_useless, []) cfg0 = CFG({var_useless, var_s}, {ter_a, ter_b}, var_s, {prod0, prod1, prod2, prod4, prod5}) - self.assertTrue(cfg0.contains([Epsilon()])) - self.assertTrue(cfg0.contains([ter_a, ter_b])) - self.assertTrue(cfg0.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertTrue(cfg0.contains( - [ter_a, ter_a, ter_a, ter_b, ter_b, ter_b])) - self.assertFalse(cfg0.contains([ter_a, ter_b, ter_b])) - self.assertFalse(cfg0.contains([ter_a, ter_b, ter_c, ter_b])) - self.assertFalse(cfg0.contains([ter_a, ter_a, ter_a, ter_b, ter_b])) + assert cfg0.contains([Epsilon()]) + assert cfg0.contains([ter_a, ter_b]) + assert cfg0.contains([ter_a, ter_a, ter_b, ter_b]) + assert cfg0.contains( + [ter_a, ter_a, ter_a, ter_b, ter_b, ter_b]) + assert not cfg0.contains([ter_a, ter_b, ter_b]) + assert not cfg0.contains([ter_a, ter_b, ter_c, ter_b]) + assert not cfg0.contains([ter_a, ter_a, ter_a, ter_b, ter_b]) prod3 = Production(var_s, [ter_c]) cfg0 = CFG({var_s}, {ter_a, ter_b, ter_c}, var_s, {prod0, prod3}) - self.assertFalse(cfg0.contains([Epsilon()])) + assert not cfg0.contains([Epsilon()]) var_a = Variable("A") prod6 = Production(var_s, [var_a, var_b]) @@ -383,12 +380,12 @@ def test_membership(self): {ter_a, ter_b}, var_s, {prod6, prod7, prod8, prod9}) - self.assertTrue(cfg1.contains([ter_a, ter_b, ter_b])) + assert cfg1.contains([ter_a, ter_b, ter_b]) cfg1 = CFG({"A", "B", "S"}, {"a", "b"}, "S", {prod6, prod7, prod8, prod9}) - self.assertTrue(cfg1.contains(["a", "b", "b"])) + assert cfg1.contains(["a", "b", "b"]) def test_to_pda(self): """ Tests the conversion to PDA """ @@ -419,11 +416,11 @@ def test_to_pda(self): var_e, productions) pda_equivalent = cfg.to_pda() - self.assertEqual(len(pda_equivalent.states), 1) - self.assertEqual(len(pda_equivalent.final_states), 0) - self.assertEqual(len(pda_equivalent.input_symbols), 8) - self.assertEqual(len(pda_equivalent.stack_symbols), 10) - self.assertEqual(pda_equivalent.get_number_transitions(), 19) + assert len(pda_equivalent.states) == 1 + assert len(pda_equivalent.final_states) == 0 + assert len(pda_equivalent.input_symbols) == 8 + assert len(pda_equivalent.stack_symbols) == 10 + assert pda_equivalent.get_number_transitions() == 19 def test_conversions(self): """ Tests multiple conversions """ @@ -435,11 +432,11 @@ def test_conversions(self): Production(var_s, [ter_c])} cfg = CFG(productions=productions, start_symbol=var_s) cfg = cfg.to_pda().to_final_state().to_empty_stack().to_cfg() - self.assertTrue(cfg.contains([ter_c])) - self.assertTrue(cfg.contains([ter_a, ter_c, ter_b])) - self.assertTrue(cfg.contains([ter_a, ter_a, ter_c, ter_b, ter_b])) - self.assertFalse(cfg.contains([ter_b, ter_c, ter_a])) - self.assertFalse(cfg.contains([ter_b, ter_b, ter_c, ter_a, ter_a])) + assert cfg.contains([ter_c]) + assert cfg.contains([ter_a, ter_c, ter_b]) + assert cfg.contains([ter_a, ter_a, ter_c, ter_b, ter_b]) + assert not cfg.contains([ter_b, ter_c, ter_a]) + assert not cfg.contains([ter_b, ter_b, ter_c, ter_a, ter_a]) @staticmethod def test_profiling_conversions(): @@ -464,23 +461,23 @@ def test_generation_words(self): Production(var_s, [])} cfg = CFG(productions=productions, start_symbol=var_s) words0 = list(cfg.get_words(max_length=0)) - self.assertIn([], words0) - self.assertEqual(len(words0), 1) + assert [] in words0 + assert len(words0) == 1 words1 = list(cfg.get_words(max_length=1)) - self.assertIn([], words1) - self.assertEqual(len(words1), 1) + assert [] in words1 + assert len(words1) == 1 words2 = list(cfg.get_words(max_length=2)) - self.assertIn([], words2) - self.assertIn([ter_a, ter_b], words2) - self.assertEqual(len(words2), 2) + assert [] in words2 + assert [ter_a, ter_b] in words2 + assert len(words2) == 2 words3 = list(cfg.get_words(max_length=3)) - self.assertIn([], words3) - self.assertIn([ter_a, ter_b], words3) - self.assertEqual(len(words3), 2) + assert [] in words3 + assert [ter_a, ter_b] in words3 + assert len(words3) == 2 words4 = list(cfg.get_words(max_length=4)) - self.assertIn([], words4) - self.assertIn([ter_a, ter_a, ter_b, ter_b], words4) - self.assertEqual(len(words4), 3) + assert [] in words4 + assert [ter_a, ter_a, ter_b, ter_b] in words4 + assert len(words4) == 3 def test_generation_words2(self): """ Tests the generation of word """ @@ -495,10 +492,10 @@ def test_generation_words2(self): Production(var_s, [])} cfg = CFG(productions=productions, start_symbol=var_s) words0 = list(cfg.get_words()) - self.assertIn([], words0) - self.assertIn([ter_a], words0) - self.assertIn([ter_a, ter_a], words0) - self.assertEqual(len(words0), 3) + assert [] in words0 + assert [ter_a] in words0 + assert [ter_a, ter_a] in words0 + assert len(words0) == 3 def test_finite(self): """ Tests whether a grammar is finite or not """ @@ -511,10 +508,10 @@ def test_finite(self): Production(var_a, [ter_a]), Production(var_b, [ter_b])} cfg = CFG(productions=prod0, start_symbol=var_s) - self.assertTrue(cfg.is_finite()) + assert cfg.is_finite() prod0.add(Production(var_a, [var_s])) cfg = CFG(productions=prod0, start_symbol=var_s) - self.assertFalse(cfg.is_finite()) + assert not cfg.is_finite() def test_intersection(self): """ Tests the intersection with a regex """ @@ -522,8 +519,8 @@ def test_intersection(self): dfa = regex.to_epsilon_nfa() symb_a = Symbol("a") symb_b = Symbol("b") - self.assertTrue(dfa.accepts([symb_a, symb_a, symb_b, symb_b])) - self.assertFalse(dfa.accepts([symb_b, symb_b, symb_a])) + assert dfa.accepts([symb_a, symb_a, symb_b, symb_b]) + assert not dfa.accepts([symb_b, symb_b, symb_a]) ter_a = Terminal("a") ter_b = Terminal("b") var_s = Variable("S") @@ -531,16 +528,16 @@ def test_intersection(self): Production(var_s, [ter_b, var_s, ter_a]), Production(var_s, [])} cfg = CFG(productions=productions, start_symbol=var_s) - self.assertTrue(cfg.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertFalse(cfg.contains([ter_a, ter_a, ter_b])) + assert cfg.contains([ter_a, ter_a, ter_b, ter_b]) + assert not cfg.contains([ter_a, ter_a, ter_b]) cfg_i = cfg.intersection(regex) - self.assertTrue(cfg_i.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertFalse(cfg_i.contains([ter_a, ter_a, ter_b])) - self.assertTrue(cfg_i.contains([])) + assert cfg_i.contains([ter_a, ter_a, ter_b, ter_b]) + assert not cfg_i.contains([ter_a, ter_a, ter_b]) + assert cfg_i.contains([]) cfg_i = cfg.intersection(dfa) - self.assertTrue(cfg_i.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertFalse(cfg_i.contains([ter_a, ter_a, ter_b])) - self.assertTrue(cfg_i.contains([])) + assert cfg_i.contains([ter_a, ter_a, ter_b, ter_b]) + assert not cfg_i.contains([ter_a, ter_a, ter_b]) + assert cfg_i.contains([]) def test_intersection_empty(self): regex = Regex("") @@ -552,7 +549,7 @@ def test_intersection_empty(self): Production(var_s, [])} cfg = CFG(productions=productions, start_symbol=var_s) cfg_i = cfg & regex - self.assertFalse(cfg_i) + assert not cfg_i def test_intersection_dfa(self): state0 = State(0) @@ -566,8 +563,8 @@ def test_intersection_dfa(self): dfa.add_transition(state0, symb_a, state0) dfa.add_transition(state0, symb_b, state1) dfa.add_transition(state1, symb_b, state1) - self.assertTrue(dfa.accepts([symb_a, symb_a, symb_b, symb_b])) - self.assertFalse(dfa.accepts([symb_b, symb_b, symb_a])) + assert dfa.accepts([symb_a, symb_a, symb_b, symb_b]) + assert not dfa.accepts([symb_b, symb_b, symb_a]) ter_a = Terminal("a") ter_b = Terminal("b") @@ -576,12 +573,12 @@ def test_intersection_dfa(self): Production(var_s, [ter_b, var_s, ter_a]), Production(var_s, [])} cfg = CFG(productions=productions, start_symbol=var_s) - self.assertTrue(cfg.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertFalse(cfg.contains([ter_a, ter_a, ter_b])) + assert cfg.contains([ter_a, ter_a, ter_b, ter_b]) + assert not cfg.contains([ter_a, ter_a, ter_b]) cfg_i = cfg.intersection(dfa) - self.assertTrue(cfg_i.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertFalse(cfg_i.contains([ter_a, ter_a, ter_b])) - self.assertTrue(cfg_i.contains([])) + assert cfg_i.contains([ter_a, ter_a, ter_b, ter_b]) + assert not cfg_i.contains([ter_a, ter_a, ter_b]) + assert cfg_i.contains([]) def test_intersection_with_epsilon(self): state0 = State(0) @@ -592,7 +589,7 @@ def test_intersection_with_epsilon(self): start_state=state0, final_states={state1}) dfa.add_transition(state0, symb_a, state1) - self.assertTrue(dfa.accepts([symb_a])) + assert dfa.accepts([symb_a]) ter_a = Terminal("a") var_s = Variable("S") @@ -603,19 +600,19 @@ def test_intersection_with_epsilon(self): Production(var_t, [ter_a]), Production(var_t, [Epsilon()])} cfg = CFG(productions=productions, start_symbol=var_s) - self.assertFalse(cfg.is_empty()) - self.assertTrue(cfg.contains([ter_a])) + assert not cfg.is_empty() + assert cfg.contains([ter_a]) cfg_temp = cfg.to_pda().to_cfg() - self.assertFalse(cfg_temp.is_empty()) - self.assertTrue(cfg_temp.contains([ter_a])) + assert not cfg_temp.is_empty() + assert cfg_temp.contains([ter_a]) cfg_temp = cfg.to_pda().to_final_state().to_empty_stack().to_cfg() - self.assertFalse(cfg_temp.is_empty()) - self.assertTrue(cfg_temp.contains([ter_a])) + assert not cfg_temp.is_empty() + assert cfg_temp.contains([ter_a]) cfg_i = cfg.intersection(dfa) - self.assertFalse(cfg_i.is_empty()) + assert not cfg_i.is_empty() def test_intersection_dfa2(self): state0 = State(0) @@ -627,7 +624,7 @@ def test_intersection_dfa2(self): final_states={state0}) dfa.add_transition(state0, symb_a, state0) dfa.add_transition(state0, symb_b, state0) - self.assertTrue(dfa.accepts([symb_a, symb_a, symb_b, symb_b])) + assert dfa.accepts([symb_a, symb_a, symb_b, symb_b]) ter_a = Terminal("a") ter_b = Terminal("b") @@ -640,12 +637,12 @@ def test_intersection_dfa2(self): Production(var_s1, [ter_b, var_s1, ter_a]), Production(var_s1, [])} cfg = CFG(productions=productions, start_symbol=var_s) - self.assertTrue(cfg.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertFalse(cfg.contains([ter_a, ter_a, ter_b])) + assert cfg.contains([ter_a, ter_a, ter_b, ter_b]) + assert not cfg.contains([ter_a, ter_a, ter_b]) cfg_i = cfg.intersection(dfa) - self.assertFalse(cfg_i.is_empty()) - self.assertTrue(cfg_i.contains([ter_a, ter_a, ter_b, ter_b])) - self.assertTrue(cfg_i.contains([])) + assert not cfg_i.is_empty() + assert cfg_i.contains([ter_a, ter_a, ter_b, ter_b]) + assert cfg_i.contains([]) def test_profiling_intersection(self): size = 3 @@ -673,19 +670,18 @@ def test_profiling_intersection(self): Production(var_s1, [])] cfg = CFG(productions=productions, start_symbol=var_s) cfg_i = cfg.intersection(dfa) - self.assertFalse(cfg_i.is_empty()) - self.assertTrue(cfg_i.contains([ter_a] * size + [ter_b] * size)) - self.assertFalse(cfg_i.contains([])) + assert not cfg_i.is_empty() + assert cfg_i.contains([ter_a] * size + [ter_b] * size) + assert not cfg_i.contains([]) def test_pda_object_creator(self): pda_oc = PDAObjectCreator([], []) - self.assertEqual(pda_oc.get_symbol_from(Epsilon()), pda.Epsilon()) - self.assertEqual(pda_oc.get_stack_symbol_from(Epsilon()), - pda.Epsilon()) + assert pda_oc.get_symbol_from(Epsilon()) == pda.Epsilon() + assert pda_oc.get_stack_symbol_from(Epsilon()) == pda.Epsilon() def test_string_variable(self): var = Variable("A") - self.assertEqual(repr(var), "Variable(A)") + assert repr(var) == "Variable(A)" def test_get_leftmost_derivation(self): ter_a = Terminal("a") @@ -702,14 +698,14 @@ def test_get_leftmost_derivation(self): cfg = CFG(productions=productions, start_symbol=var_s) parse_tree = cfg.get_cnf_parse_tree([ter_a, ter_a, ter_b]) derivation = parse_tree.get_leftmost_derivation() - self.assertEqual(derivation, - [[var_s], - [var_c, var_b], - [var_a, var_a, var_b], - [ter_a, var_a, var_b], - [ter_a, ter_a, var_b], - [ter_a, ter_a, ter_b]]) - with self.assertRaises(DerivationDoesNotExist): + assert derivation == \ + [[var_s], + [var_c, var_b], + [var_a, var_a, var_b], + [ter_a, var_a, var_b], + [ter_a, ter_a, var_b], + [ter_a, ter_a, ter_b]] + with pytest.raises(DerivationDoesNotExist): cfg.get_cnf_parse_tree([]) def test_get_rightmost_derivation(self): @@ -727,20 +723,20 @@ def test_get_rightmost_derivation(self): cfg = CFG(productions=productions, start_symbol=var_s) parse_tree = cfg.get_cnf_parse_tree([ter_a, ter_a, ter_b]) derivation = parse_tree.get_rightmost_derivation() - self.assertEqual(derivation, - [[var_s], - [var_c, var_b], - [var_c, ter_b], - [var_a, var_a, ter_b], - [var_a, ter_a, ter_b], - [ter_a, ter_a, ter_b]]) + assert derivation == \ + [[var_s], + [var_c, var_b], + [var_c, ter_b], + [var_a, var_a, ter_b], + [var_a, ter_a, ter_b], + [ter_a, ter_a, ter_b]] def test_derivation_does_not_exist(self): var_s = Variable("S") ter_a = Terminal("a") ter_b = Terminal("b") cfg = CFG(productions=[], start_symbol=var_s) - with self.assertRaises(DerivationDoesNotExist): + with pytest.raises(DerivationDoesNotExist): parse_tree = cfg.get_cnf_parse_tree([ter_a, ter_b]) parse_tree.get_rightmost_derivation() @@ -750,7 +746,7 @@ def test_derivation_empty(self): cfg = CFG(productions=productions, start_symbol=var_s) parse_tree = cfg.get_cnf_parse_tree([]) derivation = parse_tree.get_rightmost_derivation() - self.assertEqual([[var_s], []], derivation) + assert [[var_s], []] == derivation def test_from_text(self): text = """ @@ -758,10 +754,10 @@ def test_from_text(self): A -> Bobo r """ cfg = CFG.from_text(text) - self.assertEqual(len(cfg.variables), 4) - self.assertEqual(len(cfg.productions), 2) - self.assertEqual(len(cfg.terminals), 1) - self.assertEqual(cfg.start_symbol, Variable("S")) + assert len(cfg.variables) == 4 + assert len(cfg.productions) == 2 + assert len(cfg.terminals) == 1 + assert cfg.start_symbol == Variable("S") def test_from_text2(self): text = """ @@ -769,91 +765,92 @@ def test_from_text2(self): B -> b\r """ cfg = CFG.from_text(text) - self.assertTrue(cfg.contains(["a", "b"])) - self.assertTrue(["a", "b"] in cfg) + assert cfg.contains(["a", "b"]) + assert ["a", "b"] in cfg def test_from_text_union(self): text = """ "VAR:S" -> TER:a | b """ cfg = CFG.from_text(text) - self.assertEqual(2, len(cfg.productions)) + assert 2 == len(cfg.productions) def test_epsilon(self): text = "S -> epsilon" cfg = CFG.from_text(text) - self.assertTrue(cfg.generate_epsilon()) - self.assertEqual(len(cfg.terminals), 0) + assert cfg.generate_epsilon() + assert len(cfg.terminals) == 0 def test_epsilon2(self): text = "S ->$" cfg = CFG.from_text(text) - self.assertTrue(cfg.generate_epsilon()) + assert cfg.generate_epsilon() def test_generate_epsilon(self): var_s = Variable("S") ter_a = Terminal("a") productions = [Production(var_s, [ter_a])] cfg = CFG(productions=productions, start_symbol=var_s) - self.assertFalse(cfg.generate_epsilon()) + assert not cfg.generate_epsilon() def test_change_starting_variable(self): text = """S1 -> a""" cfg = CFG.from_text(text, start_symbol="S1") - self.assertEqual(Variable("S1"), cfg.start_symbol) + assert Variable("S1") == cfg.start_symbol def test_is_not_normal_form(self): text = get_example_text_duplicate() cfg = CFG.from_text(text, start_symbol="E") - self.assertFalse(cfg.is_normal_form()) + assert not cfg.is_normal_form() def test_is_normal_form(self): text = """ - E -> T E’ - E’ -> T E’ - T -> F T’ - T’ -> * - F -> ( | id - """ + E -> T E’ + E’ -> T E’ + T -> F T’ + T’ -> * + F -> ( | id + """ cfg = CFG.from_text(text, start_symbol="E") - self.assertTrue(cfg.is_normal_form()) + assert cfg.is_normal_form() def test_to_text(self): - text = """E -> T E’ + text = """ + E -> T E’ E’ -> T E’ T -> F T’ T’ -> * F -> ( | id - """ + """ text_result = CFG.from_text(text, start_symbol="E").to_text() - self.assertIn("E -> T E’", text_result) - self.assertIn("E’ -> T E’", text_result) - self.assertIn("T -> F T’", text_result) - self.assertIn("T’ -> *", text_result) - self.assertIn("F -> (", text_result) - self.assertIn("F -> id", text_result) + assert "E -> T E’" in text_result + assert "E’ -> T E’" in text_result + assert "T -> F T’" in text_result + assert "T’ -> *" in text_result + assert "F -> (" in text_result + assert "F -> id" in text_result def test_to_text_cnf(self): cfg = CFG.from_text("S -> a S b | a b") cnf = cfg.to_normal_form() - self.assertTrue(cnf.contains(["a", "b"])) + assert cnf.contains(["a", "b"]) new_text = cnf.to_text() print(new_text) new_cfg = CFG.from_text(new_text) - self.assertTrue(new_cfg.contains(["a", "b"])) + assert new_cfg.contains(["a", "b"]) def test_to_text_epsilon(self): cfg = CFG.from_text("S -> a S b | a b epsilon") - self.assertTrue(cfg.contains(["a", "b"])) + assert cfg.contains(["a", "b"]) def get_example_text_duplicate(): """ Duplicate text """ text = """ - E -> T E’ - E’ -> + T E’ | Є - T -> F T’ - T’ -> * F T’ | Є - F -> ( E ) | id - """ + E -> T E’ + E’ -> + T E’ | Є + T -> F T’ + T’ -> * F T’ | Є + F -> ( E ) | id + """ return text diff --git a/pyformlang/cfg/tests/test_llone_parser.py b/pyformlang/cfg/tests/test_llone_parser.py index 28770b3..f439c3a 100644 --- a/pyformlang/cfg/tests/test_llone_parser.py +++ b/pyformlang/cfg/tests/test_llone_parser.py @@ -1,8 +1,5 @@ -""" -Test for LL(1) parser -""" +""" Tests for the LL(1) parser """ -import unittest from os import path from pyformlang.cfg import CFG, Variable, Terminal, Epsilon @@ -11,8 +8,8 @@ from pyformlang.regular_expression import Regex -class TestLLOneParser(unittest.TestCase): - """ Tests the LL(1) Parser """ +class TestLLOneParser: + """ Tests for the LL(1) Parser """ # pylint: disable=missing-function-docstring, too-many-public-methods @@ -23,16 +20,11 @@ def test_get_first_set(self): cfg = CFG.from_text(text) llone_parser = LLOneParser(cfg) first_set = llone_parser.get_first_set() - self.assertEqual(first_set[Variable("E")], - {Terminal("("), Terminal("id")}) - self.assertEqual(first_set[Variable("E’")], - {Terminal("+"), Epsilon()}) - self.assertEqual(first_set[Variable("T")], - {Terminal("("), Terminal("id")}) - self.assertEqual(first_set[Variable("T’")], - {Terminal("*"), Epsilon()}) - self.assertEqual(first_set[Variable("F")], - {Terminal("("), Terminal("id")}) + assert first_set[Variable("E")] == {Terminal("("), Terminal("id")} + assert first_set[Variable("E’")] == {Terminal("+"), Epsilon()} + assert first_set[Variable("T")] == {Terminal("("), Terminal("id")} + assert first_set[Variable("T’")] == {Terminal("*"), Epsilon()} + assert first_set[Variable("F")] == {Terminal("("), Terminal("id")} def test_get_first_set2(self): # Example from: @@ -46,16 +38,15 @@ def test_get_first_set2(self): cfg = CFG.from_text(text) llone_parser = LLOneParser(cfg) first_set = llone_parser.get_first_set() - self.assertEqual(first_set[Variable("S")], - {Terminal(x) for x in ("d", "g", "h", "b", - "a")}.union({Epsilon()})) - self.assertEqual(first_set[Variable("A")], - {Terminal(x) for x in ("d", "g", - "h")}.union({Epsilon()})) - self.assertEqual(first_set[Variable("B")], - {Terminal(x) for x in ["g"]}.union({Epsilon()})) - self.assertEqual(first_set[Variable("C")], - {Terminal(x) for x in ["h"]}.union({Epsilon()})) + assert first_set[Variable("S")] == \ + {Terminal(x) for x in ( + "d", "g", "h", "b", "a")}.union({Epsilon()}) + assert first_set[Variable("A")] == \ + {Terminal(x) for x in ("d", "g", "h")}.union({Epsilon()}) + assert first_set[Variable("B")] == \ + {Terminal(x) for x in ["g"]}.union({Epsilon()}) + assert first_set[Variable("C")] == \ + {Terminal(x) for x in ["h"]}.union({Epsilon()}) def test_get_follow_set(self): # Example from: @@ -64,16 +55,14 @@ def test_get_follow_set(self): cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) follow_set = llone_parser.get_follow_set() - self.assertEqual(follow_set[Variable("E")], - {"$", Terminal(")")}) - self.assertEqual(follow_set[Variable("E’")], - {"$", Terminal(")")}) - self.assertEqual(follow_set[Variable("T")], - {"$", Terminal("+"), Terminal(")")}) - self.assertEqual(follow_set[Variable("T’")], - {"$", Terminal("+"), Terminal(")")}) - self.assertEqual(follow_set[Variable("F")], - {"$", Terminal("+"), Terminal("*"), Terminal(")")}) + assert follow_set[Variable("E")] == {"$", Terminal(")")} + assert follow_set[Variable("E’")] == {"$", Terminal(")")} + assert follow_set[Variable("T")] == \ + {"$", Terminal("+"), Terminal(")")} + assert follow_set[Variable("T’")] == \ + {"$", Terminal("+"), Terminal(")")} + assert follow_set[Variable("F")] == \ + {"$", Terminal("+"), Terminal("*"), Terminal(")")} def test_get_follow_set2(self): # Example from: @@ -88,14 +77,13 @@ def test_get_follow_set2(self): llone_parser = LLOneParser(cfg) follow_set = llone_parser.get_follow_set() print(follow_set) - self.assertEqual(follow_set["S"], - {"$"}) - self.assertEqual(follow_set["A"], - {"$", Terminal("h"), Terminal("g")}) - self.assertEqual(follow_set["B"], - {"$", Terminal("h"), Terminal("g"), Terminal("a")}) - self.assertEqual(follow_set["C"], - {"$", Terminal("h"), Terminal("g"), Terminal("b")}) + assert follow_set["S"] == {"$"} + assert follow_set["A"] == \ + {"$", Terminal("h"), Terminal("g")} + assert follow_set["B"] == \ + {"$", Terminal("h"), Terminal("g"), Terminal("a")} + assert follow_set["C"] == \ + {"$", Terminal("h"), Terminal("g"), Terminal("b")} def test_get_llone_table(self): # Example from: @@ -104,26 +92,16 @@ def test_get_llone_table(self): cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) parsing_table = llone_parser.get_llone_parsing_table() - self.assertEqual( - len(parsing_table.get(Variable("E"), {}) - .get(Terminal("id"), [])), - 1) - self.assertEqual( - len(parsing_table.get(Variable("E"), {}) - .get(Terminal("+"), [])), - 0) - self.assertEqual( - len(parsing_table.get(Variable("T’"), {}) - .get(Terminal(")"), [])), - 1) - self.assertEqual( - len(parsing_table.get(Variable("F"), {}) - .get(Terminal("("), [])), - 1) - self.assertEqual( - len(parsing_table.get(Variable("F"), {}) - .get(Terminal("id"), [])), - 1) + assert len(parsing_table.get(Variable("E"), {}) \ + .get(Terminal("id"), [])) == 1 + assert len(parsing_table.get(Variable("E"), {}) \ + .get(Terminal("+"), [])) == 0 + assert len(parsing_table.get(Variable("T’"), {}) \ + .get(Terminal(")"), [])) == 1 + assert len(parsing_table.get(Variable("F"), {}) \ + .get(Terminal("("), [])) == 1 + assert len(parsing_table.get(Variable("F"), {}) \ + .get(Terminal("id"), [])) == 1 def test_llone_table_non_llone(self): text = """ @@ -133,22 +111,14 @@ def test_llone_table_non_llone(self): cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) parsing_table = llone_parser.get_llone_parsing_table() - self.assertEqual( - len(parsing_table.get(Variable("S"), {}) - .get(Terminal("a"), [])), - 2) - self.assertEqual( - len(parsing_table.get(Variable("A"), {}) - .get(Terminal("a"), [])), - 1) - self.assertEqual( - len(parsing_table.get(Variable("S"), {}) - .get(Terminal("$"), [])), - 0) - self.assertEqual( - len(parsing_table.get(Variable("A"), {}) - .get(Terminal("$"), [])), - 0) + assert len(parsing_table.get(Variable("S"), {}) \ + .get(Terminal("a"), [])) == 2 + assert len(parsing_table.get(Variable("A"), {}) \ + .get(Terminal("a"), [])) == 1 + assert len(parsing_table.get(Variable("S"), {}) \ + .get(Terminal("$"), [])) == 0 + assert len(parsing_table.get(Variable("A"), {}) \ + .get(Terminal("$"), [])) == 0 def test_is_llone_parsable(self): # Example from: @@ -156,36 +126,35 @@ def test_is_llone_parsable(self): text = get_example_text_duplicate() cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) - self.assertTrue(llone_parser.is_llone_parsable()) + assert llone_parser.is_llone_parsable() def test_is_not_llone_parsable(self): # Example from: # https://www.geeksforgeeks.org/construction-of-ll1-parsing-table/ text = """ - S -> A | a - A -> a - """ + S -> A | a + A -> a + """ cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) - self.assertFalse(llone_parser.is_llone_parsable()) + assert not llone_parser.is_llone_parsable() def test_get_llone_parse_tree(self): text = get_example_text_duplicate() cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) - parse_tree = llone_parser.get_llone_parse_tree(["id", "+", "id", - "*", "id"]) - self.assertEqual(parse_tree.value, Variable("E")) - self.assertEqual(len(parse_tree.sons), 2) + parse_tree = llone_parser.get_llone_parse_tree( + ["id", "+", "id", "*", "id"]) + assert parse_tree.value == Variable("E") + assert len(parse_tree.sons) == 2 def test_get_llone_leftmost_derivation(self): text = get_example_text_duplicate() cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) - parse_tree = llone_parser.get_llone_parse_tree(["id", "+", "id", - "*", "id"]) - self.assertEqual( - parse_tree.get_leftmost_derivation(), + parse_tree = llone_parser.get_llone_parse_tree( + ["id", "+", "id", "*", "id"]) + assert parse_tree.get_leftmost_derivation() == \ [[Variable("E")], [Variable("T"), Variable("E’")], [Variable("F"), Variable("T’"), Variable("E’")], @@ -203,17 +172,16 @@ def test_get_llone_leftmost_derivation(self): [Terminal("id"), Terminal("+"), Terminal("id"), Terminal("*"), Terminal("id"), Variable("E’")], [Terminal("id"), Terminal("+"), Terminal("id"), Terminal("*"), - Terminal("id")] - ]) + Terminal("id")], + ] def test_get_llone_rightmost_derivation(self): text = get_example_text_duplicate() cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) - parse_tree = llone_parser.get_llone_parse_tree(["id", "+", "id", - "*", "id"]) - self.assertEqual( - parse_tree.get_rightmost_derivation(), + parse_tree = llone_parser.get_llone_parse_tree( + ["id", "+", "id", "*", "id"]) + assert parse_tree.get_rightmost_derivation() == \ [[Variable("E")], [Variable("T"), Variable("E’")], [Variable("T"), Terminal("+"), Variable("T"), Variable("E’")], @@ -233,22 +201,22 @@ def test_get_llone_rightmost_derivation(self): Terminal("*"), Terminal("id")], [Terminal("id"), Terminal("+"), Terminal("id"), Terminal("*"), Terminal("id")], - ]) + ] def test_save_tree(self): text = """ - E -> T E' - E' -> + T E' | epsilon - T -> F T' - T' -> * F T' | epsilon - F -> ( E ) | id - """ + E -> T E' + E' -> + T E' | epsilon + T -> F T' + T' -> * F T' | epsilon + F -> ( E ) | id + """ cfg = CFG.from_text(text, start_symbol="E") llone_parser = LLOneParser(cfg) - parse_tree = llone_parser.get_llone_parse_tree(["id", "+", "id", - "*", "id"]) + parse_tree = llone_parser.get_llone_parse_tree( + ["id", "+", "id", "*", "id"]) parse_tree.write_as_dot("parse_tree.dot") - self.assertTrue(path.exists("parse_tree.dot")) + assert path.exists("parse_tree.dot") def test_sentence_cfg(self): cfg = CFG.from_text(""" @@ -262,20 +230,17 @@ def test_sentence_cfg(self): """) regex = Regex("georges touches (a|an) (sky|gorilla) !") cfg_inter = cfg.intersection(regex) - self.assertFalse(cfg_inter.is_empty()) - self.assertTrue(cfg_inter.is_finite()) - self.assertFalse( - cfg_inter.contains(["georges", "sees", "a", "gorilla", "."])) - self.assertTrue( - cfg_inter.contains(["georges", "touches", "a", "gorilla", "!"])) - self.assertFalse(cfg_inter.is_normal_form()) + assert not cfg_inter.is_empty() + assert cfg_inter.is_finite() + assert not cfg_inter.contains(["georges", "sees", "a", "gorilla", "."]) + assert cfg_inter.contains(["georges", "touches", "a", "gorilla", "!"]) + assert not cfg_inter.is_normal_form() cnf = cfg.to_normal_form() - self.assertTrue(cnf.is_normal_form()) + assert cnf.is_normal_form() llone_parser = LLOneParser(cfg) - parse_tree = llone_parser.get_llone_parse_tree(["georges", "sees", - "a", "gorilla", "."]) - self.assertEqual( - parse_tree.get_leftmost_derivation(), + parse_tree = llone_parser.get_llone_parse_tree( + ["georges", "sees", "a", "gorilla", "."]) + assert parse_tree.get_leftmost_derivation() == \ [[Variable("S")], [Variable("NP"), Variable("VP"), Variable("PUNC")], [Terminal("georges"), Variable("VP"), Variable("PUNC")], @@ -291,9 +256,4 @@ def test_sentence_cfg(self): Terminal("gorilla"), Variable("PUNC")], [Terminal("georges"), Terminal("sees"), Terminal("a"), Terminal("gorilla"), Terminal(".")]] - ) parse_tree.write_as_dot("parse_tree.dot") - - -if __name__ == '__main__': - unittest.main() diff --git a/pyformlang/cfg/tests/test_production.py b/pyformlang/cfg/tests/test_production.py index 7d85093..c6be153 100644 --- a/pyformlang/cfg/tests/test_production.py +++ b/pyformlang/cfg/tests/test_production.py @@ -1,12 +1,10 @@ -""" Tests the productions """ - -import unittest +""" Tests for productions """ from pyformlang.cfg import Production, Variable, Terminal -class TestProduction(unittest.TestCase): - """ Tests the production """ +class TestProduction: + """ Tests for productions """ # pylint: disable=missing-function-docstring def test_creation(self): @@ -15,16 +13,16 @@ def test_creation(self): prod2 = Production(Variable("S0'"), [Terminal("S1"), Variable("a")]) prod3 = Production(Variable("S0"), [Terminal("S2"), Variable("a")]) prod4 = Production(Variable("S0"), [Terminal("S2"), Variable("b")]) - self.assertEqual(prod0, prod1) - self.assertNotEqual(prod0, prod2) - self.assertNotEqual(prod0, prod3) - self.assertNotEqual(prod0, prod4) - self.assertEqual(str(prod0), str(prod1)) - self.assertNotEqual(str(prod0), str(prod2)) - self.assertNotEqual(str(prod0), str(prod3)) - self.assertNotEqual(str(prod0), str(prod4)) - self.assertEqual(hash(prod0), hash(prod1)) - self.assertNotEqual(hash(prod0), hash(prod2)) - self.assertNotEqual(hash(prod0), hash(prod3)) - self.assertNotEqual(hash(prod0), hash(prod4)) - self.assertIn(" -> ", str(prod0)) + assert prod0 == prod1 + assert prod0 != prod2 + assert prod0 != prod3 + assert prod0 != prod4 + assert str(prod0) == str(prod1) + assert str(prod0) != str(prod2) + assert str(prod0) != str(prod3) + assert str(prod0) != str(prod4) + assert hash(prod0) == hash(prod1) + assert hash(prod0) != hash(prod2) + assert hash(prod0) != hash(prod3) + assert hash(prod0) != hash(prod4) + assert " -> " in str(prod0) diff --git a/pyformlang/cfg/tests/test_recursive_decent_parser.py b/pyformlang/cfg/tests/test_recursive_decent_parser.py index dca8a83..f95dd5f 100644 --- a/pyformlang/cfg/tests/test_recursive_decent_parser.py +++ b/pyformlang/cfg/tests/test_recursive_decent_parser.py @@ -1,16 +1,18 @@ # pylint: disable=missing-module-docstring # pylint: disable=missing-class-docstring # pylint: disable=missing-function-docstring -import unittest +# pylint: disable=attribute-defined-outside-init + +import pytest from pyformlang.cfg import CFG, Variable, Terminal from pyformlang.cfg.cfg import NotParsableException from pyformlang.cfg.recursive_decent_parser import RecursiveDecentParser -class TestRecursiveDecentParser(unittest.TestCase): +class TestRecursiveDecentParser: - def setUp(self) -> None: + def setup_method(self) -> None: cfg = CFG.from_text(""" E -> S + S E -> S * S @@ -20,17 +22,15 @@ def setUp(self) -> None: self.parser = RecursiveDecentParser(cfg) def test_creation(self): - self.assertIsNotNone(self.parser) + assert self.parser is not None def test_get_parsing_tree(self): - self.assertTrue(self.parser.is_parsable( - ["(", "int", "+", "(", "int", "*", "int", ")", ")"] - )) + assert self.parser.is_parsable( + ["(", "int", "+", "(", "int", "*", "int", ")", ")"]) parse_tree = self.parser.get_parse_tree( ["(", "int", "+", "(", "int", "*", "int", ")", ")"]) derivation = parse_tree.get_leftmost_derivation() - self.assertEqual( - derivation, + assert derivation == \ [[Variable("S")], [Terminal("("), Variable("E"), Terminal(")")], [Terminal("("), Variable("S"), Terminal("+"), Variable("S"), @@ -48,18 +48,16 @@ def test_get_parsing_tree(self): [Terminal("("), Terminal("int"), Terminal("+"), Terminal("("), Terminal("int"), Terminal("*"), Terminal("int"), Terminal(")"), Terminal(")")], - ]) + ] def test_no_parse_tree(self): - with self.assertRaises(NotParsableException): + with pytest.raises(NotParsableException): self.parser.get_parse_tree([")"]) - self.assertFalse((self.parser.is_parsable([")"]))) + assert not self.parser.is_parsable([")"]) def test_infinite_recursion(self): - cfg = CFG.from_text(""" - S -> S E - """) + cfg = CFG.from_text("S -> S E") parser = RecursiveDecentParser(cfg) - with self.assertRaises(RecursionError): + with pytest.raises(RecursionError): parser.is_parsable([")"]) - self.assertFalse(parser.is_parsable([")"], left=False)) + assert not parser.is_parsable([")"], left=False) diff --git a/pyformlang/cfg/tests/test_terminal.py b/pyformlang/cfg/tests/test_terminal.py index 839587a..4716f80 100644 --- a/pyformlang/cfg/tests/test_terminal.py +++ b/pyformlang/cfg/tests/test_terminal.py @@ -1,12 +1,10 @@ -""" Tests the terminal """ - -import unittest +""" Tests for the terminal """ from pyformlang.cfg import Terminal, Epsilon -class TestTerminal(unittest.TestCase): - """ Tests the terminal """ +class TestTerminal: + """ Tests for the terminal """ # pylint: disable=missing-function-docstring def test_creation(self): @@ -14,14 +12,14 @@ def test_creation(self): terminal1 = Terminal(1) terminal2 = Terminal(0) terminal3 = Terminal("0") - self.assertEqual(terminal0, terminal2) - self.assertNotEqual(terminal0, terminal1) - self.assertNotEqual(terminal0, terminal3) - self.assertEqual(hash(terminal0), hash(terminal2)) - self.assertNotEqual(hash(terminal0), hash(terminal1)) - self.assertEqual(str(terminal0), str(terminal2)) - self.assertEqual(str(terminal0), str(terminal3)) - self.assertNotEqual(str(terminal0), str(terminal1)) + assert terminal0 == terminal2 + assert terminal0 != terminal1 + assert terminal0 != terminal3 + assert hash(terminal0) == hash(terminal2) + assert hash(terminal0) != hash(terminal1) + assert str(terminal0) == str(terminal2) + assert str(terminal0) == str(terminal3) + assert str(terminal0) != str(terminal1) epsilon = Epsilon() - self.assertEqual(epsilon.to_text(), "epsilon") - self.assertEqual(Terminal("C").to_text(), '"TER:C"') + assert epsilon.to_text() == "epsilon" + assert Terminal("C").to_text() == '"TER:C"' diff --git a/pyformlang/cfg/tests/test_variable.py b/pyformlang/cfg/tests/test_variable.py index 95179c9..173c55c 100644 --- a/pyformlang/cfg/tests/test_variable.py +++ b/pyformlang/cfg/tests/test_variable.py @@ -1,12 +1,10 @@ -""" Tests the variable """ - -import unittest +""" Tests for variables """ from pyformlang.cfg import Variable -class TestVariable(unittest.TestCase): - """ Tests the variable """ +class TestVariable: + """ Tests for variables """ # pylint: disable=missing-function-docstring def test_creation(self): @@ -14,11 +12,11 @@ def test_creation(self): variable1 = Variable(1) variable2 = Variable(0) variable3 = Variable("0") - self.assertEqual(variable0, variable2) - self.assertNotEqual(variable0, variable1) - self.assertNotEqual(variable0, variable3) - self.assertEqual(hash(variable0), hash(variable2)) - self.assertNotEqual(hash(variable0), hash(variable1)) - self.assertEqual(str(variable0), str(variable2)) - self.assertEqual(str(variable0), str(variable3)) - self.assertNotEqual(str(variable0), str(variable1)) + assert variable0 == variable2 + assert variable0 != variable1 + assert variable0 != variable3 + assert hash(variable0) == hash(variable2) + assert hash(variable0) != hash(variable1) + assert str(variable0) == str(variable2) + assert str(variable0) == str(variable3) + assert str(variable0) != str(variable1) diff --git a/pyformlang/fcfg/tests/test_fcfg.py b/pyformlang/fcfg/tests/test_fcfg.py index f6a3348..4f45660 100644 --- a/pyformlang/fcfg/tests/test_fcfg.py +++ b/pyformlang/fcfg/tests/test_fcfg.py @@ -1,5 +1,6 @@ -"""Test a FCFG""" -import unittest +""" Test for the FCFG """ + +import pytest from pyformlang.cfg import Variable, Terminal from pyformlang.cfg.cfg import NotParsableException @@ -10,11 +11,11 @@ from pyformlang.fcfg.state import State, StateProcessed -class TestFCFG(unittest.TestCase): - """Test a FCFG""" +class TestFCFG: + """ Tests for the FCFG """ def test_contains(self): - """Test containment""" + """ Test containment """ # 1st: S -> NP VP agreement = FeatureStructure() np_feat = FeatureStructure() @@ -32,7 +33,8 @@ def test_contains(self): np_feat = FeatureStructure() np_feat.add_content("AGREEMENT", agreement) fp2 = FeatureProduction(Variable("S"), - [Variable("Aux"), Variable("NP"), Variable("VP")], + [Variable("Aux"), + Variable("NP"), Variable("VP")], FeatureStructure(), [aux_feat, np_feat, FeatureStructure()]) # Third: NP -> Det Nominal @@ -95,7 +97,7 @@ def test_contains(self): [Variable("Verb")], vp_feat, [verb_feat]) - self.assertIn("AGREEMENT", str(fp8)) + assert "AGREEMENT" in str(fp8) # 9: Verb -> serve agreement = FeatureStructure() agreement.add_content("NUMBER", FeatureStructure("pl")) @@ -149,15 +151,15 @@ def test_contains(self): self._sub_tests_contains1(fcfg) def _sub_tests_contains1(self, fcfg): - self.assertTrue(fcfg.contains(["this", "flight", "serves"])) - self.assertTrue(["this", "flight", "serves"] in fcfg) - self.assertTrue(fcfg.contains(["these", "flights", "serve"])) - self.assertFalse(fcfg.contains(["this", "flights", "serves"])) - self.assertFalse(fcfg.contains(["this", "flight", "serve"])) - self.assertFalse(fcfg.contains(["this", "flights", "serve"])) + assert fcfg.contains(["this", "flight", "serves"]) + assert ["this", "flight", "serves"] in fcfg + assert fcfg.contains(["these", "flights", "serve"]) + assert not fcfg.contains(["this", "flights", "serves"]) + assert not fcfg.contains(["this", "flight", "serve"]) + assert not fcfg.contains(["this", "flights", "serve"]) def test_contains2(self): - """Test containment""" + """ Test containment """ # 1st: S -> NP number = FeatureStructure("sg") np_feat = FeatureStructure() @@ -174,22 +176,26 @@ def test_contains2(self): [Terminal("flights")], np_feat, [FeatureStructure()]) - self.assertIn("NUMBER", str(fp2)) + assert "NUMBER" in str(fp2) fcfg = FCFG(start_symbol=Variable("S"), productions=[fp1, fp2]) - self.assertFalse(fcfg.contains(["flights"])) + assert not fcfg.contains(["flights"]) def test_state(self): - """Test functions on states""" + """ Test functions on states """ fs1 = FeatureStructure() fs1.add_content("NUMBER", FeatureStructure("sg")) - state0 = State(FeatureProduction(Variable("S"), [], FeatureStructure, []), (0, 0, 0), fs1, ParseTree("S")) + state0 = State( + FeatureProduction(Variable("S"), [], FeatureStructure, []), + (0, 0, 0), fs1, ParseTree("S")) processed = StateProcessed(1) - state1 = State(FeatureProduction(Variable("S"), [], FeatureStructure, []), (0, 0, 0), fs1, ParseTree("S")) - self.assertTrue(processed.add(0, state0)) - self.assertFalse(processed.add(0, state1)) + state1 = State( + FeatureProduction(Variable("S"), [], FeatureStructure, []), + (0, 0, 0), fs1, ParseTree("S")) + assert processed.add(0, state0) + assert not processed.add(0, state1) def test_from_text(self): - """Test containment from a text description""" + """ Test containment from a text description """ fcfg = FCFG.from_text(""" S -> NP[AGREEMENT=?a] VP[AGREEMENT=?a] S -> Aux[AGREEMENT=?a] NP[AGREEMENT=?a] VP @@ -207,6 +213,6 @@ def test_from_text(self): """) self._sub_tests_contains1(fcfg) parse_tree = fcfg.get_parse_tree(["this", "flight", "serves"]) - with self.assertRaises(NotParsableException): + with pytest.raises(NotParsableException): fcfg.get_parse_tree(["these", "flight", "serves"]) - self.assertIn("Det", str(parse_tree)) + assert "Det" in str(parse_tree) diff --git a/pyformlang/fcfg/tests/test_feature_structure.py b/pyformlang/fcfg/tests/test_feature_structure.py index b0d1025..b6c0c18 100644 --- a/pyformlang/fcfg/tests/test_feature_structure.py +++ b/pyformlang/fcfg/tests/test_feature_structure.py @@ -1,88 +1,94 @@ -"""Testing of the feature structure""" -import unittest +""" Tests for the feature structure """ -from pyformlang.fcfg.feature_structure import FeatureStructure, PathDoesNotExistsException, \ +import pytest + +from pyformlang.fcfg.feature_structure import \ + FeatureStructure, PathDoesNotExistsException, \ ContentAlreadyExistsException, FeatureStructuresNotCompatibleException def _get_agreement_subject_number_person(): - fs2 = FeatureStructure.from_text("AGREEMENT=(1)[NUMBER=sg, PERSON=3], SUBJECT=[AGREEMENT->(1)]") + fs2 = FeatureStructure.from_text( + "AGREEMENT=(1)[NUMBER=sg, PERSON=3], SUBJECT=[AGREEMENT->(1)]") return fs2 -class TestFeatureStructure(unittest.TestCase): - """Testing of the feature structure""" +class TestFeatureStructure: + """ Tests for the feature structure """ def test_creation(self): - """Test of creation""" + """ Test of creation """ feature_structure = FeatureStructure() - self.assertEqual(len(feature_structure.content), 0) - self.assertEqual(feature_structure.pointer, None) - self.assertEqual(feature_structure.get_feature_by_path().value, None) - with self.assertRaises(PathDoesNotExistsException): + assert len(feature_structure.content) == 0 + assert feature_structure.pointer is None + assert feature_structure.get_feature_by_path().value is None + with pytest.raises(PathDoesNotExistsException): feature_structure.get_feature_by_path(["NUMBER"]) feature_structure.add_content("NUMBER", FeatureStructure("sg")) - self.assertEqual(feature_structure.get_feature_by_path(["NUMBER"]).value, "sg") - with self.assertRaises(ContentAlreadyExistsException): + assert feature_structure.get_feature_by_path(["NUMBER"]).value == "sg" + with pytest.raises(ContentAlreadyExistsException): feature_structure.add_content("NUMBER", FeatureStructure("sg")) feature_structure = _get_agreement_subject_number_person() - self.assertEqual(feature_structure.get_feature_by_path(["SUBJECT", "AGREEMENT", "NUMBER"]).value, "sg") + assert feature_structure.get_feature_by_path( + ["SUBJECT", "AGREEMENT", "NUMBER"]).value == "sg" def test_unify1(self): - """First tests to unify""" + """ First tests to unify """ left = FeatureStructure() right = FeatureStructure() left.unify(right) - self.assertEqual(len(left.content), len(right.content)) + assert len(left.content) == len(right.content) def test_unify2(self): - """Second test to unify""" + """ Second test to unify """ left = FeatureStructure("pl") right = FeatureStructure("sg") - with self.assertRaises(FeatureStructuresNotCompatibleException): + with pytest.raises(FeatureStructuresNotCompatibleException): left.unify(right) def test_unify3(self): - """Test to unify""" + """ Test to unify """ left = FeatureStructure() right = FeatureStructure("sg") left.unify(right) - self.assertEqual(len(left.content), len(right.content)) - self.assertEqual(left.value, right.value) + assert len(left.content) == len(right.content) + assert left.value == right.value def test_unify4(self): - """Test to unify""" + """ Test to unify """ left = FeatureStructure("pl") right = FeatureStructure() left.unify(right) - self.assertEqual(len(left.content), len(right.content)) - self.assertEqual(left.value, right.value) + assert len(left.content) == len(right.content) + assert left.value == right.value def test_unify5(self): - """Test to unify""" + """ Test to unify """ left = FeatureStructure() right = FeatureStructure() right.add_content("NUMBER", FeatureStructure("sg")) left.unify(right) - self.assertEqual(len(left.content), len(right.content)) - self.assertEqual(left.value, right.value) - self.assertEqual(left.get_feature_by_path(["NUMBER"]).value, right.get_feature_by_path(["NUMBER"]).value) - self.assertEqual(left.get_feature_by_path(["NUMBER"]).value, "sg") + assert len(left.content) == len(right.content) + assert left.value == right.value + assert left.get_feature_by_path(["NUMBER"]).value == \ + right.get_feature_by_path(["NUMBER"]).value + assert left.get_feature_by_path(["NUMBER"]).value == "sg" def test_unify6(self): - """Test to unify""" + """ Test to unify """ left = FeatureStructure() left.add_content("PERSON", FeatureStructure("M")) right = FeatureStructure() left.add_content("NUMBER", FeatureStructure("sg")) left.unify(right) - self.assertTrue(len(left.content) >= len(right.content)) - self.assertEqual(left.value, right.value) - self.assertEqual(left.get_feature_by_path(["NUMBER"]).value, right.get_feature_by_path(["NUMBER"]).value) - self.assertEqual(left.get_feature_by_path(["NUMBER"]).value, "sg") + assert len(left.content) >= len(right.content) + assert left.value == right.value + assert left.get_feature_by_path(["NUMBER"]).value == \ + right.get_feature_by_path(["NUMBER"]).value + assert left.get_feature_by_path(["NUMBER"]).value == "sg" def test_unify7(self): - """Test to unify""" + """ Test to unify """ left = FeatureStructure() agreement_left = FeatureStructure() agreement_left.add_content("NUMBER", FeatureStructure("sg")) @@ -93,17 +99,19 @@ def test_unify7(self): right = FeatureStructure() right.add_content("SUBJECT", FeatureStructure()) right.add_content_path("AGREEMENT", FeatureStructure(), ["SUBJECT"]) - right.add_content_path("PERSON", FeatureStructure("3rd"), ["SUBJECT", "AGREEMENT"]) + right.add_content_path( + "PERSON", FeatureStructure("3rd"), ["SUBJECT", "AGREEMENT"]) left.unify(right) - self.assertEqual(left.get_feature_by_path(["AGREEMENT", "PERSON"]).value, - right.get_feature_by_path(["AGREEMENT", "PERSON"]).value) - self.assertEqual(left.get_feature_by_path(["SUBJECT", "AGREEMENT", "PERSON"]).value, - right.get_feature_by_path(["AGREEMENT", "PERSON"]).value) - self.assertEqual(left.get_feature_by_path(["SUBJECT", "AGREEMENT", "PERSON"]).value, - "3rd") + assert left.get_feature_by_path(["AGREEMENT", "PERSON"]).value == \ + right.get_feature_by_path(["AGREEMENT", "PERSON"]).value + assert left.get_feature_by_path( + ["SUBJECT", "AGREEMENT", "PERSON"]).value == \ + right.get_feature_by_path(["AGREEMENT", "PERSON"]).value + assert left.get_feature_by_path( + ["SUBJECT", "AGREEMENT", "PERSON"]).value == "3rd" def test_subsumes1(self): - """Test to subsume""" + """ Test to subsume """ fs0 = FeatureStructure() fs0.add_content("NUMBER", FeatureStructure("pl")) fs1 = FeatureStructure() @@ -129,38 +137,38 @@ def test_subsumes1(self): subject = FeatureStructure() subject.add_content("AGREEMENT", agreement) fs5.add_content("SUBJECT", subject) - self.assertFalse(fs1.subsumes(fs0)) + assert not fs1.subsumes(fs0) # Identify - self.assertTrue(fs1.subsumes(fs1)) - self.assertTrue(fs2.subsumes(fs2)) - self.assertTrue(fs3.subsumes(fs3)) - self.assertTrue(fs4.subsumes(fs4)) - self.assertTrue(fs5.subsumes(fs5)) + assert fs1.subsumes(fs1) + assert fs2.subsumes(fs2) + assert fs3.subsumes(fs3) + assert fs4.subsumes(fs4) + assert fs5.subsumes(fs5) # Subsumes - self.assertTrue(fs1.subsumes(fs3)) - self.assertTrue(fs2.subsumes(fs3)) - self.assertTrue(fs4.subsumes(fs5)) + assert fs1.subsumes(fs3) + assert fs2.subsumes(fs3) + assert fs4.subsumes(fs5) # Not Subsumes - self.assertFalse(fs1.subsumes(fs2)) - self.assertFalse(fs1.subsumes(fs4)) - self.assertFalse(fs1.subsumes(fs5)) - self.assertFalse(fs2.subsumes(fs1)) - self.assertFalse(fs2.subsumes(fs4)) - self.assertFalse(fs2.subsumes(fs5)) - self.assertFalse(fs3.subsumes(fs1)) - self.assertFalse(fs3.subsumes(fs2)) - self.assertFalse(fs3.subsumes(fs4)) - self.assertFalse(fs3.subsumes(fs5)) - self.assertFalse(fs4.subsumes(fs1)) - self.assertFalse(fs4.subsumes(fs2)) - self.assertFalse(fs4.subsumes(fs3)) - self.assertFalse(fs5.subsumes(fs1)) - self.assertFalse(fs5.subsumes(fs2)) - self.assertFalse(fs5.subsumes(fs3)) - self.assertFalse(fs5.subsumes(fs4)) + assert not fs1.subsumes(fs2) + assert not fs1.subsumes(fs4) + assert not fs1.subsumes(fs5) + assert not fs2.subsumes(fs1) + assert not fs2.subsumes(fs4) + assert not fs2.subsumes(fs5) + assert not fs3.subsumes(fs1) + assert not fs3.subsumes(fs2) + assert not fs3.subsumes(fs4) + assert not fs3.subsumes(fs5) + assert not fs4.subsumes(fs1) + assert not fs4.subsumes(fs2) + assert not fs4.subsumes(fs3) + assert not fs5.subsumes(fs1) + assert not fs5.subsumes(fs2) + assert not fs5.subsumes(fs3) + assert not fs5.subsumes(fs4) def test_copy(self): - """Test to subsume""" + """ Test to subsume """ fs1 = FeatureStructure() agreement = FeatureStructure() subject = FeatureStructure() @@ -180,17 +188,21 @@ def test_copy(self): self._assertions_test_copy(copy_of_copy) def _assertions_test_copy(self, fs1_copy): - self.assertEqual(fs1_copy.get_feature_by_path(["AGREEMENT", "NUMBER"]).value, "sg") - self.assertEqual(fs1_copy.get_feature_by_path(["AGREEMENT", "PERSON"]).value, "3") - self.assertEqual(fs1_copy.get_feature_by_path(["SUBJECT", "AGREEMENT", "NUMBER"]).value, "sg") - self.assertEqual(fs1_copy.get_feature_by_path(["SUBJECT", "AGREEMENT", "PERSON"]).value, "3") + assert fs1_copy.get_feature_by_path( + ["AGREEMENT", "NUMBER"]).value == "sg" + assert fs1_copy.get_feature_by_path( + ["AGREEMENT", "PERSON"]).value == "3" + assert fs1_copy.get_feature_by_path( + ["SUBJECT", "AGREEMENT", "NUMBER"]).value == "sg" + assert fs1_copy.get_feature_by_path( + ["SUBJECT", "AGREEMENT", "PERSON"]).value == "3" def test_paths(self): - """Test the path generation""" + """ Test the path generation """ fs2 = _get_agreement_subject_number_person() - self.assertEqual(len(fs2.get_all_paths()), 4) + assert len(fs2.get_all_paths()) == 4 representation = repr(fs2) - self.assertIn("AGREEMENT.NUMBER", representation) - self.assertIn("AGREEMENT.PERSON", representation) - self.assertIn("SUBJECT.AGREEMENT.NUMBER", representation) - self.assertIn("SUBJECT.AGREEMENT.PERSON", representation) + assert "AGREEMENT.NUMBER" in representation + assert "AGREEMENT.PERSON" in representation + assert "SUBJECT.AGREEMENT.NUMBER" in representation + assert "SUBJECT.AGREEMENT.PERSON" in representation diff --git a/pyformlang/finite_automaton/tests/test_deterministic_finite_automaton.py b/pyformlang/finite_automaton/tests/test_deterministic_finite_automaton.py index 6629639..65f7e25 100644 --- a/pyformlang/finite_automaton/tests/test_deterministic_finite_automaton.py +++ b/pyformlang/finite_automaton/tests/test_deterministic_finite_automaton.py @@ -1,8 +1,6 @@ -""" -Tests for the deterministic finite automata -""" +""" Tests for deterministic finite automata """ -import unittest +import pytest from pyformlang.finite_automaton import DeterministicFiniteAutomaton, Epsilon from pyformlang.finite_automaton import State @@ -12,15 +10,13 @@ InvalidEpsilonTransition -class TestDeterministicFiniteAutomaton(unittest.TestCase): - """ Tests for deterministic finite automata - """ +class TestDeterministicFiniteAutomaton: + """ Tests for deterministic finite automata """ # pylint: disable=missing-function-docstring, protected-access def test_can_create(self): - """ Test the creation of dfa - """ + """ Test the creation of dfa """ state0 = State("0") state1 = State("1") symb0 = Symbol("a") @@ -35,49 +31,48 @@ def test_can_create(self): transition_function, start_state, final_states) - self.assertEqual(len(dfa.to_dict()), 1) - self.assertEqual(len(dfa), 1) - self.assertIsNotNone(dfa) + assert len(dfa.to_dict()) == 1 + assert len(dfa) == 1 + assert dfa is not None dfa = DeterministicFiniteAutomaton() - self.assertIsNotNone(dfa) + assert dfa is not None dfa = DeterministicFiniteAutomaton(start_state=state1, final_states={state0, state1}) - self.assertIsNotNone(dfa) - self.assertTrue(dfa is dfa.to_deterministic()) + assert dfa is not None + assert dfa is dfa.to_deterministic() def test_add_transition(self): - """ Tests the addition of transitions - """ + """ Tests the addition of transitions """ dfa = DeterministicFiniteAutomaton() - self.assertEqual(len(dfa.states), 0) + assert len(dfa.states) == 0 state0 = State("0") state1 = State("1") symb = Symbol("a") dfa.add_transition(state0, symb, state1) - self.assertEqual(len(dfa.states), 2) - self.assertEqual(len(dfa.symbols), 1) - self.assertEqual(len(list(dfa._transition_function.get_edges())), 1) + assert len(dfa.states) == 2 + assert len(dfa.symbols) == 1 + assert len(list(dfa._transition_function.get_edges())) == 1 def test_add_remove_start_final(self): - """ Tests the addition and removal of initial state and final states + """ + Tests the addition and removal of initial state and final states """ dfa = DeterministicFiniteAutomaton() state0 = State("0") state1 = State("1") - self.assertEqual(dfa.add_start_state(state0), 1) - self.assertEqual(len(dfa.states), 1) - self.assertEqual(dfa.add_final_state(state1), 1) - self.assertEqual(len(dfa.states), 2) - self.assertEqual(dfa.remove_final_state(state0), 0) - self.assertTrue(dfa.is_final_state(state1)) - self.assertFalse(dfa.is_final_state(state0)) - self.assertEqual(dfa.remove_final_state(state1), 1) - self.assertFalse(dfa.is_final_state(state1)) - self.assertEqual(dfa.remove_final_state(state1), 0) + assert dfa.add_start_state(state0) == 1 + assert len(dfa.states) == 1 + assert dfa.add_final_state(state1) == 1 + assert len(dfa.states) == 2 + assert dfa.remove_final_state(state0) == 0 + assert dfa.is_final_state(state1) + assert not dfa.is_final_state(state0) + assert dfa.remove_final_state(state1) == 1 + assert not dfa.is_final_state(state1) + assert dfa.remove_final_state(state1) == 0 def test_accepts(self): - """ Tests the acceptance of dfa - """ + """ Tests the acceptance of dfa """ dfa = get_example0() self._perform_tests_example0(dfa) dfa = get_example0_bis() @@ -91,30 +86,30 @@ def _perform_tests_example0(self, dfa): symb_d = Symbol("d") state0 = State(0) state1 = State(1) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_c])) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_c])) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_d])) - self.assertTrue(dfa.accepts([symb_a, symb_d])) - self.assertFalse(dfa.accepts([symb_a, symb_c, symb_d])) - self.assertFalse(dfa.accepts([symb_d, symb_c, symb_d])) - self.assertFalse(dfa.accepts([])) - self.assertEqual(dfa.remove_start_state(state1), 0) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_c])) - self.assertEqual(dfa.remove_start_state(state0), 1) - self.assertFalse(dfa.accepts([symb_a, symb_b, symb_c])) + assert dfa.accepts([symb_a, symb_b, symb_c]) + assert dfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_c]) + assert dfa.accepts([symb_a, symb_b, symb_d]) + assert dfa.accepts([symb_a, symb_d]) + assert not dfa.accepts([symb_a, symb_c, symb_d]) + assert not dfa.accepts([symb_d, symb_c, symb_d]) + assert not dfa.accepts([]) + assert dfa.remove_start_state(state1) == 0 + assert dfa.accepts([symb_a, symb_b, symb_c]) + assert dfa.remove_start_state(state0) == 1 + assert not dfa.accepts([symb_a, symb_b, symb_c]) dfa.add_start_state(0) - self.assertTrue(dfa.accepts(["a", "b", "c"])) - self.assertTrue(dfa.accepts(["a", "b", "b", "b", "c"])) - self.assertTrue(dfa.accepts(["a", "b", "d"])) - self.assertTrue(dfa.accepts(["a", "d"])) - self.assertFalse(dfa.accepts(["a", "c", "d"])) - self.assertFalse(dfa.accepts(["d", "c", "d"])) - self.assertFalse(dfa.accepts([])) - self.assertEqual(dfa.remove_start_state(1), 0) - self.assertTrue(dfa.accepts(["a", "b", "c"])) - self.assertEqual(dfa.remove_start_state(0), 1) - self.assertFalse(dfa.accepts(["a", "b", "c"])) + assert dfa.accepts(["a", "b", "c"]) + assert dfa.accepts(["a", "b", "b", "b", "c"]) + assert dfa.accepts(["a", "b", "d"]) + assert dfa.accepts(["a", "d"]) + assert not dfa.accepts(["a", "c", "d"]) + assert not dfa.accepts(["d", "c", "d"]) + assert not dfa.accepts([]) + assert dfa.remove_start_state(1) == 0 + assert dfa.accepts(["a", "b", "c"]) + assert dfa.remove_start_state(0) == 1 + assert not dfa.accepts(["a", "b", "c"]) def test_copy(self): """ Test the copy of a DFA """ @@ -140,11 +135,11 @@ def test_complement(self): dfa.add_transition(state0, symb_a, state1) dfa.add_transition(state1, symb_b, state2) dfa_comp = dfa.get_complement() - self.assertTrue(dfa_comp.accepts([symb_a])) - self.assertTrue(dfa_comp.accepts([symb_b])) - self.assertTrue(dfa_comp.accepts([symb_b, symb_a])) - self.assertTrue(dfa_comp.accepts([])) - self.assertFalse(dfa_comp.accepts([symb_a, symb_b])) + assert dfa_comp.accepts([symb_a]) + assert dfa_comp.accepts([symb_b]) + assert dfa_comp.accepts([symb_b, symb_a]) + assert dfa_comp.accepts([]) + assert not dfa_comp.accepts([symb_a, symb_b]) def test_big_minimize(self): dfa = DeterministicFiniteAutomaton() @@ -155,8 +150,8 @@ def test_big_minimize(self): for i in range(size): dfa.add_transition(State(i), symb, State(i+1)) dfa = dfa.minimize() - self.assertEqual(len(dfa.states), size + 1) - self.assertFalse(dfa.accepts([symb])) + assert len(dfa.states) == size + 1 + assert not dfa.accepts([symb]) def test_big_minimize_reduce(self): dfa = DeterministicFiniteAutomaton() @@ -189,13 +184,13 @@ def test_big_minimize_reduce(self): dfa.add_transition(states[1], symb_0_minus, states[5]) dfa.add_transition(states[6], symb_0_minus, states[7]) dfa.add_transition(states[3], symb_1_minus, states[4]) - self.assertFalse(dfa.accepts(["0", "STAR", "0-", "STAR", "0-", "0", - "STAR", "0", "0", "STAR", "0-", "STAR", - "0-", "1-"])) + assert not dfa.accepts(["0", "STAR", "0-", "STAR", "0-", "0", + "STAR", "0", "0", "STAR", "0-", "STAR", + "0-", "1-"]) dfa = dfa.minimize() - self.assertFalse(dfa.accepts(["0", "STAR", "0-", "STAR", "0-", "0", - "STAR", "0", "0", "STAR", "0-", "STAR", - "0-", "1-"])) + assert not dfa.accepts(["0", "STAR", "0-", "STAR", "0-", "0", + "STAR", "0", "0", "STAR", "0-", "STAR", + "0-", "1-"]) def test_minimize_repetition(self): dfa = DeterministicFiniteAutomaton() @@ -226,7 +221,7 @@ def test_minimize_repetition(self): dfa.add_transition(states[8], symb_a, states[1]) dfa.add_transition(states[8], symb_b, states[5]) dfa = dfa.minimize() - self.assertTrue(dfa.accepts([symb_a, symb_star, symb_a])) + assert dfa.accepts([symb_a, symb_star, symb_a]) def test_not_cyclic(self): dfa = DeterministicFiniteAutomaton() @@ -235,7 +230,7 @@ def test_not_cyclic(self): symb_a = Symbol('a') dfa.add_start_state(state0) dfa.add_transition(state0, symb_a, state1) - self.assertTrue(dfa.is_acyclic()) + assert dfa.is_acyclic() def test_not_cyclic2(self): dfa = DeterministicFiniteAutomaton() @@ -246,13 +241,13 @@ def test_not_cyclic2(self): dfa.add_start_state(state0) dfa.add_transition(state0, symb_a, state1) dfa.add_transition(state0, symb_b, state1) - self.assertTrue(dfa.is_acyclic()) + assert dfa.is_acyclic() def test_epsilon_refused(self): dfa = DeterministicFiniteAutomaton() state0 = State(0) state1 = State(1) - with self.assertRaises(InvalidEpsilonTransition): + with pytest.raises(InvalidEpsilonTransition): dfa.add_transition(state0, Epsilon(), state1) def test_cyclic(self): @@ -263,7 +258,7 @@ def test_cyclic(self): dfa.add_start_state(state0) dfa.add_transition(state0, symb_a, state1) dfa.add_transition(state1, symb_a, state0) - self.assertFalse(dfa.is_acyclic()) + assert not dfa.is_acyclic() def test_equivalent(self): dfa1 = get_dfa_example() @@ -275,20 +270,20 @@ def test_equivalent(self): ("B", "c", "D")]) dfa2.add_start_state(State("A")) dfa2.add_final_state(State("D")) - self.assertNotEqual(dfa2, dfa1) + assert dfa2 != dfa1 def test_regex_dfa(self): dfa1 = get_dfa_example() dfa_regex = dfa1.to_regex().to_epsilon_nfa() - self.assertEqual(dfa1, dfa_regex) + assert dfa1 == dfa_regex def test_word_generation(self): dfa = get_dfa_example_for_word_generation() accepted_words = list(dfa.get_accepted_words()) - self.assertTrue([] in accepted_words) - self.assertTrue([Symbol("b"), Symbol("c")] in accepted_words) - self.assertTrue([Symbol("b"), Symbol("d")] in accepted_words) - self.assertEqual(len(accepted_words), 3) + assert [] in accepted_words + assert [Symbol("b"), Symbol("c")] in accepted_words + assert [Symbol("b"), Symbol("d")] in accepted_words + assert len(accepted_words) == 3 def get_example0(): diff --git a/pyformlang/finite_automaton/tests/test_epsilon.py b/pyformlang/finite_automaton/tests/test_epsilon.py index c49f15d..eebac00 100644 --- a/pyformlang/finite_automaton/tests/test_epsilon.py +++ b/pyformlang/finite_automaton/tests/test_epsilon.py @@ -1,14 +1,10 @@ -""" -Tests for epsilon transitions -""" - -import unittest +""" Tests for epsilon transitions """ from pyformlang.finite_automaton import Epsilon from pyformlang.finite_automaton import Symbol -class TestEpsilon(unittest.TestCase): +class TestEpsilon: """ Tests for epsilon transitions """ def test_epsilon(self): @@ -16,5 +12,5 @@ def test_epsilon(self): eps0 = Epsilon() eps1 = Epsilon() symb = Symbol(0) - self.assertEqual(eps0, eps1) - self.assertNotEqual(eps0, symb) + assert eps0 == eps1 + assert eps0 != symb diff --git a/pyformlang/finite_automaton/tests/test_epsilon_nfa.py b/pyformlang/finite_automaton/tests/test_epsilon_nfa.py index c21f561..52f2ee2 100644 --- a/pyformlang/finite_automaton/tests/test_epsilon_nfa.py +++ b/pyformlang/finite_automaton/tests/test_epsilon_nfa.py @@ -1,17 +1,15 @@ -""" -Tests for epsilon NFA -""" -import copy -import unittest +""" Tests for epsilon NFA """ +import copy +import pytest import networkx from pyformlang.finite_automaton import EpsilonNFA, State, Symbol, Epsilon from ..regexable import Regexable -class TestEpsilonNFA(unittest.TestCase): - """ Tests epsilon NFA """ +class TestEpsilonNFA: + """ Tests for epsilon NFA """ # pylint: disable=missing-function-docstring, protected-access # pylint: disable=too-many-statements, too-many-public-methods @@ -30,14 +28,13 @@ def test_eclose(self): enfa.add_transition(states[5], epsilon, states[7]) enfa.add_transition(states[4], symb_a, states[5]) enfa.add_transition(states[5], symb_b, states[6]) - self.assertEqual(len(enfa.eclose(states[1])), 5) - self.assertEqual(len(enfa.eclose(states[2])), 3) - self.assertEqual(len(enfa.eclose(states[5])), 2) - self.assertEqual(len(enfa.eclose(states[6])), 1) - self.assertEqual(len(list(enfa._transition_function.get_edges())), 7) - self.assertEqual(enfa.remove_transition(states[1], epsilon, states[4]), - 1) - self.assertFalse(enfa.is_deterministic()) + assert len(enfa.eclose(states[1])) == 5 + assert len(enfa.eclose(states[2])) == 3 + assert len(enfa.eclose(states[5])) == 2 + assert len(enfa.eclose(states[6])) == 1 + assert len(list(enfa._transition_function.get_edges())) == 7 + assert enfa.remove_transition(states[1], epsilon, states[4]) == 1 + assert not enfa.is_deterministic() def test_accept(self): """ Test the acceptance """ @@ -51,41 +48,41 @@ def _perform_tests_digits(self, should_copy=False): enfa, digits, epsilon, plus, minus, point = get_digits_enfa() if should_copy: enfa = copy.copy(enfa) - self.assertTrue(enfa.accepts([plus, digits[1], point, digits[9]])) - self.assertTrue(enfa.accepts([minus, digits[1], point, digits[9]])) - self.assertTrue(enfa.accepts([digits[1], point, digits[9]])) - self.assertTrue(enfa.accepts([digits[1], point])) - self.assertTrue(enfa.accepts([digits[1], point, epsilon])) - self.assertTrue(enfa.accepts([point, digits[9]])) - self.assertFalse(enfa.accepts([point])) - self.assertFalse(enfa.accepts([plus])) - self.assertFalse(enfa.is_deterministic()) - - self.assertTrue(enfa.accepts(["+", digits[1], ".", digits[9]])) - self.assertTrue(enfa.accepts(["-", digits[1], ".", digits[9]])) - self.assertTrue(enfa.accepts([digits[1], ".", digits[9]])) - self.assertTrue(enfa.accepts([digits[1], "."])) - self.assertTrue(enfa.accepts([digits[1], ".", "epsilon"])) - self.assertTrue(enfa.accepts([".", digits[9]])) - self.assertFalse(enfa.accepts(["."])) - self.assertFalse(enfa.accepts(["+"])) + assert enfa.accepts([plus, digits[1], point, digits[9]]) + assert enfa.accepts([minus, digits[1], point, digits[9]]) + assert enfa.accepts([digits[1], point, digits[9]]) + assert enfa.accepts([digits[1], point]) + assert enfa.accepts([digits[1], point, epsilon]) + assert enfa.accepts([point, digits[9]]) + assert not enfa.accepts([point]) + assert not enfa.accepts([plus]) + assert not enfa.is_deterministic() + + assert enfa.accepts(["+", digits[1], ".", digits[9]]) + assert enfa.accepts(["-", digits[1], ".", digits[9]]) + assert enfa.accepts([digits[1], ".", digits[9]]) + assert enfa.accepts([digits[1], "."]) + assert enfa.accepts([digits[1], ".", "epsilon"]) + assert enfa.accepts([".", digits[9]]) + assert not enfa.accepts(["."]) + assert not enfa.accepts(["+"]) def test_deterministic(self): """ Tests the transformation to a dfa""" enfa, digits, _, plus, minus, point = get_digits_enfa() dfa = enfa.to_deterministic() - self.assertTrue(dfa.is_deterministic()) - self.assertEqual(len(dfa.states), 6) - self.assertEqual(dfa.get_number_transitions(), 65) - self.assertEqual(len(dfa.final_states), 2) - self.assertTrue(dfa.accepts([plus, digits[1], point, digits[9]])) - self.assertTrue(dfa.accepts([minus, digits[1], point, digits[9]])) - self.assertTrue(dfa.accepts([digits[1], point, digits[9]])) - self.assertTrue(dfa.accepts([digits[1], point])) - self.assertTrue(dfa.accepts([digits[1], point])) - self.assertTrue(dfa.accepts([point, digits[9]])) - self.assertFalse(dfa.accepts([point])) - self.assertFalse(dfa.accepts([plus])) + assert dfa.is_deterministic() + assert len(dfa.states) == 6 + assert dfa.get_number_transitions() == 65 + assert len(dfa.final_states) == 2 + assert dfa.accepts([plus, digits[1], point, digits[9]]) + assert dfa.accepts([minus, digits[1], point, digits[9]]) + assert dfa.accepts([digits[1], point, digits[9]]) + assert dfa.accepts([digits[1], point]) + assert dfa.accepts([digits[1], point]) + assert dfa.accepts([point, digits[9]]) + assert not dfa.accepts([point]) + assert not dfa.accepts([plus]) def test_remove_state(self): " Tests the remove of state """ @@ -104,8 +101,8 @@ def test_remove_state(self): enfa.add_transition(state1, symb11, state1) enfa.add_transition(state1, symb12, state2) enfa._remove_all_basic_states() - self.assertEqual(enfa.get_number_transitions(), 1) - self.assertEqual(len(enfa.states), 2) + assert enfa.get_number_transitions() == 1 + assert len(enfa.states) == 2 def test_to_regex(self): """ Tests the transformation to regex """ @@ -123,40 +120,40 @@ def test_to_regex(self): enfa.add_transition(state0, symb_g, state2) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() - self.assertTrue(enfa2.accepts([symb_e, symb_f])) - self.assertTrue(enfa2.accepts([symb_g])) - self.assertFalse(enfa2.accepts([])) - self.assertFalse(enfa2.accepts([symb_e])) - self.assertFalse(enfa2.accepts([symb_f])) + assert enfa2.accepts([symb_e, symb_f]) + assert enfa2.accepts([symb_g]) + assert not enfa2.accepts([]) + assert not enfa2.accepts([symb_e]) + assert not enfa2.accepts([symb_f]) enfa.add_final_state(state0) - with self.assertRaises(ValueError) as _: + with pytest.raises(ValueError) as _: enfa._get_regex_simple() regex = enfa.to_regex() enfa3 = regex.to_epsilon_nfa() - self.assertTrue(enfa3.accepts([symb_e, symb_f])) - self.assertTrue(enfa3.accepts([symb_g])) - self.assertTrue(enfa3.accepts([])) - self.assertFalse(enfa3.accepts([symb_e])) - self.assertFalse(enfa3.accepts([symb_f])) + assert enfa3.accepts([symb_e, symb_f]) + assert enfa3.accepts([symb_g]) + assert enfa3.accepts([]) + assert not enfa3.accepts([symb_e]) + assert not enfa3.accepts([symb_f]) enfa.remove_start_state(state0) regex = enfa.to_regex() enfa3 = regex.to_epsilon_nfa() - self.assertFalse(enfa3.accepts([symb_e, symb_f])) - self.assertFalse(enfa3.accepts([symb_g])) - self.assertFalse(enfa3.accepts([])) - self.assertFalse(enfa3.accepts([symb_e])) - self.assertFalse(enfa3.accepts([symb_f])) + assert not enfa3.accepts([symb_e, symb_f]) + assert not enfa3.accepts([symb_g]) + assert not enfa3.accepts([]) + assert not enfa3.accepts([symb_e]) + assert not enfa3.accepts([symb_f]) enfa.add_start_state(state0) enfa.add_transition(state0, symb_f, state0) regex = enfa.to_regex() enfa3 = regex.to_epsilon_nfa() - self.assertTrue(enfa3.accepts([symb_e, symb_f])) - self.assertTrue(enfa3.accepts([symb_f, symb_e, symb_f])) - self.assertTrue(enfa3.accepts([symb_g])) - self.assertTrue(enfa3.accepts([symb_f, symb_f, symb_g])) - self.assertTrue(enfa3.accepts([])) - self.assertFalse(enfa3.accepts([symb_e])) - self.assertTrue(enfa3.accepts([symb_f])) + assert enfa3.accepts([symb_e, symb_f]) + assert enfa3.accepts([symb_f, symb_e, symb_f]) + assert enfa3.accepts([symb_g]) + assert enfa3.accepts([symb_f, symb_f, symb_g]) + assert enfa3.accepts([]) + assert not enfa3.accepts([symb_e]) + assert enfa3.accepts([symb_f]) def test_to_regex2(self): """ Tests the transformation to regex """ @@ -173,15 +170,15 @@ def test_to_regex2(self): enfa.add_transition(state1, symb_b, state1) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() - self.assertTrue(enfa2.accepts([symb_a])) - self.assertTrue(enfa2.accepts([symb_a, symb_a])) - self.assertTrue(enfa2.accepts([symb_a, symb_a, symb_b])) - self.assertTrue(enfa2.accepts([symb_a, symb_a, symb_b, symb_b])) - self.assertTrue(enfa2.accepts([symb_a, symb_a, - symb_b, symb_b, symb_a])) - self.assertTrue(enfa2.accepts([symb_a, symb_a, symb_b, - symb_b, symb_a, symb_b])) - self.assertFalse(enfa2.accepts([symb_b])) + assert enfa2.accepts([symb_a]) + assert enfa2.accepts([symb_a, symb_a]) + assert enfa2.accepts([symb_a, symb_a, symb_b]) + assert enfa2.accepts([symb_a, symb_a, symb_b, symb_b]) + assert enfa2.accepts([symb_a, symb_a, + symb_b, symb_b, symb_a]) + assert enfa2.accepts([symb_a, symb_a, symb_b, + symb_b, symb_a, symb_b]) + assert not enfa2.accepts([symb_b]) def test_to_regex3(self): """ Tests the transformation to regex """ @@ -197,51 +194,51 @@ def test_to_regex3(self): enfa.add_transition(state1, symb_b, state1) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() - self.assertFalse(enfa2.accepts([symb_a])) - self.assertFalse(enfa2.accepts([symb_a, symb_a])) - self.assertFalse(enfa2.accepts([symb_a, symb_a, symb_b])) - self.assertFalse(enfa2.accepts([symb_a, symb_a, - symb_b, symb_b, symb_a])) - self.assertFalse(enfa2.accepts([symb_a, symb_a, symb_b, - symb_b, symb_a, symb_b])) - self.assertFalse(enfa2.accepts([symb_b])) + assert not enfa2.accepts([symb_a]) + assert not enfa2.accepts([symb_a, symb_a]) + assert not enfa2.accepts([symb_a, symb_a, symb_b]) + assert not enfa2.accepts([symb_a, symb_a, + symb_b, symb_b, symb_a]) + assert not enfa2.accepts([symb_a, symb_a, symb_b, + symb_b, symb_a, symb_b]) + assert not enfa2.accepts([symb_b]) epsilon = Epsilon() enfa.add_transition(state0, epsilon, state1) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([])) - self.assertTrue(enfa.accepts([symb_a])) - self.assertTrue(enfa2.accepts([symb_a])) - self.assertTrue(enfa2.accepts([symb_a, symb_a])) - self.assertTrue(enfa2.accepts([symb_a, symb_a, symb_b, symb_b])) - self.assertTrue(enfa2.accepts([symb_a, symb_a, symb_b, symb_b, - symb_a, symb_b])) - self.assertTrue(enfa2.accepts([symb_b])) - self.assertTrue(enfa2.accepts([])) + assert enfa.accepts([]) + assert enfa.accepts([symb_a]) + assert enfa2.accepts([symb_a]) + assert enfa2.accepts([symb_a, symb_a]) + assert enfa2.accepts([symb_a, symb_a, symb_b, symb_b]) + assert enfa2.accepts([symb_a, symb_a, symb_b, + symb_b, symb_a, symb_b]) + assert enfa2.accepts([symb_b]) + assert enfa2.accepts([]) enfa.remove_transition(state0, symb_a, state0) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() - self.assertFalse(enfa2.accepts([symb_a])) - self.assertFalse(enfa2.accepts([symb_a, symb_a])) - self.assertFalse(enfa2.accepts([symb_a, symb_a, symb_b])) - self.assertFalse(enfa2.accepts([symb_a, symb_a, symb_b, - symb_b, symb_a])) - self.assertFalse(enfa2.accepts([symb_a, symb_a, symb_b, symb_b, - symb_a, symb_b])) - self.assertTrue(enfa2.accepts([symb_b])) - self.assertTrue(enfa2.accepts([])) + assert not enfa2.accepts([symb_a]) + assert not enfa2.accepts([symb_a, symb_a]) + assert not enfa2.accepts([symb_a, symb_a, symb_b]) + assert not enfa2.accepts([symb_a, symb_a, symb_b, + symb_b, symb_a]) + assert not enfa2.accepts([symb_a, symb_a, symb_b, + symb_b, symb_a, symb_b]) + assert enfa2.accepts([symb_b]) + assert enfa2.accepts([]) enfa.remove_transition(state1, symb_b, state1) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() - self.assertTrue(enfa2.accepts([symb_b, symb_b])) + assert enfa2.accepts([symb_b, symb_b]) enfa.add_transition(state0, symb_a, state0) regex = enfa.to_regex() enfa2 = regex.to_epsilon_nfa() - self.assertTrue(enfa2.accepts([symb_a, symb_b])) + assert enfa2.accepts([symb_a, symb_b]) def test_union(self): """ Tests the union of two epsilon NFA """ - with self.assertRaises(NotImplementedError) as _: + with pytest.raises(NotImplementedError) as _: Regexable().to_regex() enfa0 = get_enfa_example0() enfa1 = get_enfa_example1() @@ -249,11 +246,11 @@ def test_union(self): symb_b = Symbol("b") symb_c = Symbol("c") enfa = enfa0.union(enfa1) - self.assertTrue(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_c])) - self.assertFalse(enfa.accepts([symb_a])) - self.assertFalse(enfa.accepts([])) + assert enfa.accepts([symb_b]) + assert enfa.accepts([symb_a, symb_b]) + assert enfa.accepts([symb_c]) + assert not enfa.accepts([symb_a]) + assert not enfa.accepts([]) def test_concatenate(self): """ Tests the concatenation of two epsilon NFA """ @@ -263,12 +260,12 @@ def test_concatenate(self): symb_b = Symbol("b") symb_c = Symbol("c") enfa = enfa0.concatenate(enfa1) - self.assertTrue(enfa.accepts([symb_b, symb_c])) - self.assertTrue(enfa.accepts([symb_a, symb_b, symb_c])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b, symb_c])) - self.assertFalse(enfa.accepts([symb_c])) - self.assertFalse(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([])) + assert enfa.accepts([symb_b, symb_c]) + assert enfa.accepts([symb_a, symb_b, symb_c]) + assert enfa.accepts([symb_a, symb_a, symb_b, symb_c]) + assert not enfa.accepts([symb_c]) + assert not enfa.accepts([symb_b]) + assert not enfa.accepts([]) def test_kleene(self): """ Tests the kleene star of an epsilon NFA """ @@ -276,13 +273,13 @@ def test_kleene(self): symb_a = Symbol("a") symb_b = Symbol("b") enfa = enfa0.kleene_star() - self.assertTrue(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_a, symb_b, symb_a, symb_b])) - self.assertTrue(enfa.accepts([])) - self.assertTrue(enfa.accepts([symb_b, symb_b])) - self.assertFalse(enfa.accepts([symb_a])) - self.assertFalse(enfa.accepts([symb_a, symb_b, symb_a])) + assert enfa.accepts([symb_b]) + assert enfa.accepts([symb_a, symb_b]) + assert enfa.accepts([symb_a, symb_b, symb_a, symb_b]) + assert enfa.accepts([]) + assert enfa.accepts([symb_b, symb_b]) + assert not enfa.accepts([symb_a]) + assert not enfa.accepts([symb_a, symb_b, symb_a]) def test_complement(self): """ Tests the complement operation """ @@ -296,7 +293,7 @@ def test_complement(self): enfa.add_transition(state0, Epsilon(), state1) enfa.add_transition(state1, symb_a, state2) enfa_comp = -enfa - self.assertFalse(enfa_comp.accepts([symb_a])) + assert not enfa_comp.accepts([symb_a]) def test_intersection(self): """ Tests the intersection of two enfas """ @@ -318,14 +315,14 @@ def test_intersection(self): enfa1.add_transition(state2, eps, state3) enfa1.add_transition(state3, symb_b, state4) enfa = enfa0 & enfa1 - self.assertEqual(len(enfa.start_states), 4) - self.assertEqual(len(enfa.final_states), 2) - self.assertEqual(len(enfa.symbols), 2) - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertFalse(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_a])) - self.assertFalse(enfa.accepts([])) - self.assertFalse(enfa.accepts([symb_a, symb_a, symb_b])) + assert len(enfa.start_states) == 4 + assert len(enfa.final_states) == 2 + assert len(enfa.symbols) == 2 + assert enfa.accepts([symb_a, symb_b]) + assert not enfa.accepts([symb_b]) + assert not enfa.accepts([symb_a]) + assert not enfa.accepts([]) + assert not enfa.accepts([symb_a, symb_a, symb_b]) def test_difference(self): """ Tests the intersection of two languages """ @@ -335,19 +332,19 @@ def test_difference(self): symb_b = Symbol("b") symb_c = Symbol("c") enfa = enfa0 - enfa1 - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_c])) - self.assertFalse(enfa.accepts([])) + assert enfa.accepts([symb_a, symb_b]) + assert enfa.accepts([symb_b]) + assert not enfa.accepts([symb_c]) + assert not enfa.accepts([]) enfa2 = EpsilonNFA() state0 = State(0) enfa2.add_start_state(state0) enfa2.add_final_state(state0) enfa2.add_transition(state0, symb_b, state0) enfa = enfa0.get_difference(enfa2) - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertFalse(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_c])) + assert enfa.accepts([symb_a, symb_b]) + assert not enfa.accepts([symb_b]) + assert not enfa.accepts([symb_c]) def test_reverse(self): """ Test the reversal of a language """ @@ -355,27 +352,27 @@ def test_reverse(self): symb_a = Symbol("a") symb_b = Symbol("b") enfa = ~enfa0 - self.assertTrue(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_b, symb_a])) - self.assertTrue(enfa.accepts([symb_b, symb_a, symb_a])) - self.assertFalse(enfa.accepts([symb_a, symb_b])) - self.assertFalse(enfa.accepts([symb_a])) - self.assertFalse(enfa.accepts([])) + assert enfa.accepts([symb_b]) + assert enfa.accepts([symb_b, symb_a]) + assert enfa.accepts([symb_b, symb_a, symb_a]) + assert not enfa.accepts([symb_a, symb_b]) + assert not enfa.accepts([symb_a]) + assert not enfa.accepts([]) def test_empty(self): """ Tests the emptiness of a finite automaton """ - self.assertTrue(get_enfa_example0()) - self.assertFalse(get_enfa_example1().is_empty()) + assert get_enfa_example0() + assert not get_enfa_example1().is_empty() enfa = EpsilonNFA() state0 = State(0) enfa.add_start_state(state0) - self.assertTrue(enfa.is_empty()) + assert enfa.is_empty() state1 = State(1) symb_a = Symbol('a') enfa.add_transition(state0, symb_a, state1) - self.assertTrue(enfa.is_empty()) + assert enfa.is_empty() enfa.add_final_state(state1) - self.assertFalse(enfa.is_empty()) + assert not enfa.is_empty() def test_minimization(self): """ Tests the minimization algorithm """ @@ -383,92 +380,92 @@ def test_minimization(self): symb_a = Symbol("a") symb_b = Symbol("b") enfa = enfa.minimize() - self.assertTrue(enfa.is_deterministic()) - self.assertEqual(len(enfa.states), 2) - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_a])) + assert enfa.is_deterministic() + assert len(enfa.states) == 2 + assert enfa.accepts([symb_a, symb_b]) + assert enfa.accepts([symb_a, symb_a, symb_b]) + assert enfa.accepts([symb_b]) + assert not enfa.accepts([symb_a]) enfa = get_example_non_minimal() enfa = enfa.minimize() - self.assertTrue(enfa.is_deterministic()) - self.assertEqual(len(enfa.states), 3) - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) - self.assertFalse(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_a])) + assert enfa.is_deterministic() + assert len(enfa.states) == 3 + assert enfa.accepts([symb_a, symb_b]) + assert enfa.accepts([symb_a, symb_a, symb_b]) + assert not enfa.accepts([symb_b]) + assert not enfa.accepts([symb_a]) enfa = EpsilonNFA() enfa = enfa.minimize() - self.assertTrue(enfa.is_deterministic()) - self.assertEqual(len(enfa.states), 1) - self.assertFalse(enfa.accepts([])) + assert enfa.is_deterministic() + assert len(enfa.states) == 1 + assert not enfa.accepts([]) def test_to_fst(self): """ Tests to turn a ENFA into a FST """ enfa = EpsilonNFA() fst = enfa.to_fst() - self.assertEqual(len(fst.states), 0) - self.assertEqual(len(fst.final_states), 0) - self.assertEqual(len(fst.start_states), 0) - self.assertEqual(len(fst.input_symbols), 0) - self.assertEqual(len(fst.output_symbols), 0) - self.assertEqual(fst.get_number_transitions(), 0) + assert len(fst.states) == 0 + assert len(fst.final_states) == 0 + assert len(fst.start_states) == 0 + assert len(fst.input_symbols) == 0 + assert len(fst.output_symbols) == 0 + assert fst.get_number_transitions() == 0 state0 = State("q0") s0bis = State("q0bis") enfa.add_start_state(state0) enfa.add_start_state(s0bis) fst = enfa.to_fst() - self.assertEqual(len(fst.states), 2) - self.assertEqual(len(fst.final_states), 0) - self.assertEqual(len(fst.start_states), 2) - self.assertEqual(len(fst.input_symbols), 0) - self.assertEqual(len(fst.output_symbols), 0) - self.assertEqual(fst.get_number_transitions(), 0) + assert len(fst.states) == 2 + assert len(fst.final_states) == 0 + assert len(fst.start_states) == 2 + assert len(fst.input_symbols) == 0 + assert len(fst.output_symbols) == 0 + assert fst.get_number_transitions() == 0 sfinal = State("qfinal") sfinalbis = State("qfinalbis") enfa.add_final_state(sfinal) enfa.add_final_state(sfinalbis) fst = enfa.to_fst() - self.assertEqual(len(fst.states), 4) - self.assertEqual(len(fst.final_states), 2) - self.assertEqual(len(fst.start_states), 2) - self.assertEqual(len(fst.input_symbols), 0) - self.assertEqual(len(fst.output_symbols), 0) - self.assertEqual(fst.get_number_transitions(), 0) + assert len(fst.states) == 4 + assert len(fst.final_states) == 2 + assert len(fst.start_states) == 2 + assert len(fst.input_symbols) == 0 + assert len(fst.output_symbols) == 0 + assert fst.get_number_transitions() == 0 enfa.add_transition(state0, Symbol("a"), sfinal) enfa.add_transition(sfinal, Symbol("b"), sfinal) enfa.add_transition(state0, Symbol("c"), sfinalbis) fst = enfa.to_fst() - self.assertEqual(len(fst.states), 4) - self.assertEqual(len(fst.final_states), 2) - self.assertEqual(len(fst.start_states), 2) - self.assertEqual(len(fst.input_symbols), 3) - self.assertEqual(len(fst.output_symbols), 3) - self.assertEqual(fst.get_number_transitions(), 3) + assert len(fst.states) == 4 + assert len(fst.final_states) == 2 + assert len(fst.start_states) == 2 + assert len(fst.input_symbols) == 3 + assert len(fst.output_symbols) == 3 + assert fst.get_number_transitions() == 3 enfa.add_transition(state0, Epsilon(), sfinalbis) fst = enfa.to_fst() - self.assertEqual(len(fst.states), 4) - self.assertEqual(len(fst.final_states), 2) - self.assertEqual(len(fst.start_states), 2) - self.assertEqual(len(fst.input_symbols), 3) - self.assertEqual(len(fst.output_symbols), 3) - self.assertEqual(fst.get_number_transitions(), 4) + assert len(fst.states) == 4 + assert len(fst.final_states) == 2 + assert len(fst.start_states) == 2 + assert len(fst.input_symbols) == 3 + assert len(fst.output_symbols) == 3 + assert fst.get_number_transitions() == 4 trans0 = list(fst.translate(["a"])) - self.assertEqual(trans0, [["a"]]) + assert trans0 == [["a"]] trans0 = list(fst.translate(["a", "b", "b"])) - self.assertEqual(trans0, [["a", "b", "b"]]) + assert trans0 == [["a", "b", "b"]] trans0 = list(fst.translate(["b", "b"])) - self.assertEqual(trans0, []) + assert not trans0 trans0 = list(fst.translate(["c"])) - self.assertEqual(trans0, [["c"]]) + assert trans0 == [["c"]] def test_cyclic(self): enfa = EpsilonNFA() @@ -478,7 +475,7 @@ def test_cyclic(self): enfa.add_start_state(state0) enfa.add_transition(state0, symb_a, state1) enfa.add_transition(state1, Epsilon(), state0) - self.assertFalse(enfa.is_acyclic()) + assert not enfa.is_acyclic() def test_export_networkx(self): enfa = EpsilonNFA() @@ -490,14 +487,14 @@ def test_export_networkx(self): enfa.add_transition(state0, symb_a, state1) enfa.add_transition(state1, Epsilon(), state0) graph = enfa.to_networkx() - self.assertTrue(isinstance(graph, networkx.MultiDiGraph)) - self.assertTrue("0" in graph) - self.assertTrue(("0", 1) in graph.edges) - self.assertIn("a", [x["label"] for x in graph["0"][1].values()]) - self.assertTrue(graph.nodes["0"]["is_start"]) - self.assertFalse(graph.nodes["0"]["is_final"]) - self.assertFalse(graph.nodes[1]["is_start"]) - self.assertTrue(graph.nodes[1]["is_final"]) + assert isinstance(graph, networkx.MultiDiGraph) + assert "0" in graph + assert ("0", 1) in graph.edges + assert "a" in [x["label"] for x in graph["0"][1].values()] + assert graph.nodes["0"]["is_start"] + assert not graph.nodes["0"]["is_final"] + assert not graph.nodes[1]["is_start"] + assert graph.nodes[1]["is_final"] enfa.write_as_dot("enfa.dot") def test_import_networkx(self): @@ -511,9 +508,9 @@ def test_import_networkx(self): enfa.add_transition(state1, Epsilon(), state0) graph = enfa.to_networkx() enfa_from_nx = EpsilonNFA.from_networkx(graph) - self.assertTrue(enfa_from_nx.accepts([symb_a])) - self.assertTrue(enfa_from_nx.accepts([symb_a, symb_a])) - self.assertFalse(enfa_from_nx.accepts([])) + assert enfa_from_nx.accepts([symb_a]) + assert enfa_from_nx.accepts([symb_a, symb_a]) + assert not enfa_from_nx.accepts([]) def test_iter(self): enfa = EpsilonNFA() @@ -527,10 +524,10 @@ def test_iter(self): counter = 0 for s_from, symb, s_to in enfa: counter += 1 - self.assertIn((s_from, symb, s_to), enfa) - self.assertNotIn((state1, symb_a, state1), enfa) - self.assertIn(("0", "a", 1), enfa) - self.assertEqual(counter, 2) + assert (s_from, symb, s_to) in enfa + assert (state1, symb_a, state1) not in enfa + assert ("0", "a", 1) in enfa + assert counter == 2 def test_equivalent(self): enfa0 = EpsilonNFA() @@ -546,7 +543,7 @@ def test_equivalent(self): enfa1.add_final_state(state1) enfa1.add_transition(state0, symb_a, state1) enfa1.add_transition(state1, symb_a, state1) - self.assertTrue(enfa0.is_equivalent_to(enfa1)) + assert enfa0.is_equivalent_to(enfa1) def test_non_equivalent(self): enfa0 = EpsilonNFA() @@ -562,7 +559,7 @@ def test_non_equivalent(self): enfa1.add_final_state(state1) enfa1.add_transition(state0, symb_a, state1) enfa1.add_transition(state1, symb_a, state0) - self.assertFalse(enfa0.is_equivalent_to(enfa1)) + assert not enfa0.is_equivalent_to(enfa1) def test_get_as_dict(self): enfa0 = EpsilonNFA() @@ -574,17 +571,17 @@ def test_get_as_dict(self): enfa0.add_transition(state0, symb_a, state1) enfa0.add_transition(state1, Epsilon(), state0) d_enfa = enfa0.to_dict() - self.assertIn(state0, d_enfa) - self.assertIn(symb_a, d_enfa[state0]) - self.assertIn(state1, d_enfa[state0][symb_a]) + assert state0 in d_enfa + assert symb_a in d_enfa[state0] + assert state1 in d_enfa[state0][symb_a] def test_len(self): enfa = get_enfa_example1() - self.assertEqual(len(enfa), 1) + assert len(enfa) == 1 def test_call(self): enfa = get_enfa_example1() - self.assertEqual(len(enfa(2)), 1) + assert len(enfa(2)) == 1 def test_example_doc(self): enfa = EpsilonNFA() @@ -602,7 +599,7 @@ def test_example_doc(self): regex = enfa.to_regex() # And turn it back into an epsilon non deterministic automaton enfa2 = regex.to_epsilon_nfa() - self.assertEqual(enfa, enfa2) + assert enfa == enfa2 def test_remove_epsilon_transitions(self): enfa = EpsilonNFA() @@ -612,26 +609,25 @@ def test_remove_epsilon_transitions(self): ("a", "u", "c"), ("b", "epsilon", "d") ]) - self.assertEqual(enfa.get_number_transitions(), 4) + assert enfa.get_number_transitions() == 4 enfa.add_start_state("a") enfa.add_final_state("b") - self.assertEqual(len(enfa.start_states), 1) + assert len(enfa.start_states) == 1 nfa = enfa.remove_epsilon_transitions() - self.assertEqual(len(nfa.start_states), 3) - self.assertEqual(len(nfa.final_states), 2) - self.assertEqual(nfa.get_number_transitions(), 3) - self.assertTrue(nfa.is_equivalent_to(enfa)) + assert len(nfa.start_states) == 3 + assert len(nfa.final_states) == 2 + assert nfa.get_number_transitions() == 3 + assert nfa.is_equivalent_to(enfa) def test_word_generation(self): enfa = get_enfa_example_for_word_generation() accepted_words = list(enfa.get_accepted_words()) - self.assertTrue([] in accepted_words) - self.assertTrue([Symbol("b")] in accepted_words) - self.assertTrue([Symbol("c")] in accepted_words) - self.assertTrue([Symbol("d"), Symbol("e")] in accepted_words) - self.assertTrue( - [Symbol("d"), Symbol("e"), Symbol("f")] in accepted_words) - self.assertEqual(len(accepted_words), 5) + assert [] in accepted_words + assert [Symbol("b")] in accepted_words + assert [Symbol("c")] in accepted_words + assert [Symbol("d"), Symbol("e")] in accepted_words + assert [Symbol("d"), Symbol("e"), Symbol("f")] in accepted_words + assert len(accepted_words) == 5 def get_digits_enfa(): @@ -662,7 +658,8 @@ def get_digits_enfa(): def get_enfa_example0(): - """ Gives an example ENFA + """ + Gives an example ENFA Accepts a*b """ enfa0 = EpsilonNFA() @@ -680,7 +677,8 @@ def get_enfa_example0(): def get_enfa_example1(): - """ Gives and example ENFA + """ + Gives and example ENFA Accepts c """ enfa1 = EpsilonNFA() @@ -717,7 +715,7 @@ def get_enfa_example0_bis(): def get_example_non_minimal(): - """ A non minimal example a.a*.b""" + """ A non minimal example a.a*.b """ enfa0 = EpsilonNFA() state0 = State(0) state3 = State(3) diff --git a/pyformlang/finite_automaton/tests/test_nondeterministic_finite_automaton.py b/pyformlang/finite_automaton/tests/test_nondeterministic_finite_automaton.py index 7417e7f..6612c6a 100644 --- a/pyformlang/finite_automaton/tests/test_nondeterministic_finite_automaton.py +++ b/pyformlang/finite_automaton/tests/test_nondeterministic_finite_automaton.py @@ -1,8 +1,6 @@ -""" -Tests for nondeterministic finite automata -""" +""" Tests for nondeterministic finite automata """ -import unittest +import pytest from pyformlang.finite_automaton import NondeterministicFiniteAutomaton,\ Epsilon @@ -12,25 +10,21 @@ InvalidEpsilonTransition -class TestNondeterministicFiniteAutomaton(unittest.TestCase): - """ - Tests for nondeterministic finite automata - """ +class TestNondeterministicFiniteAutomaton: + """ Tests for nondeterministic finite automata """ # pylint: disable=missing-function-docstring, protected-access def test_creation(self): - """ Test the creation of nfa - """ + """ Test the creation of nfa """ nfa = NondeterministicFiniteAutomaton() - self.assertIsNotNone(nfa) + assert nfa is not None states = [State(x) for x in range(10)] nfa = NondeterministicFiniteAutomaton(start_state=states) - self.assertIsNotNone(nfa) + assert nfa is not None def test_remove_initial(self): - """ Test the remove of initial state - """ + """ Test the remove of initial state """ nfa = NondeterministicFiniteAutomaton() state0 = State(0) state1 = State(1) @@ -38,16 +32,15 @@ def test_remove_initial(self): nfa.add_transition(state0, symb_a, state1) nfa.add_start_state(state0) nfa.add_final_state(state1) - self.assertTrue(nfa.is_deterministic()) - self.assertTrue(nfa.accepts([symb_a])) - self.assertEqual(nfa.remove_start_state(state1), 0) - self.assertTrue(nfa.accepts([symb_a])) - self.assertEqual(nfa.remove_start_state(state0), 1) - self.assertFalse(nfa.accepts([symb_a])) + assert nfa.is_deterministic() + assert nfa.accepts([symb_a]) + assert nfa.remove_start_state(state1) == 0 + assert nfa.accepts([symb_a]) + assert nfa.remove_start_state(state0) == 1 + assert not nfa.accepts([symb_a]) def test_accepts(self): - """ Tests the acceptance of nfa - """ + """ Tests the acceptance of nfa """ nfa = NondeterministicFiniteAutomaton() state0 = State(0) state1 = State(1) @@ -67,31 +60,31 @@ def test_accepts(self): nfa.add_transition(state1, symb_d, state3) nfa.add_transition(state1, symb_c, state4) nfa.add_transition(state1, symb_b, state4) - self.assertFalse(nfa.is_deterministic()) - self.assertTrue(nfa.accepts([symb_a, symb_b, symb_c])) - self.assertTrue(nfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_c])) - self.assertTrue(nfa.accepts([symb_a, symb_b, symb_d])) - self.assertTrue(nfa.accepts([symb_a, symb_d])) - self.assertTrue(nfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_b])) - self.assertFalse(nfa.accepts([symb_a, symb_c, symb_d])) - self.assertFalse(nfa.accepts([symb_d, symb_c, symb_d])) - self.assertFalse(nfa.accepts([])) - self.assertFalse(nfa.accepts([symb_c])) + assert not nfa.is_deterministic() + assert nfa.accepts([symb_a, symb_b, symb_c]) + assert nfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_c]) + assert nfa.accepts([symb_a, symb_b, symb_d]) + assert nfa.accepts([symb_a, symb_d]) + assert nfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_b]) + assert not nfa.accepts([symb_a, symb_c, symb_d]) + assert not nfa.accepts([symb_d, symb_c, symb_d]) + assert not nfa.accepts([]) + assert not nfa.accepts([symb_c]) nfa.add_start_state(state1) - self.assertFalse(nfa.is_deterministic()) - self.assertTrue(nfa.accepts([symb_c])) + assert not nfa.is_deterministic() + assert nfa.accepts([symb_c]) nfa.remove_start_state(state1) dfa = nfa.to_deterministic() - self.assertTrue(dfa.is_deterministic()) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_c])) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_c])) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_d])) - self.assertTrue(dfa.accepts([symb_a, symb_d])) - self.assertTrue(dfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_b])) - self.assertFalse(dfa.accepts([symb_a, symb_c, symb_d])) - self.assertFalse(dfa.accepts([symb_d, symb_c, symb_d])) - self.assertFalse(dfa.accepts([])) - self.assertFalse(dfa.accepts([symb_c])) + assert dfa.is_deterministic() + assert dfa.accepts([symb_a, symb_b, symb_c]) + assert dfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_c]) + assert dfa.accepts([symb_a, symb_b, symb_d]) + assert dfa.accepts([symb_a, symb_d]) + assert dfa.accepts([symb_a, symb_b, symb_b, symb_b, symb_b]) + assert not dfa.accepts([symb_a, symb_c, symb_d]) + assert not dfa.accepts([symb_d, symb_c, symb_d]) + assert not dfa.accepts([]) + assert not dfa.accepts([symb_c]) def test_deterministic(self): """ Tests the deterministic transformation """ @@ -108,26 +101,25 @@ def test_deterministic(self): nfa.add_transition(state0, symb1, state0) nfa.add_transition(state1, symb1, state2) dfa = nfa.to_deterministic() - self.assertEqual(len(dfa.states), 3) - self.assertEqual(dfa.get_number_transitions(), 6) + assert len(dfa.states) == 3 + assert dfa.get_number_transitions() == 6 def test_epsilon_refused(self): dfa = NondeterministicFiniteAutomaton() state0 = State(0) state1 = State(1) - with self.assertRaises(InvalidEpsilonTransition): + with pytest.raises(InvalidEpsilonTransition): dfa.add_transition(state0, Epsilon(), state1) def test_word_generation(self): nfa = get_nfa_example_for_word_generation() accepted_words = list(nfa.get_accepted_words()) - self.assertTrue([] in accepted_words) - self.assertTrue([Symbol("a"), Symbol("b")] in accepted_words) - self.assertTrue([Symbol("a"), Symbol("c")] in accepted_words) - self.assertTrue([Symbol("d"), Symbol("e")] in accepted_words) - self.assertTrue( - [Symbol("d"), Symbol("e"), Symbol("f")] in accepted_words) - self.assertEqual(len(accepted_words), 5) + assert [] in accepted_words + assert [Symbol("a"), Symbol("b")] in accepted_words + assert [Symbol("a"), Symbol("c")] in accepted_words + assert [Symbol("d"), Symbol("e")] in accepted_words + assert [Symbol("d"), Symbol("e"), Symbol("f")] in accepted_words + assert len(accepted_words) == 5 def get_nfa_example_for_word_generation(): diff --git a/pyformlang/finite_automaton/tests/test_nondeterministic_transition_function.py b/pyformlang/finite_automaton/tests/test_nondeterministic_transition_function.py index bf168d0..2eb6c15 100644 --- a/pyformlang/finite_automaton/tests/test_nondeterministic_transition_function.py +++ b/pyformlang/finite_automaton/tests/test_nondeterministic_transition_function.py @@ -1,27 +1,19 @@ -""" -Test the nondeterministic transition functions -""" - - -import unittest +""" Tests for nondeterministic transition functions """ from pyformlang.finite_automaton import State, Symbol, \ NondeterministicTransitionFunction, Epsilon -class TestNondeterministicTransitionFunction(unittest.TestCase): - """ Tests the nondeterministic transitions functions - """ +class TestNondeterministicTransitionFunction: + """ Tests for nondeterministic transition functions """ def test_creation(self): - """ Tests the creation of nondeterministic transition functions - """ + """ Tests the creation of nondeterministic transition functions """ transition_function = NondeterministicTransitionFunction() - self.assertIsNotNone(transition_function) + assert transition_function is not None def test_add_transitions(self): - """ Tests the addition of transitions - """ + """ Tests the addition of transitions """ transition_function = NondeterministicTransitionFunction() s_from = State(0) s_to = State(1) @@ -31,66 +23,63 @@ def test_add_transitions(self): transition_function.add_transition(s_from, symb_by, s_to) transition_function.add_transition(s_from, symb_by, s_to_bis) transition_function.add_transition(s_to, symb_by, s_to) - self.assertEqual(transition_function.get_number_transitions(), 3) + assert transition_function.get_number_transitions() == 3 def test_number_transitions(self): - """ Tests the number of transitions - """ + """ Tests the number of transitions """ transition_function = NondeterministicTransitionFunction() - self.assertEqual(transition_function.get_number_transitions(), 0) + assert transition_function.get_number_transitions() == 0 s_from = State(0) s_to = State(1) s_to_bis = State(2) symb_by = Symbol("a") symb_by2 = Symbol("b") transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function.get_number_transitions(), 1) + assert transition_function.get_number_transitions() == 1 transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function.get_number_transitions(), 1) + assert transition_function.get_number_transitions() == 1 transition_function.add_transition(s_from, symb_by2, s_to_bis) - self.assertEqual(transition_function.get_number_transitions(), 2) + assert transition_function.get_number_transitions() == 2 transition_function.add_transition(s_to, symb_by, s_to_bis) - self.assertEqual(transition_function.get_number_transitions(), 3) + assert transition_function.get_number_transitions() == 3 transition_function.add_transition(s_from, symb_by, s_from) - self.assertEqual(transition_function.get_number_transitions(), 4) + assert transition_function.get_number_transitions() == 4 def test_remove_transitions(self): - """ Tests the removal of transitions - """ + """ Tests the removal of transitions """ transition_function = NondeterministicTransitionFunction() s_from = State(0) s_to = State(1) symb_by = Symbol("a") transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function.remove_transition(s_from, - symb_by, - s_to), 1) - self.assertEqual(len(transition_function(s_to, symb_by)), 0) - self.assertEqual(transition_function.get_number_transitions(), 0) - self.assertEqual(len(transition_function(s_from, symb_by)), 0) - self.assertEqual(transition_function.remove_transition(s_from, - symb_by, - s_to), 0) + assert transition_function.remove_transition(s_from, + symb_by, + s_to) == 1 + assert len(transition_function(s_to, symb_by)) == 0 + assert transition_function.get_number_transitions() == 0 + assert len(transition_function(s_from, symb_by)) == 0 + assert transition_function.remove_transition(s_from, + symb_by, + s_to) == 0 transition_function.add_transition(s_from, symb_by, s_to) transition_function.add_transition(s_from, symb_by, s_from) - self.assertEqual(transition_function.remove_transition(s_from, - symb_by, - s_to), 1) - self.assertEqual(transition_function.get_number_transitions(), 1) - self.assertEqual(len(transition_function(s_from, symb_by)), 1) + assert transition_function.remove_transition(s_from, + symb_by, + s_to) == 1 + assert transition_function.get_number_transitions() == 1 + assert len(transition_function(s_from, symb_by)) == 1 def test_call(self): - """ Tests the call of a transition function - """ + """ Tests the call of a transition function """ transition_function = NondeterministicTransitionFunction() s_from = State(0) s_to = State(1) symb_by = Symbol("a") transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function(s_from, symb_by), {s_to}) - self.assertEqual(len(transition_function(s_to, symb_by)), 0) + assert transition_function(s_from, symb_by) == {s_to} + assert len(transition_function(s_to, symb_by)) == 0 transition_function.add_transition(s_from, symb_by, s_from) - self.assertEqual(transition_function(s_from, symb_by), {s_to, s_from}) + assert transition_function(s_from, symb_by) == {s_to, s_from} def test_get_transitions_from(self): """ Tests iteration of transitions from specified state """ @@ -106,8 +95,8 @@ def test_get_transitions_from(self): transition_function.add_transition(states[1], symbol_c, states[3]) transition_function.add_transition(states[1], epsilon, states[4]) transitions = list(transition_function.get_transitions_from(states[1])) - self.assertTrue((symbol_b, states[2]) in transitions) - self.assertTrue((symbol_c, states[2]) in transitions) - self.assertTrue((symbol_c, states[3]) in transitions) - self.assertTrue((epsilon, states[4]) in transitions) - self.assertEqual(len(transitions), 4) + assert (symbol_b, states[2]) in transitions + assert (symbol_c, states[2]) in transitions + assert (symbol_c, states[3]) in transitions + assert (epsilon, states[4]) in transitions + assert len(transitions) == 4 diff --git a/pyformlang/finite_automaton/tests/test_state.py b/pyformlang/finite_automaton/tests/test_state.py index b37c450..e49b716 100644 --- a/pyformlang/finite_automaton/tests/test_state.py +++ b/pyformlang/finite_automaton/tests/test_state.py @@ -1,50 +1,40 @@ -""" -Tests the states -""" - - -import unittest +""" Tests for states """ from pyformlang.finite_automaton import State -class TestState(unittest.TestCase): - """ Test the states - """ +class TestState: + """ Tests for states """ def test_can_create(self): - """ Tests the creation of states - """ - self.assertIsNotNone(State("")) - self.assertIsNotNone(State(1)) + """ Tests the creation of states """ + assert State("") is not None + assert State(1) is not None def test_repr(self): - """ Tests the representation of states - """ + """ Tests the representation of states """ state1 = State("ABC") - self.assertEqual(str(state1), "ABC") + assert str(state1) == "ABC" state2 = State(1) - self.assertEqual(str(state2), "1") + assert str(state2) == "1" def test_eq(self): - """ Tests the equality of states - """ + """ Tests the equality of states """ state1 = State("ABC") state2 = State(1) state3 = State("ABC") - self.assertEqual(state1, state3) - self.assertTrue(state2 == 1) - self.assertNotEqual(state2, state3) - self.assertEqual(state2, 1) - self.assertNotEqual(state1, state2) + assert state1 == state3 + assert state2 == 1 + assert state2 != state3 + assert state2 == 1 + assert state1 != state2 def test_hash(self): - """ Tests the hashing of states - """ + """ Tests the hashing of states """ state1 = hash(State("ABC")) state2 = hash(State(1)) state3 = hash(State("ABC")) - self.assertIsInstance(state1, int) - self.assertEqual(state1, state3) - self.assertNotEqual(state2, state3) - self.assertNotEqual(state1, state2) + assert isinstance(state1, int) + assert state1 == state3 + assert state2 != state3 + assert state1 != state2 diff --git a/pyformlang/finite_automaton/tests/test_symbol.py b/pyformlang/finite_automaton/tests/test_symbol.py index 63a893d..1a7dd30 100644 --- a/pyformlang/finite_automaton/tests/test_symbol.py +++ b/pyformlang/finite_automaton/tests/test_symbol.py @@ -1,49 +1,39 @@ -""" -Tests for the symbols -""" - - -import unittest +""" Tests for symbols """ from pyformlang.finite_automaton import Symbol -class TestSymbol(unittest.TestCase): - """ Tests for the symbols - """ +class TestSymbol: + """ Tests for symbols """ def test_can_create(self): - """ Tests the creation of symbols - """ - self.assertIsNotNone(Symbol("")) - self.assertIsNotNone(Symbol(1)) + """ Tests the creation of symbols """ + assert Symbol("") is not None + assert Symbol(1) is not None def test_repr(self): - """ Tests the representation of symbols - """ + """ Tests the representation of symbols """ symbol1 = Symbol("ABC") - self.assertEqual(str(symbol1), "ABC") + assert str(symbol1) == "ABC" symbol2 = Symbol(1) - self.assertEqual(str(symbol2), "1") + assert str(symbol2) == "1" def test_eq(self): - """ Tests equality of symbols - """ + """ Tests equality of symbols """ symbol1 = Symbol("ABC") symbol2 = Symbol(1) symbol3 = Symbol("ABC") - self.assertEqual(symbol1, symbol3) - self.assertEqual(symbol2, 1) - self.assertNotEqual(symbol2, symbol3) - self.assertNotEqual(symbol1, symbol2) + assert symbol1 == symbol3 + assert symbol2 == 1 + assert symbol2 != symbol3 + assert symbol1 != symbol2 def test_hash(self): - """ Tests the hashing of symbols - """ + """ Tests the hashing of symbols """ symbol1 = hash(Symbol("ABC")) symbol2 = hash(Symbol(1)) symbol3 = hash(Symbol("ABC")) - self.assertIsInstance(symbol1, int) - self.assertEqual(symbol1, symbol3) - self.assertNotEqual(symbol2, symbol3) - self.assertNotEqual(symbol1, symbol2) + assert isinstance(symbol1, int) + assert symbol1 == symbol3 + assert symbol2 != symbol3 + assert symbol1 != symbol2 diff --git a/pyformlang/finite_automaton/tests/test_transition_function.py b/pyformlang/finite_automaton/tests/test_transition_function.py index 59bc3b0..d9cf11b 100644 --- a/pyformlang/finite_automaton/tests/test_transition_function.py +++ b/pyformlang/finite_automaton/tests/test_transition_function.py @@ -1,27 +1,21 @@ -""" -Test the transition functions -""" - -import unittest +""" Tests for transition functions """ +import pytest from pyformlang.finite_automaton import State, Symbol, TransitionFunction, \ DuplicateTransitionError, InvalidEpsilonTransition, Epsilon -class TestTransitionFunction(unittest.TestCase): - """ Tests the transitions functions - """ +class TestTransitionFunction: + """ Tests for transition functions """ def test_creation(self): - """ Tests the creation of transition functions - """ + """ Tests the creation of transition functions """ transition_function = TransitionFunction() - self.assertIsNotNone(transition_function) + assert transition_function is not None # pylint: disable=protected-access def test_add_transitions(self): - """ Tests the addition of transitions - """ + """ Tests the addition of transitions """ transition_function = TransitionFunction() s_from = State(10) s_to = State(11) @@ -29,66 +23,63 @@ def test_add_transitions(self): symb_by = Symbol("abc") transition_function.add_transition(s_from, symb_by, s_to) transition_function.add_transition(s_from, symb_by, s_to) - with self.assertRaises(DuplicateTransitionError) as dte: + with pytest.raises(DuplicateTransitionError) as dte: transition_function.add_transition(s_from, symb_by, s_to_bis) - dte = dte.exception - self.assertEqual(dte.s_from, s_from) - self.assertEqual(dte.s_to, s_to_bis) - self.assertEqual(dte.symb_by, symb_by) - self.assertEqual(dte.s_to_old, s_to) + dte = dte.value + assert dte.s_from == s_from + assert dte.s_to == s_to_bis + assert dte.symb_by == symb_by + assert dte.s_to_old == s_to def test_number_transitions(self): - """ Tests the number of transitions - """ + """ Tests the number of transitions """ transition_function = TransitionFunction() - self.assertEqual(transition_function.get_number_transitions(), 0) + assert transition_function.get_number_transitions() == 0 s_from = State(110) s_to = State(12) s_to_bis = State(2) symb_by = Symbol("a") transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function.get_number_transitions(), 1) + assert transition_function.get_number_transitions() == 1 transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function.get_number_transitions(), 1) + assert transition_function.get_number_transitions() == 1 symb_by2 = Symbol("bc") transition_function.add_transition(s_from, symb_by2, s_to_bis) - self.assertEqual(transition_function.get_number_transitions(), 2) + assert transition_function.get_number_transitions() == 2 transition_function.add_transition(s_to, symb_by, s_to_bis) - self.assertEqual(transition_function.get_number_transitions(), 3) + assert transition_function.get_number_transitions() == 3 def test_remove_transitions(self): - """ Tests the removal of transitions - """ + """ Tests the removal of transitions """ transition_function = TransitionFunction() s_from = State(10) s_to = State(11) symb_by = Symbol("abc") transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function.remove_transition(s_from, - symb_by, - s_to), 1) - self.assertEqual(transition_function.get_number_transitions(), 0) - self.assertEqual(transition_function(s_to, symb_by), []) - self.assertEqual(transition_function(s_from, symb_by), []) - self.assertEqual(transition_function.remove_transition(s_from, - symb_by, - s_to), 0) + assert transition_function.remove_transition(s_from, + symb_by, + s_to) == 1 + assert transition_function.get_number_transitions() == 0 + assert transition_function(s_to, symb_by) == [] + assert transition_function(s_from, symb_by) == [] + assert transition_function.remove_transition(s_from, + symb_by, + s_to) == 0 def test_call(self): - """ Tests the call of a transition function - """ + """ Tests the call of a transition function """ transition_function = TransitionFunction() s_from = State(0) s_to = State(1) symb_by = Symbol("a") transition_function.add_transition(s_from, symb_by, s_to) - self.assertEqual(transition_function(s_from, symb_by), [s_to]) - self.assertEqual(transition_function(s_to, symb_by), []) + assert transition_function(s_from, symb_by) == [s_to] + assert transition_function(s_to, symb_by) == [] def test_invalid_epsilon(self): """ Tests invalid transition """ transition_function = TransitionFunction() - with self.assertRaises(InvalidEpsilonTransition): + with pytest.raises(InvalidEpsilonTransition): transition_function.add_transition("1", Epsilon(), "2") def test_get_transitions_from(self): @@ -104,7 +95,7 @@ def test_get_transitions_from(self): transition_function.add_transition(states[1], symbol_c, states[2]) transition_function.add_transition(states[1], symbol_d, states[3]) transitions = list(transition_function.get_transitions_from(states[1])) - self.assertTrue((symbol_b, states[2]) in transitions) - self.assertTrue((symbol_c, states[2]) in transitions) - self.assertTrue((symbol_d, states[3]) in transitions) - self.assertEqual(len(transitions), 3) + assert (symbol_b, states[2]) in transitions + assert (symbol_c, states[2]) in transitions + assert (symbol_d, states[3]) in transitions + assert len(transitions) == 3 diff --git a/pyformlang/fst/tests/test_fst.py b/pyformlang/fst/tests/test_fst.py index a097034..84888af 100644 --- a/pyformlang/fst/tests/test_fst.py +++ b/pyformlang/fst/tests/test_fst.py @@ -1,8 +1,9 @@ -""" Tests the FST """ -# pylint: disable=duplicate-code +""" Tests for the FST """ +# pylint: disable=duplicate-code +# pylint: disable=missing-function-docstring +# pylint: disable=attribute-defined-outside-init -import unittest from os import path from pyformlang.fst import FST @@ -11,10 +12,10 @@ ConsumptionRule, IndexedGrammar, Rules) -class TestFST(unittest.TestCase): - """ Tests FST """ +class TestFST: + """ Tests for the FST """ - def setUp(self) -> None: + def setup_method(self) -> None: self.fst0 = FST() self.fst0.add_start_state("q0") self.fst0.add_transition("q0", "a", "q1", ["b"]) @@ -27,66 +28,66 @@ def setUp(self) -> None: def test_creation(self): """ Test Translate """ fst = FST() - self.assertIsNotNone(fst) - self.assertEqual(len(fst.states), 0) - self.assertEqual(len(fst.input_symbols), 0) - self.assertEqual(len(fst.output_symbols), 0) - self.assertEqual(fst.get_number_transitions(), 0) - self.assertEqual(len(fst.final_states), 0) + assert fst is not None + assert len(fst.states) == 0 + assert len(fst.input_symbols) == 0 + assert len(fst.output_symbols) == 0 + assert fst.get_number_transitions() == 0 + assert len(fst.final_states) == 0 fst.add_start_state("q0") - self.assertEqual(len(fst.states), 1) + assert len(fst.states) == 1 fst.add_transition("q0", "a", "q1", ["bc"]) - self.assertEqual(len(fst.states), 2) - self.assertEqual(len(fst.input_symbols), 1) - self.assertEqual(len(fst.output_symbols), 1) - self.assertEqual(fst.get_number_transitions(), 1) - self.assertEqual(len(fst.final_states), 0) + assert len(fst.states) == 2 + assert len(fst.input_symbols) == 1 + assert len(fst.output_symbols) == 1 + assert fst.get_number_transitions() == 1 + assert len(fst.final_states) == 0 fst.add_transition("q0", "epsilon", "q1", ["bc"]) - self.assertEqual(len(fst.states), 2) - self.assertEqual(len(fst.input_symbols), 1) - self.assertEqual(len(fst.output_symbols), 1) - self.assertEqual(fst.get_number_transitions(), 2) - self.assertEqual(len(fst.final_states), 0) + assert len(fst.states) == 2 + assert len(fst.input_symbols) == 1 + assert len(fst.output_symbols) == 1 + assert fst.get_number_transitions() == 2 + assert len(fst.final_states) == 0 fst.add_final_state("q2") - self.assertEqual(len(fst.states), 3) - self.assertEqual(len(fst.input_symbols), 1) - self.assertEqual(len(fst.output_symbols), 1) - self.assertEqual(fst.get_number_transitions(), 2) - self.assertEqual(len(fst.final_states), 1) + assert len(fst.states) == 3 + assert len(fst.input_symbols) == 1 + assert len(fst.output_symbols) == 1 + assert fst.get_number_transitions() == 2 + assert len(fst.final_states) == 1 fst.add_transition("q0", "a", "q1", ["d"]) - self.assertEqual(len(fst.states), 3) - self.assertEqual(len(fst.input_symbols), 1) - self.assertEqual(len(fst.output_symbols), 2) - self.assertEqual(fst.get_number_transitions(), 3) - self.assertEqual(len(fst.final_states), 1) + assert len(fst.states) == 3 + assert len(fst.input_symbols) == 1 + assert len(fst.output_symbols) == 2 + assert fst.get_number_transitions() == 3 + assert len(fst.final_states) == 1 def test_translate(self): """ Test a translation """ fst = FST() fst.add_start_state("q0") translation = list(fst.translate(["a"])) - self.assertEqual(len(translation), 0) + assert len(translation) == 0 fst.add_transition("q0", "a", "q1", ["b"]) translation = list(fst.translate(["a"])) - self.assertEqual(len(translation), 0) + assert len(translation) == 0 fst.add_final_state("q1") translation = list(fst.translate(["a"])) - self.assertEqual(len(translation), 1) - self.assertEqual(translation, [["b"]]) + assert len(translation) == 1 + assert translation == [["b"]] fst.add_transition("q1", "epsilon", "q1", ["c"]) translation = list(fst.translate(["a"], max_length=10)) - self.assertEqual(len(translation), 10) - self.assertIn(["b"], translation) - self.assertIn(["b", "c"], translation) - self.assertIn(["b"] + ["c"] * 9, translation) + assert len(translation) == 10 + assert ["b"] in translation + assert ["b", "c"] in translation + assert ["b"] + ["c"] * 9 in translation def test_intersection_indexed_grammar(self): """ Test the intersection with indexed grammar """ @@ -95,7 +96,7 @@ def test_intersection_indexed_grammar(self): indexed_grammar = IndexedGrammar(rules) fst = FST() intersection = fst & indexed_grammar - self.assertTrue(intersection.is_empty()) + assert intersection.is_empty() l_rules.append(ProductionRule("S", "D", "f")) l_rules.append(DuplicationRule("D", "A", "B")) @@ -107,14 +108,14 @@ def test_intersection_indexed_grammar(self): rules = Rules(l_rules) indexed_grammar = IndexedGrammar(rules) intersection = fst.intersection(indexed_grammar) - self.assertTrue(intersection.is_empty()) + assert intersection.is_empty() fst.add_start_state("q0") fst.add_final_state("final") fst.add_transition("q0", "a", "q1", ["a"]) fst.add_transition("q1", "b", "final", ["b"]) intersection = fst.intersection(indexed_grammar) - self.assertFalse(intersection.is_empty()) + assert not intersection.is_empty() def test_union(self): """ Tests the union""" @@ -124,45 +125,45 @@ def test_union(self): self._make_test_fst_union(fst_union) def _make_test_fst_union(self, fst_union): - self.assertEqual(len(fst_union.start_states), 2) - self.assertEqual(len(fst_union.final_states), 2) - self.assertEqual(fst_union.get_number_transitions(), 2) + assert len(fst_union.start_states) == 2 + assert len(fst_union.final_states) == 2 + assert fst_union.get_number_transitions() == 2 translation = list(fst_union.translate(["a"])) - self.assertEqual(translation, [["b"]]) + assert translation == [["b"]] translation = list(fst_union.translate(["b"])) - self.assertEqual(translation, [["c"]]) + assert translation == [["c"]] translation = list(fst_union.translate(["a", "b"])) - self.assertEqual(translation, []) + assert not translation def test_concatenate(self): """ Tests the concatenation """ fst_concatenate = self.fst0 + self.fst1 translation = list(fst_concatenate.translate(["a", "b"])) - self.assertEqual(translation, [["b", "c"]]) + assert translation == [["b", "c"]] translation = list(fst_concatenate.translate(["a"])) - self.assertEqual(translation, []) + assert not translation translation = list(fst_concatenate.translate(["b"])) - self.assertEqual(translation, []) + assert not translation def test_concatenate2(self): """ Tests the concatenation """ fst_concatenate = self.fst0 + self.fst1 + self.fst1 translation = list(fst_concatenate.translate(["a", "b", "b"])) - self.assertEqual(translation, [["b", "c", "c"]]) + assert translation == [["b", "c", "c"]] translation = list(fst_concatenate.translate(["a"])) - self.assertEqual(translation, []) + assert not translation translation = list(fst_concatenate.translate(["b"])) - self.assertEqual(translation, []) + assert not translation def test_kleene_start(self): """ Tests the kleene star on a fst""" fst_star = self.fst0.kleene_star() translation = list(fst_star.translate(["a"])) - self.assertEqual(translation, [["b"]]) + assert translation == [["b"]] translation = list(fst_star.translate(["a", "a"])) - self.assertEqual(translation, [["b", "b"]]) + assert translation == [["b", "b"]] translation = list(fst_star.translate([])) - self.assertEqual(translation, [[]]) + assert translation == [[]] def test_generate_empty_word_from_nothing(self): """ Generate empty word from nothing """ @@ -171,7 +172,7 @@ def test_generate_empty_word_from_nothing(self): fst.add_transition("q0", "epsilon", "q1", []) fst.add_final_state("q1") translation = list(fst.translate([])) - self.assertEqual(translation, [[]]) + assert translation == [[]] def test_epsilon_loop(self): """ Test empty loop """ @@ -181,7 +182,7 @@ def test_epsilon_loop(self): fst.add_final_state("q1") fst.add_transition("q1", "epsilon", "q0", []) translation = list(fst.translate([])) - self.assertEqual(translation, [[]]) + assert translation == [[]] def test_epsilon_loop2(self): """ Test empty loop bis """ @@ -193,7 +194,7 @@ def test_epsilon_loop2(self): ("q1", "epsilon", "q0", [])]) fst.add_final_state("q2") translation = list(fst.translate(["a"])) - self.assertEqual(translation, [["b"]]) + assert translation == [["b"]] def test_paper(self): """ Test for the paper """ @@ -204,14 +205,12 @@ def test_paper(self): (2, "alone", 3, ["seul"])]) fst.add_start_state(0) fst.add_final_state(3) - self.assertEqual( - list(fst.translate(["I", "am", "alone"])), + assert list(fst.translate(["I", "am", "alone"])) == \ [['Je', 'suis', 'seul'], - ['Je', 'suis', 'tout', 'seul']]) + ['Je', 'suis', 'tout', 'seul']] fst = FST.from_networkx(fst.to_networkx()) - self.assertEqual( - list(fst.translate(["I", "am", "alone"])), + assert list(fst.translate(["I", "am", "alone"])) == \ [['Je', 'suis', 'seul'], - ['Je', 'suis', 'tout', 'seul']]) + ['Je', 'suis', 'tout', 'seul']] fst.write_as_dot("fst.dot") - self.assertTrue(path.exists("fst.dot")) + assert path.exists("fst.dot") diff --git a/pyformlang/indexed_grammar/tests/test_indexed_grammar.py b/pyformlang/indexed_grammar/tests/test_indexed_grammar.py index 8db742d..16cdfe6 100644 --- a/pyformlang/indexed_grammar/tests/test_indexed_grammar.py +++ b/pyformlang/indexed_grammar/tests/test_indexed_grammar.py @@ -1,8 +1,6 @@ -""" -Testing of indexed grammar, with manual rules -""" +""" Testing of indexed grammar, with manual rules """ -import unittest +# pylint: disable=missing-function-docstring from pyformlang.indexed_grammar import Rules from pyformlang.indexed_grammar import ConsumptionRule @@ -13,21 +11,16 @@ from pyformlang.regular_expression import Regex -class TestIndexedGrammar(unittest.TestCase): - """ Tests the indexed grammar """ - - # pylint: disable=missing-function-docstring +class TestIndexedGrammar: + """ Tests for the indexed grammar """ def test_simple_ig_0(self): - """Test""" - l_rules = get_example_rules() - for i in range(9): rules = Rules(l_rules, i) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) - self.assertEqual(i_grammar.terminals, {"end", "b", "epsilon"}) + assert not i_grammar.is_empty() + assert i_grammar.terminals == {"end", "b", "epsilon"} def test_simple_ig_1(self): # Write rules @@ -61,7 +54,7 @@ def test_simple_ig_1(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_simple_ig_2(self): # Write rules @@ -91,7 +84,7 @@ def test_simple_ig_2(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertTrue(i_grammar.is_empty()) + assert i_grammar.is_empty() def test_simple_ig_3(self): # Write rules @@ -113,7 +106,7 @@ def test_simple_ig_3(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertTrue(i_grammar.is_empty()) + assert i_grammar.is_empty() def test_simple_ig_4(self): # Write rules @@ -152,7 +145,7 @@ def test_simple_ig_4(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertTrue(i_grammar.is_empty()) + assert i_grammar.is_empty() def test_simple_ig_5(self): # Write rules @@ -171,10 +164,10 @@ def test_simple_ig_5(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_simple_ig_regular_expression(self): - # Test for regular expression functions + """ Test for regular expression functions """ l_rules = [] l_rules.append(ProductionRule("S", "Ci", "end")) @@ -193,21 +186,20 @@ def test_simple_ig_regular_expression(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_simple_ig6(self): - """ Test number 6 """ l_rules = [] l_rules.append(DuplicationRule("S", "S", "B")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertTrue(i_grammar.is_empty()) + assert i_grammar.is_empty() l_rules = [] l_rules.append(DuplicationRule("S", "B", "S")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertTrue(i_grammar.is_empty()) + assert i_grammar.is_empty() l_rules = [] l_rules.append(DuplicationRule("S", "A", "B")) @@ -215,10 +207,9 @@ def test_simple_ig6(self): l_rules.append(EndRule("B", "b")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_simple_ig7(self): - """ Test 7 """ l_rules = [] l_rules.append(ProductionRule("S", "A", "end")) l_rules.append(ConsumptionRule("end", "A", "S")) @@ -227,10 +218,9 @@ def test_simple_ig7(self): l_rules.append(EndRule("C", "c")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_simple_ig8(self): - """ Tests 8 """ l_rules = [] l_rules.append(ProductionRule("S", "Q", "end")) l_rules.append(ProductionRule("Q", "A", "end")) @@ -243,10 +233,10 @@ def test_simple_ig8(self): l_rules.append(EndRule("G", "G")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_simple_ig9(self): - """ Tests 9 {a^n b^n c^n}""" + """ {a^n b^n c^n} """ l_rules = [] l_rules.append(ProductionRule("S", "T", "g")) l_rules.append(ProductionRule("T", "T", "f")) @@ -266,7 +256,7 @@ def test_simple_ig9(self): l_rules.append(ConsumptionRule("g", "C", "Cfinal")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules) - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_start_symbol(self): """ Tests the change of the start symbol """ @@ -274,16 +264,16 @@ def test_start_symbol(self): l_rules.append(EndRule("S", "s")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules, "S2") - self.assertTrue(i_grammar.is_empty()) + assert i_grammar.is_empty() i_grammar = IndexedGrammar(rules, "S") - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() l_rules = [] l_rules.append(EndRule("S2", "s")) rules = Rules(l_rules) i_grammar = IndexedGrammar(rules, start_variable="S2") - self.assertFalse(i_grammar.is_empty()) + assert not i_grammar.is_empty() def test_reachable(self): """ Tests the reachable symbols """ @@ -300,7 +290,7 @@ def test_reachable(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules, start_variable="S") reachable = i_grammar.get_reachable_non_terminals() - self.assertEqual(reachable, {"S", "A", "B", "D", "G"}) + assert reachable == {"S", "A", "B", "D", "G"} def test_generating(self): """ Tests the generating symbols """ @@ -317,7 +307,7 @@ def test_generating(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules, start_variable="S") generating = i_grammar.get_generating_non_terminals() - self.assertEqual(generating, {"D", "A", "E", "Q"}) + assert generating == {"D", "A", "E", "Q"} def test_removal_useless(self): """ Tests the removal of useless symbols """ @@ -335,14 +325,15 @@ def test_removal_useless(self): rules = Rules(l_rules) i_grammar = IndexedGrammar(rules, start_variable="S") i_grammar2 = i_grammar.remove_useless_rules() - self.assertFalse(i_grammar.is_empty()) - self.assertEqual(i_grammar2.non_terminals, - i_grammar2.get_generating_non_terminals()) - self.assertEqual(i_grammar2.non_terminals, - i_grammar2.get_reachable_non_terminals()) + assert not i_grammar.is_empty() + assert i_grammar2.non_terminals == \ + i_grammar2.get_generating_non_terminals() + assert i_grammar2.non_terminals == \ + i_grammar2.get_reachable_non_terminals() def test_intersection(self): - """ Tests the intersection of indexed grammar with regex + """ + Tests the intersection of indexed grammar with regex. Long to run! """ l_rules = [ProductionRule("S", "D", "f"), @@ -353,7 +344,7 @@ def test_intersection(self): rules = Rules(l_rules, 6) indexed_grammar = IndexedGrammar(rules) i_inter = indexed_grammar.intersection(Regex("a.b")) - self.assertTrue(i_inter) + assert i_inter def get_example_rules(): diff --git a/pyformlang/indexed_grammar/tests/test_rules.py b/pyformlang/indexed_grammar/tests/test_rules.py index 35d7320..f754e0b 100644 --- a/pyformlang/indexed_grammar/tests/test_rules.py +++ b/pyformlang/indexed_grammar/tests/test_rules.py @@ -1,9 +1,4 @@ -""" -Testing the rules -""" - -import unittest - +""" Testing of the rules """ from pyformlang.indexed_grammar import ProductionRule from pyformlang.indexed_grammar import DuplicationRule @@ -14,8 +9,8 @@ import get_example_rules -class TestIndexedGrammar(unittest.TestCase): - """ Tests things related to rules """ +class TestIndexedGrammar: + """ Tests for things related to rules """ # pylint: disable=missing-function-docstring @@ -23,37 +18,36 @@ def test_consumption_rules(self): """ Tests the consumption rules """ conso = ConsumptionRule("end", "C", "T") terminals = conso.terminals - self.assertEqual(terminals, {"end"}) + assert terminals == {"end"} representation = str(conso) - self.assertEqual(representation, "C [ end ] -> T") + assert representation == "C [ end ] -> T" def test_duplication_rules(self): """ Tests the duplication rules """ dupli = DuplicationRule("B0", "A0", "C") - self.assertEqual(dupli.terminals, set()) - self.assertEqual(str(dupli), - "B0 -> A0 C") + assert dupli.terminals == set() + assert str(dupli) == "B0 -> A0 C" def test_end_rule(self): """ Tests the end rules """ end_rule = EndRule("A0", "b") - self.assertEqual(end_rule.terminals, {"b"}) - self.assertEqual(end_rule.right_term, "b") - self.assertEqual(str(end_rule), "A0 -> b") + assert end_rule.terminals == {"b"} + assert end_rule.right_term == "b" + assert str(end_rule) == "A0 -> b" def test_production_rules(self): """ Tests the production rules """ produ = ProductionRule("S", "C", "end") - self.assertEqual(produ.terminals, {"end"}) - self.assertEqual(str(produ), "S -> C[ end ]") + assert produ.terminals == {"end"} + assert str(produ) == "S -> C[ end ]" def test_rules(self): """ Tests the rules """ l_rules = get_example_rules() rules = Rules(l_rules) - self.assertEqual(rules.terminals, {"b", "end", "epsilon"}) - self.assertEqual(rules.length, (5, 2)) + assert rules.terminals == {"b", "end", "epsilon"} + assert rules.length == (5, 2) rules.remove_production("S", "Cinit", "end") - self.assertEqual(rules.length, (4, 2)) + assert rules.length == (4, 2) rules.add_production("S", "Cinit", "end") - self.assertEqual(rules.length, (5, 2)) + assert rules.length == (5, 2) diff --git a/pyformlang/pda/tests/test_pda.py b/pyformlang/pda/tests/test_pda.py index 70728aa..ca76310 100644 --- a/pyformlang/pda/tests/test_pda.py +++ b/pyformlang/pda/tests/test_pda.py @@ -1,6 +1,5 @@ -""" Tests the PDA """ +""" Tests for the PDA """ -import unittest from os import path from pyformlang.pda import PDA, State, StackSymbol, Symbol, Epsilon @@ -10,72 +9,72 @@ from pyformlang.regular_expression import Regex -class TestPDA(unittest.TestCase): - """ Tests the pushdown automata """ +class TestPDA: + """ Tests for the pushdown automata """ def test_creation(self): """ Test of creation """ pda = PDA() - self.assertIsNotNone(pda) - self.assertEqual(len(pda.states), 0) - self.assertEqual(len(pda.final_states), 0) - self.assertEqual(len(pda.input_symbols), 0) - self.assertEqual(len(pda.stack_symbols), 0) - self.assertEqual(len(pda.to_dict()), 0) + assert pda is not None + assert len(pda.states) == 0 + assert len(pda.final_states) == 0 + assert len(pda.input_symbols) == 0 + assert len(pda.stack_symbols) == 0 + assert len(pda.to_dict()) == 0 pda = PDA(start_state=State("A")) - self.assertIsNotNone(pda) - self.assertEqual(len(pda.states), 1) - self.assertEqual(len(pda.stack_symbols), 0) - self.assertEqual(len(pda.final_states), 0) + assert pda is not None + assert len(pda.states) == 1 + assert len(pda.stack_symbols) == 0 + assert len(pda.final_states) == 0 pda = PDA(final_states={State("A"), State("A"), State("B"), Symbol("B")}) - self.assertIsNotNone(pda) - self.assertEqual(len(pda.states), 3) - self.assertEqual(len(pda.input_symbols), 0) - self.assertEqual(len(pda.stack_symbols), 0) - self.assertEqual(len(pda.final_states), 3) + assert pda is not None + assert len(pda.states) == 3 + assert len(pda.input_symbols) == 0 + assert len(pda.stack_symbols) == 0 + assert len(pda.final_states) == 3 pda = PDA(input_symbols={Symbol("A"), Symbol("B"), Symbol("A"), State("A")}) - self.assertIsNotNone(pda) - self.assertEqual(len(pda.states), 0) - self.assertEqual(len(pda.input_symbols), 3) - self.assertEqual(len(pda.stack_symbols), 0) - self.assertEqual(len(pda.final_states), 0) + assert pda is not None + assert len(pda.states) == 0 + assert len(pda.input_symbols) == 3 + assert len(pda.stack_symbols) == 0 + assert len(pda.final_states) == 0 pda = PDA(start_stack_symbol=StackSymbol("A")) - self.assertIsNotNone(pda) - self.assertEqual(len(pda.input_symbols), 0) - self.assertEqual(len(pda.states), 0) - self.assertEqual(len(pda.stack_symbols), 1) - self.assertEqual(len(pda.final_states), 0) + assert pda is not None + assert len(pda.input_symbols) == 0 + assert len(pda.states) == 0 + assert len(pda.stack_symbols) == 1 + assert len(pda.final_states) == 0 pda = PDA(stack_alphabet={StackSymbol("A"), StackSymbol("A"), StackSymbol("B")}) - self.assertIsNotNone(pda) - self.assertEqual(len(pda.states), 0) - self.assertEqual(len(pda.input_symbols), 0) - self.assertEqual(len(pda.stack_symbols), 2) - self.assertEqual(len(pda.final_states), 0) + assert pda is not None + assert len(pda.states) == 0 + assert len(pda.input_symbols) == 0 + assert len(pda.stack_symbols) == 2 + assert len(pda.final_states) == 0 pda = PDA(input_symbols={Epsilon()}) - self.assertIsNotNone(pda) - self.assertEqual(len(pda.states), 0) - self.assertEqual(len(pda.input_symbols), 1) - self.assertEqual(len(pda.stack_symbols), 0) - self.assertEqual(pda.get_number_transitions(), 0) - self.assertEqual(len(pda.final_states), 0) + assert pda is not None + assert len(pda.states) == 0 + assert len(pda.input_symbols) == 1 + assert len(pda.stack_symbols) == 0 + assert pda.get_number_transitions() == 0 + assert len(pda.final_states) == 0 def test_represent(self): """ Tests representations """ symb = Symbol("S") - self.assertEqual(str(symb), "Symbol(S)") + assert str(symb) == "Symbol(S)" state = State("T") - self.assertEqual(str(state), "State(T)") + assert str(state) == "State(T)" stack_symb = StackSymbol("U") - self.assertEqual(str(stack_symb), "StackSymbol(U)") + assert str(stack_symb) == "StackSymbol(U)" def test_transition(self): """ Tests the creation of transition """ @@ -85,19 +84,19 @@ def test_transition(self): StackSymbol("stack symbol"), State("to"), [StackSymbol("A"), StackSymbol("B")]) - self.assertEqual(len(pda.states), 2) - self.assertEqual(len(pda.input_symbols), 1) - self.assertEqual(len(pda.stack_symbols), 3) - self.assertEqual(pda.get_number_transitions(), 1) + assert len(pda.states) == 2 + assert len(pda.input_symbols) == 1 + assert len(pda.stack_symbols) == 3 + assert pda.get_number_transitions() == 1 pda.add_transition(State("from"), Epsilon(), StackSymbol("stack symbol"), State("to"), [StackSymbol("A"), StackSymbol("B")]) - self.assertEqual(len(pda.states), 2) - self.assertEqual(len(pda.input_symbols), 1) - self.assertEqual(len(pda.stack_symbols), 3) - self.assertEqual(pda.get_number_transitions(), 2) + assert len(pda.states) == 2 + assert len(pda.input_symbols) == 1 + assert len(pda.stack_symbols) == 3 + assert pda.get_number_transitions() == 2 def test_example62(self): """ Example from the book """ @@ -115,10 +114,10 @@ def test_example62(self): start_state=state0, start_stack_symbol=ss_z0, final_states={state2}) - self.assertEqual(len(pda.states), 3) - self.assertEqual(len(pda.input_symbols), 2) - self.assertEqual(len(pda.stack_symbols), 3) - self.assertEqual(pda.get_number_transitions(), 0) + assert len(pda.states) == 3 + assert len(pda.input_symbols) == 2 + assert len(pda.stack_symbols) == 3 + assert pda.get_number_transitions() == 0 pda.add_transition(state0, s_zero, ss_z0, state0, [ss_zero, ss_z0]) pda.add_transition(state0, s_one, ss_z0, state0, [ss_one, ss_z0]) @@ -137,16 +136,16 @@ def test_example62(self): pda.add_transition(state1, Epsilon(), ss_z0, state2, [ss_z0]) - self.assertEqual(pda.get_number_transitions(), 12) + assert pda.get_number_transitions() == 12 t_zero = Terminal("0") t_one = Terminal("1") cfg = pda.to_empty_stack().to_cfg() - self.assertTrue(cfg.contains([])) - self.assertTrue(cfg.contains([t_zero, t_zero])) - self.assertTrue(cfg.contains([t_zero, t_one, t_one, t_zero])) - self.assertFalse(cfg.contains([t_zero])) - self.assertFalse(cfg.contains([t_zero, t_one, t_zero])) + assert cfg.contains([]) + assert cfg.contains([t_zero, t_zero]) + assert cfg.contains([t_zero, t_one, t_one, t_zero]) + assert not cfg.contains([t_zero]) + assert not cfg.contains([t_zero, t_one, t_zero]) def test_to_final_state(self): """ Test transformation to final state """ @@ -166,11 +165,11 @@ def test_to_final_state(self): [symbol_z, symbol_z]) pda.add_transition(state, symbol_e, symbol_z, state, []) new_pda = pda.to_final_state() - self.assertEqual(len(new_pda.states), 3) - self.assertEqual(len(new_pda.input_symbols), 2) - self.assertEqual(len(new_pda.stack_symbols), 2) - self.assertEqual(new_pda.get_number_transitions(), 4) - self.assertEqual(len(new_pda.final_states), 1) + assert len(new_pda.states) == 3 + assert len(new_pda.input_symbols) == 2 + assert len(new_pda.stack_symbols) == 2 + assert new_pda.get_number_transitions() == 4 + assert len(new_pda.final_states) == 1 def test_to_empty_stack(self): """ Test transformation to empty stack """ @@ -193,11 +192,11 @@ def test_to_empty_stack(self): pda.add_transition(state_q, symbol_e, symbol_z, state_q, []) pda.add_transition(state_q, Epsilon(), symbol_z0, state_q0, []) new_pda = pda.to_empty_stack() - self.assertEqual(len(new_pda.states), 4) - self.assertEqual(len(new_pda.input_symbols), 2) - self.assertEqual(len(new_pda.stack_symbols), 3) - self.assertEqual(new_pda.get_number_transitions(), 11) - self.assertEqual(len(new_pda.final_states), 0) + assert len(new_pda.states) == 4 + assert len(new_pda.input_symbols) == 2 + assert len(new_pda.stack_symbols) == 3 + assert new_pda.get_number_transitions() == 11 + assert len(new_pda.final_states) == 0 def test_to_cfg(self): """ Test the transformation to CFG """ @@ -214,9 +213,9 @@ def test_to_cfg(self): [symbol_z, symbol_z]) pda.add_transition(state_q, symbol_e, symbol_z, state_q, []) cfg = pda.to_cfg() - self.assertEqual(len(cfg.variables), 2) - self.assertEqual(len(cfg.terminals), 2) - self.assertEqual(len(cfg.productions), 3) + assert len(cfg.variables) == 2 + assert len(cfg.terminals) == 2 + assert len(cfg.productions) == 3 pda = PDA(states={"q"}, input_symbols={"i", "e"}, @@ -226,9 +225,9 @@ def test_to_cfg(self): pda.add_transition("q", "i", "Z", "q", ("Z", "Z")) pda.add_transition("q", "e", "Z", "q", []) cfg = pda.to_cfg() - self.assertEqual(len(cfg.variables), 2) - self.assertEqual(len(cfg.terminals), 2) - self.assertEqual(len(cfg.productions), 3) + assert len(cfg.variables) == 2 + assert len(cfg.terminals) == 2 + assert len(cfg.productions) == 3 pda.add_transition("q", "epsilon", "Z", "q", ["Z"]) def test_pda_conversion(self): @@ -260,9 +259,9 @@ def test_pda_conversion(self): pda.add_transition(state_p, state_b, stack_symbol_b, state_p, []) pda.add_transition(state_p, state_c, stack_symbol_c, state_p, []) cfg = pda.to_empty_stack().to_cfg() - self.assertTrue(cfg.contains([])) - self.assertTrue(cfg.contains([terminal_a, terminal_b, terminal_c])) - self.assertFalse(cfg.contains([terminal_c, terminal_b, terminal_a])) + assert cfg.contains([]) + assert cfg.contains([terminal_a, terminal_b, terminal_c]) + assert not cfg.contains([terminal_c, terminal_b, terminal_a]) def test_intersection_regex(self): """ Tests the intersection with a regex """ @@ -303,35 +302,35 @@ def test_intersection_regex(self): new_pda = pda.intersection(dfa) pda_es = new_pda.to_empty_stack() cfg = pda_es.to_cfg() - self.assertEqual(new_pda.get_number_transitions(), 6) - self.assertEqual(len(new_pda.states), 5) - self.assertEqual(len(new_pda.final_states), 2) - self.assertEqual(len(new_pda.input_symbols), 2) - self.assertEqual(len(new_pda.stack_symbols), 2) + assert new_pda.get_number_transitions() == 6 + assert len(new_pda.states) == 5 + assert len(new_pda.final_states) == 2 + assert len(new_pda.input_symbols) == 2 + assert len(new_pda.stack_symbols) == 2 i_cfg = Terminal("i") e_cfg = Terminal("e") - self.assertTrue(cfg.contains([i_cfg, i_cfg, e_cfg, e_cfg, e_cfg])) + assert cfg.contains([i_cfg, i_cfg, e_cfg, e_cfg, e_cfg]) new_pda = pda.intersection( finite_automaton.DeterministicFiniteAutomaton()) - self.assertEqual(new_pda.get_number_transitions(), 0) + assert new_pda.get_number_transitions() == 0 new_pda = pda.intersection(Regex("")) pda_es = new_pda.to_empty_stack() cfg = pda_es.to_cfg() - self.assertFalse(cfg) + assert not cfg new_pda = pda & Regex("z|y").to_epsilon_nfa() pda_es = new_pda.to_empty_stack() cfg = pda_es.to_cfg() - self.assertFalse(cfg) + assert not cfg def test_pda_object_creator_epsilon(self): """ Test creation objects """ poc = PDAObjectCreator() - self.assertEqual(poc.to_stack_symbol(Epsilon()), Epsilon()) + assert poc.to_stack_symbol(Epsilon()) == Epsilon() def test_pda_paper(self): """ Code in the paper """ @@ -347,16 +346,16 @@ def test_pda_paper(self): pda.set_start_stack_symbol("Z0") pda.add_final_state("q2") pda_final_state = pda.to_final_state() - self.assertIsNotNone(pda_final_state) + assert pda_final_state is not None cfg = pda.to_empty_stack().to_cfg() - self.assertTrue(cfg.contains(["0", "1"])) + assert cfg.contains(["0", "1"]) pda_networkx = PDA.from_networkx(pda.to_networkx()) - self.assertEqual(pda.states, pda_networkx.states) - self.assertEqual(pda.start_state, pda_networkx.start_state) - self.assertEqual(pda.final_states, pda_networkx.final_states) - self.assertEqual(pda.input_symbols, pda_networkx.input_symbols) - self.assertEqual(pda.stack_symbols, pda_networkx.stack_symbols) + assert pda.states == pda_networkx.states + assert pda.start_state == pda_networkx.start_state + assert pda.final_states == pda_networkx.final_states + assert pda.input_symbols == pda_networkx.input_symbols + assert pda.stack_symbols == pda_networkx.stack_symbols cfg = pda_networkx.to_empty_stack().to_cfg() pda_networkx.write_as_dot("pda.dot") - self.assertTrue(cfg.contains(["0", "1"])) - self.assertTrue(path.exists("pda.dot")) + assert cfg.contains(["0", "1"]) + assert path.exists("pda.dot") diff --git a/pyformlang/regular_expression/tests/test_python_regex.py b/pyformlang/regular_expression/tests/test_python_regex.py index e08468c..6263059 100644 --- a/pyformlang/regular_expression/tests/test_python_regex.py +++ b/pyformlang/regular_expression/tests/test_python_regex.py @@ -1,128 +1,126 @@ -""" -Testing python regex parsing -""" +""" Testing of python regex parsing """ + import re -import unittest from pyformlang.regular_expression.python_regex import PythonRegex -class TestPythonRegex(unittest.TestCase): +class TestPythonRegex: """ Tests for python regex """ # pylint: disable=missing-function-docstring, too-many-public-methods def test_with_brackets(self): regex = PythonRegex("a[bc]") - self.assertTrue(regex.accepts(["a", "b"])) - self.assertTrue(regex.accepts(["a", "c"])) - self.assertFalse(regex.accepts(["a", "b", "c"])) - self.assertFalse(regex.accepts(["a", "a"])) + assert regex.accepts(["a", "b"]) + assert regex.accepts(["a", "c"]) + assert not regex.accepts(["a", "b", "c"]) + assert not regex.accepts(["a", "a"]) def test_range_in_brackets(self): regex = PythonRegex("a[a-z]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", "c"])) - self.assertTrue(regex.accepts(["a", "g"])) - self.assertTrue(regex.accepts(["a", "z"])) - self.assertFalse(regex.accepts(["a", "b", "c"])) - self.assertFalse(regex.accepts(["a", "A"])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", "c"]) + assert regex.accepts(["a", "g"]) + assert regex.accepts(["a", "z"]) + assert not regex.accepts(["a", "b", "c"]) + assert not regex.accepts(["a", "A"]) def test_range_in_brackets_trap(self): regex = PythonRegex("a[a-e-z]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", "c"])) - self.assertTrue(regex.accepts(["a", "z"])) - self.assertTrue(regex.accepts(["a", "-"])) - self.assertFalse(regex.accepts(["a", "y"])) - self.assertFalse(regex.accepts(["a", "f"])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", "c"]) + assert regex.accepts(["a", "z"]) + assert regex.accepts(["a", "-"]) + assert not regex.accepts(["a", "y"]) + assert not regex.accepts(["a", "f"]) def test_range_in_brackets_trap2(self): regex = PythonRegex("[a-e-g-z]*") - self.assertTrue(regex.accepts(["a", "-", "y"])) + assert regex.accepts(["a", "-", "y"]) def test_range_in_brackets_trap2_bis(self): regex = PythonRegex(re.compile("[a-e-g-z]*")) - self.assertTrue(regex.accepts(["a", "-", "y"])) + assert regex.accepts(["a", "-", "y"]) def test_parenthesis(self): regex = PythonRegex("((a)|(b))+") - self.assertTrue(regex.accepts(["a", "b"])) + assert regex.accepts(["a", "b"]) def test_plus(self): regex = PythonRegex("a+") - self.assertFalse(regex.accepts([])) - self.assertTrue(regex.accepts(["a"])) - self.assertTrue(regex.accepts(["a", "a"])) + assert not regex.accepts([]) + assert regex.accepts(["a"]) + assert regex.accepts(["a", "a"]) def test_dot(self): regex = PythonRegex("a.") - self.assertTrue(regex.accepts(["a", "b"])) - self.assertTrue(regex.accepts(["a", "?"])) - self.assertFalse(regex.accepts(["a", "\n"])) - self.assertFalse(regex.accepts(["a"])) - self.assertTrue(regex.accepts(["a", "|"])) - self.assertTrue(regex.accepts(["a", "("])) - self.assertTrue(regex.accepts(["a", ")"])) - self.assertTrue(regex.accepts(["a", "."])) - self.assertTrue(regex.accepts(["a", "*"])) - self.assertTrue(regex.accepts(["a", "+"])) - self.assertTrue(regex.accepts(["a", "$"])) + assert regex.accepts(["a", "b"]) + assert regex.accepts(["a", "?"]) + assert not regex.accepts(["a", "\n"]) + assert not regex.accepts(["a"]) + assert regex.accepts(["a", "|"]) + assert regex.accepts(["a", "("]) + assert regex.accepts(["a", ")"]) + assert regex.accepts(["a", "."]) + assert regex.accepts(["a", "*"]) + assert regex.accepts(["a", "+"]) + assert regex.accepts(["a", "$"]) self._test_compare(".", "\n") def test_dot_spaces(self): regex = PythonRegex("a.") - self.assertTrue(regex.accepts(["a", " "])) - self.assertTrue(regex.accepts(["a", "\t"])) - self.assertTrue(regex.accepts(["a", "\v"])) - self.assertTrue(regex.accepts(["a", "\r"])) + assert regex.accepts(["a", " "]) + assert regex.accepts(["a", "\t"]) + assert regex.accepts(["a", "\v"]) + assert regex.accepts(["a", "\r"]) def test_simple_optional(self): regex = PythonRegex("ab?") - self.assertTrue(regex.accepts(["a"])) - self.assertTrue(regex.accepts(["a", "b"])) - self.assertFalse(regex.accepts(["a", "a"])) + assert regex.accepts(["a"]) + assert regex.accepts(["a", "b"]) + assert not regex.accepts(["a", "a"]) def test_with_parenthesis_optional(self): regex = PythonRegex("a(bb|c)?") - self.assertTrue(regex.accepts(["a"])) - self.assertTrue(regex.accepts(["a", "b", "b"])) - self.assertTrue(regex.accepts(["a", "c"])) - self.assertFalse(regex.accepts(["a", "b"])) + assert regex.accepts(["a"]) + assert regex.accepts(["a", "b", "b"]) + assert regex.accepts(["a", "c"]) + assert not regex.accepts(["a", "b"]) def test_escape_question_mark(self): regex = PythonRegex(r"ab\?") - self.assertTrue(regex.accepts(["a", "b", "?"])) + assert regex.accepts(["a", "b", "?"]) def test_escape_kleene_star(self): regex = PythonRegex(r"ab\*") - self.assertTrue(regex.accepts(["a", "b", "*"])) + assert regex.accepts(["a", "b", "*"]) def test_escape_plus(self): regex = PythonRegex(r"ab\+") - self.assertTrue(regex.accepts(["a", "b", "+"])) - self.assertFalse(regex.accepts(["a", "b", "\\"])) + assert regex.accepts(["a", "b", "+"]) + assert not regex.accepts(["a", "b", "\\"]) def test_escape_opening_bracket(self): regex = PythonRegex(r"a\[") - self.assertTrue(regex.accepts(["a", "["])) + assert regex.accepts(["a", "["]) def test_escape_closing_bracket(self): regex = PythonRegex(r"a\]") - self.assertTrue(regex.accepts(["a", "]"])) + assert regex.accepts(["a", "]"]) def test_escape_backslash(self): regex = PythonRegex(r"a\\") - self.assertTrue(regex.accepts(["a", "\\"])) + assert regex.accepts(["a", "\\"]) def test_escape_backslash_plus(self): regex = PythonRegex(r"a\\+") - self.assertTrue(regex.accepts(["a", "\\", "\\"])) + assert regex.accepts(["a", "\\", "\\"]) def test_escape_backslash_opening_bracket(self): regex = PythonRegex(r"a\\[ab]") - self.assertTrue(regex.accepts(["a", "\\", "a"])) - self.assertTrue(regex.accepts(["a", "\\", "b"])) + assert regex.accepts(["a", "\\", "a"]) + assert regex.accepts(["a", "\\", "b"]) self._test_compare(r"a\\[ab]", "a\\a") def test_escape_backslash_closing_bracket(self): @@ -132,79 +130,76 @@ def test_escape_backslash_closing_bracket(self): def test_escape_backslash_question_mark(self): regex = PythonRegex(r"a\\?") - self.assertTrue(regex.accepts(["a"])) - self.assertTrue(regex.accepts(["a", "\\"])) - self.assertFalse(regex.accepts(["a", "\\", "?"])) - self.assertFalse(regex.accepts(["a", "\\?"])) + assert regex.accepts(["a"]) + assert regex.accepts(["a", "\\"]) + assert not regex.accepts(["a", "\\", "?"]) + assert not regex.accepts(["a", "\\?"]) def test_escape_dash_in_brackets(self): regex = PythonRegex(r"a[a\-]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", "-"])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", "-"]) def test_special_in_brackets_opening_parenthesis(self): regex = PythonRegex(r"a[a(]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", "("])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", "("]) def test_special_in_brackets_closing_parenthesis(self): regex = PythonRegex(r"a[a)]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", ")"])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", ")"]) def test_special_in_brackets_kleene_star(self): regex = PythonRegex(r"a[a*]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", "*"])) - self.assertFalse(regex.accepts(["a", "a", "a"])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", "*"]) + assert not regex.accepts(["a", "a", "a"]) def test_special_in_brackets_positive_closure(self): regex = PythonRegex(r"a[a+]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", "+"])) - self.assertFalse(regex.accepts(["a", "a", "a"])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", "+"]) + assert not regex.accepts(["a", "a", "a"]) def test_special_in_brackets_optional(self): regex = PythonRegex(r"a[a?]") - self.assertTrue(regex.accepts(["a", "a"])) - self.assertTrue(regex.accepts(["a", "?"])) - self.assertFalse(regex.accepts(["a"])) + assert regex.accepts(["a", "a"]) + assert regex.accepts(["a", "?"]) + assert not regex.accepts(["a"]) def test_shortcut_digits(self): regex = PythonRegex(r"a\d") - self.assertTrue(regex.accepts(["a", "0"])) - self.assertTrue(regex.accepts(["a", "1"])) + assert regex.accepts(["a", "0"]) + assert regex.accepts(["a", "1"]) def test_shortcut_digits_in_brackets(self): regex = PythonRegex(r"a[\da]") - self.assertTrue(regex.accepts(["a", "0"])) - self.assertTrue(regex.accepts(["a", "1"])) - self.assertTrue(regex.accepts(["a", "a"])) + assert regex.accepts(["a", "0"]) + assert regex.accepts(["a", "1"]) + assert regex.accepts(["a", "a"]) def test_shortcut_spaces(self): regex = PythonRegex(r"a\s") - self.assertTrue(regex.accepts(["a", " "])) - self.assertTrue(regex.accepts(["a", "\t"])) + assert regex.accepts(["a", " "]) + assert regex.accepts(["a", "\t"]) def test_space(self): regex = PythonRegex(" ") - self.assertTrue(regex.accepts([" "])) + assert regex.accepts([" "]) def test_shortcut_word(self): regex = PythonRegex(r"a\w") - self.assertTrue(regex.accepts(["a", "0"])) - self.assertTrue(regex.accepts(["a", "_"])) - self.assertTrue(regex.accepts(["a", "A"])) - self.assertTrue(regex.accepts(["a", "f"])) + assert regex.accepts(["a", "0"]) + assert regex.accepts(["a", "_"]) + assert regex.accepts(["a", "A"]) + assert regex.accepts(["a", "f"]) def _test_compare(self, regex, s_test): r_pyformlang = PythonRegex(regex) r_python = re.compile(regex) - self.assertEqual(r_python.fullmatch(s_test) is not None, r_pyformlang.accepts(s_test)) - - def test_backslash(self): - self._test_compare(".*", "]") - self._test_compare(".*", "\\") + assert (r_python.fullmatch(s_test) is not None) == \ + r_pyformlang.accepts(s_test) def test_escape_dot(self): self._test_compare("\\.", ".") @@ -246,7 +241,15 @@ def test_brackets_backslash_middle(self): self._test_compare(r"[a\b]", "\\b") self._test_compare(r"[a\b]", "\\") + def test_octal(self): + self._test_compare(r"\x10", "\x10") + self._test_compare(r"\110", "\110") + self._test_compare(r"\\\\x10", "\x10") + self._test_compare(r"\\\\x10", "\\x10") + def test_backslash(self): + # self._test_compare(r".*", "]") + # self._test_compare(r".*", "\\") self._test_compare(r"\t", "t") self._test_compare(r"\t", "\t") self._test_compare(r"\t", "\\t") @@ -254,12 +257,6 @@ def test_backslash(self): self._test_compare(r"(a | \t)", "\t") self._test_compare(r"(a | \t)", "\\t") - def test_octal(self): - self._test_compare(r"\x10", "\x10") - self._test_compare(r"\110", "\110") - self._test_compare(r"\\\\x10", "\x10") - self._test_compare(r"\\\\x10", "\\x10") - def test_backspace(self): self._test_compare(r"a[b\b]", "ab") self._test_compare(r"a[b\b]", "a\b") @@ -315,7 +312,8 @@ def test_error_backslash(self): self._test_compare(r"\"([d\"\\\\]|\\\\.)*\"", '"d\\"') self._test_compare(r"[a\\\\]", "a") self._test_compare(r"\"([^\"\\\\]|\\\\.)*\"", '"ddd"') - self._test_compare(r"([a-z_]+:\s([^,\n]+,)*[^,\n]*)", "abho-ja: njzk,szi,szkok") + self._test_compare(r"([a-z_]+:\s([^,\n]+,)*[^,\n]*)", + "abho-ja: njzk,szi,szkok") def test_negation_brackets(self): self._test_compare(r"[^abc]*", "") diff --git a/pyformlang/regular_expression/tests/test_regex.py b/pyformlang/regular_expression/tests/test_regex.py index 1e0cdeb..89d0e6a 100644 --- a/pyformlang/regular_expression/tests/test_regex.py +++ b/pyformlang/regular_expression/tests/test_regex.py @@ -1,14 +1,12 @@ -""" -Tests for regular expressions -""" +""" Tests for regular expressions """ -import unittest +import pytest from pyformlang.regular_expression import Regex, MisformedRegexError from pyformlang import finite_automaton -class TestRegex(unittest.TestCase): +class TestRegex: """ Tests for regex """ # pylint: disable=missing-function-docstring,too-many-public-methods @@ -16,54 +14,54 @@ class TestRegex(unittest.TestCase): def test_creation(self): """ Try to create regex """ regex = Regex("a|b") - self.assertEqual(regex.get_number_symbols(), 2) - self.assertEqual(regex.get_number_operators(), 1) + assert regex.get_number_symbols() == 2 + assert regex.get_number_operators() == 1 regex = Regex("a b") - self.assertEqual(regex.get_number_symbols(), 2) - self.assertEqual(regex.get_number_operators(), 1) + assert regex.get_number_symbols() == 2 + assert regex.get_number_operators() == 1 regex = Regex("a b c") - self.assertEqual(regex.get_number_symbols(), 3) - self.assertEqual(regex.get_number_operators(), 2) + assert regex.get_number_symbols() == 3 + assert regex.get_number_operators() == 2 regex = Regex("(a b)|c") - self.assertEqual(regex.get_number_symbols(), 3) - self.assertEqual(regex.get_number_operators(), 2) + assert regex.get_number_symbols() == 3 + assert regex.get_number_operators() == 2 regex = Regex("") - self.assertEqual(regex.get_number_symbols(), 1) - self.assertEqual(regex.get_number_operators(), 0) + assert regex.get_number_symbols() == 1 + assert regex.get_number_operators() == 0 regex = Regex("a*") - self.assertEqual(regex.get_number_symbols(), 1) - self.assertEqual(regex.get_number_operators(), 1) + assert regex.get_number_symbols() == 1 + assert regex.get_number_operators() == 1 regex = Regex("a**") - self.assertEqual(regex.get_number_symbols(), 1) - self.assertEqual(regex.get_number_operators(), 2) + assert regex.get_number_symbols() == 1 + assert regex.get_number_operators() == 2 regex = Regex("a*b|c") - self.assertEqual(regex.get_number_symbols(), 3) - self.assertEqual(regex.get_number_operators(), 3) + assert regex.get_number_symbols() == 3 + assert regex.get_number_operators() == 3 regex = Regex("a*(b|c)") - self.assertEqual(regex.get_number_symbols(), 3) - self.assertEqual(regex.get_number_operators(), 3) + assert regex.get_number_symbols() == 3 + assert regex.get_number_operators() == 3 regex = Regex("a*.(b|c)") - self.assertEqual(regex.get_number_symbols(), 3) - self.assertEqual(regex.get_number_operators(), 3) + assert regex.get_number_symbols() == 3 + assert regex.get_number_operators() == 3 regex = Regex("a*.(b|c)epsilon") - self.assertEqual(regex.get_number_symbols(), 4) - self.assertEqual(regex.get_number_operators(), 4) + assert regex.get_number_symbols() == 4 + assert regex.get_number_operators() == 4 regex = Regex("$") - self.assertEqual(regex.get_number_symbols(), 1) + assert regex.get_number_symbols() == 1 regex = Regex("a|") - self.assertEqual(regex.get_number_symbols(), 2) - self.assertEqual(regex.get_number_operators(), 1) - with self.assertRaises(MisformedRegexError): + assert regex.get_number_symbols() == 2 + assert regex.get_number_operators() == 1 + with pytest.raises(MisformedRegexError): Regex(")a b()") - with self.assertRaises(MisformedRegexError): + with pytest.raises(MisformedRegexError): Regex("(a b()") - with self.assertRaises(MisformedRegexError): + with pytest.raises(MisformedRegexError): Regex("(a b))") - with self.assertRaises(MisformedRegexError): + with pytest.raises(MisformedRegexError): Regex("| a b") regex = Regex("(a-|a a b)") - self.assertEqual(regex.get_number_symbols(), 4) - self.assertEqual(regex.get_number_operators(), 3) + assert regex.get_number_symbols() == 4 + assert regex.get_number_operators() == 3 def test_to_enfa0(self): """ Tests the transformation to a regex """ @@ -73,39 +71,39 @@ def test_to_enfa0(self): epsilon = finite_automaton.Epsilon() regex = Regex("a|b") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a])) - self.assertTrue(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_c])) - self.assertFalse(enfa.accepts([epsilon])) - self.assertFalse(enfa.accepts([symb_a, symb_b])) + assert enfa.accepts([symb_a]) + assert enfa.accepts([symb_b]) + assert not enfa.accepts([symb_c]) + assert not enfa.accepts([epsilon]) + assert not enfa.accepts([symb_a, symb_b]) regex = Regex("a b") enfa = regex.to_epsilon_nfa() - self.assertFalse(enfa.accepts([symb_a])) - self.assertFalse(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_a, symb_b])) + assert not enfa.accepts([symb_a]) + assert not enfa.accepts([symb_b]) + assert enfa.accepts([symb_a, symb_b]) regex = Regex("a b c") enfa = regex.to_epsilon_nfa() - self.assertFalse(enfa.accepts([symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_a, symb_b, symb_c])) - self.assertFalse(enfa.accepts([symb_a, symb_b, symb_a])) + assert not enfa.accepts([symb_a, symb_b]) + assert enfa.accepts([symb_a, symb_b, symb_c]) + assert not enfa.accepts([symb_a, symb_b, symb_a]) regex = Regex("(a b)|c") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a, symb_b])) - self.assertFalse(enfa.accepts([symb_a, symb_c])) - self.assertFalse(enfa.accepts([symb_b, symb_c])) - self.assertTrue(enfa.accepts([symb_c])) + assert enfa.accepts([symb_a, symb_b]) + assert not enfa.accepts([symb_a, symb_c]) + assert not enfa.accepts([symb_b, symb_c]) + assert enfa.accepts([symb_c]) regex = Regex("") enfa = regex.to_epsilon_nfa() - self.assertFalse(enfa.accepts([symb_a])) - self.assertFalse(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_c])) - self.assertFalse(enfa.accepts([])) + assert not enfa.accepts([symb_a]) + assert not enfa.accepts([symb_b]) + assert not enfa.accepts([symb_c]) + assert not enfa.accepts([]) regex = Regex("a*") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a])) - self.assertTrue(enfa.accepts([])) - self.assertTrue(enfa.accepts([symb_a, symb_a])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_a])) + assert enfa.accepts([symb_a]) + assert enfa.accepts([]) + assert enfa.accepts([symb_a, symb_a]) + assert enfa.accepts([symb_a, symb_a, symb_a]) def test_to_enfa1(self): """ Tests the transformation to a regex """ @@ -114,52 +112,52 @@ def test_to_enfa1(self): symb_c = finite_automaton.Symbol("c") regex = Regex("a**") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a])) - self.assertTrue(enfa.accepts([])) - self.assertTrue(enfa.accepts([symb_a, symb_a])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_a])) + assert enfa.accepts([symb_a]) + assert enfa.accepts([]) + assert enfa.accepts([symb_a, symb_a]) + assert enfa.accepts([symb_a, symb_a, symb_a]) regex = Regex("a*b|c") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_c])) - self.assertFalse(enfa.accepts([symb_a, symb_a, symb_c])) + assert enfa.accepts([symb_a, symb_a, symb_b]) + assert enfa.accepts([symb_b]) + assert enfa.accepts([symb_c]) + assert not enfa.accepts([symb_a, symb_a, symb_c]) regex = Regex("a*(b|c)") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_c])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_c])) + assert enfa.accepts([symb_a, symb_a, symb_b]) + assert enfa.accepts([symb_b]) + assert enfa.accepts([symb_c]) + assert enfa.accepts([symb_a, symb_a, symb_c]) regex = Regex("a*.(b|c)") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_c])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_c])) + assert enfa.accepts([symb_a, symb_a, symb_b]) + assert enfa.accepts([symb_b]) + assert enfa.accepts([symb_c]) + assert enfa.accepts([symb_a, symb_a, symb_c]) regex = Regex("a*.(b|c)epsilon") enfa = regex.to_epsilon_nfa() - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_b])) - self.assertTrue(enfa.accepts([symb_b])) - self.assertTrue(enfa.accepts([symb_c])) - self.assertTrue(enfa.accepts([symb_a, symb_a, symb_c])) + assert enfa.accepts([symb_a, symb_a, symb_b]) + assert enfa.accepts([symb_b]) + assert enfa.accepts([symb_c]) + assert enfa.accepts([symb_a, symb_a, symb_c]) regex = Regex("$") enfa = regex.to_epsilon_nfa() - self.assertFalse(enfa.accepts([symb_a])) - self.assertFalse(enfa.accepts([symb_b])) - self.assertFalse(enfa.accepts([symb_c])) - self.assertTrue(enfa.accepts([])) + assert not enfa.accepts([symb_a]) + assert not enfa.accepts([symb_b]) + assert not enfa.accepts([symb_c]) + assert enfa.accepts([]) def test_print(self): """ Test printing functions """ regex = Regex("a*.(b|c)epsilon") tree_str = regex.get_tree_str() - self.assertTrue("Concatenation" in tree_str) - self.assertTrue("Union" in tree_str) - self.assertTrue("Kleene Star" in tree_str) - self.assertTrue("Symbol" in tree_str) + assert "Concatenation" in tree_str + assert "Union" in tree_str + assert "Kleene Star" in tree_str + assert "Symbol" in tree_str regex = Regex("") tree_str = regex.get_tree_str() - self.assertTrue("Empty" in tree_str) + assert "Empty" in tree_str def test_get_repr(self): regex0 = Regex("a*.(b|c)epsilon") @@ -167,126 +165,126 @@ def test_get_repr(self): regex1 = Regex(regex_str) dfa0 = regex0.to_epsilon_nfa().to_deterministic().minimize() dfa1 = regex1.to_epsilon_nfa().to_deterministic().minimize() - self.assertEqual(dfa0, dfa1) + assert dfa0 == dfa1 def test_accepts(self): regex = Regex("a|b|c") - self.assertTrue(regex.accepts(["a"])) - self.assertFalse(regex.accepts(["a", "b"])) + assert regex.accepts(["a"]) + assert not regex.accepts(["a", "b"]) def test_from_python_simple(self): regex = Regex.from_python_regex("abc") - self.assertTrue(regex.accepts(["a", "b", "c"])) - self.assertFalse(regex.accepts(["a", "b", "b"])) - self.assertFalse(regex.accepts(["a", "b"])) + assert regex.accepts(["a", "b", "c"]) + assert not regex.accepts(["a", "b", "b"]) + assert not regex.accepts(["a", "b"]) def test_from_python_brackets(self): regex = Regex.from_python_regex("a[bc]") - self.assertTrue(regex.accepts(["a", "b"])) - self.assertTrue(regex.accepts(["a", "c"])) - self.assertFalse(regex.accepts(["a", "b", "c"])) - self.assertFalse(regex.accepts(["a", "a"])) + assert regex.accepts(["a", "b"]) + assert regex.accepts(["a", "c"]) + assert not regex.accepts(["a", "b", "c"]) + assert not regex.accepts(["a", "a"]) def test_space(self): regex = Regex("\\ ") - self.assertTrue(regex.accepts([" "])) + assert regex.accepts([" "]) def test_parenthesis_gorilla(self): regex = Regex("george touches (a|an) (sky|gorilla) !") - self.assertTrue(regex.accepts(["george", "touches", "a", "sky", "!"])) + assert regex.accepts(["george", "touches", "a", "sky", "!"]) def test_regex_or(self): regex = Regex("a|b") - self.assertTrue(regex.accepts(["a"])) + assert regex.accepts(["a"]) def test_regex_or_concat(self): regex = Regex("c (a|b)") - self.assertTrue(regex.accepts(["c", "b"])) + assert regex.accepts(["c", "b"]) def test_regex_two_or_concat(self): regex = Regex("c (a|b) (d|e)") - self.assertTrue(regex.accepts(["c", "b", "e"])) + assert regex.accepts(["c", "b", "e"]) def test_regex_two_or_concat_parenthesis(self): regex = Regex("c.(a|b)(d|e)") - self.assertTrue(regex.accepts(["c", "b", "e"])) + assert regex.accepts(["c", "b", "e"]) def test_regex_two_or_concat_parenthesis2(self): regex = Regex("c (a|(b d)|e)") - self.assertTrue(regex.accepts(["c", "a"])) - self.assertTrue(regex.accepts(["c", "b", "d"])) - self.assertTrue(regex.accepts(["c", "e"])) + assert regex.accepts(["c", "a"]) + assert regex.accepts(["c", "b", "d"]) + assert regex.accepts(["c", "e"]) def test_regex_two_or_concat_parenthesis2_concat(self): regex = Regex("c (a|(b d)|e) !") - self.assertTrue(regex.accepts(["c", "a", "!"])) - self.assertTrue(regex.accepts(["c", "b", "d", "!"])) - self.assertTrue(regex.accepts(["c", "e", "!"])) + assert regex.accepts(["c", "a", "!"]) + assert regex.accepts(["c", "b", "d", "!"]) + assert regex.accepts(["c", "e", "!"]) def test_regex_or_two_concat(self): regex = Regex("c d (a|b)") - self.assertTrue(regex.accepts(["c", "d", "b"])) + assert regex.accepts(["c", "d", "b"]) def test_after_union(self): regex = Regex("(a|b) !") - self.assertTrue(regex.accepts(["a", "!"])) + assert regex.accepts(["a", "!"]) def test_star_union(self): regex = Regex("a*(b|c)") - self.assertTrue(regex.accepts(["a", "a", "c"])) + assert regex.accepts(["a", "a", "c"]) def test_misformed(self): - with self.assertRaises(MisformedRegexError): + with pytest.raises(MisformedRegexError): Regex(")") def test_misformed2(self): - with self.assertRaises(MisformedRegexError): + with pytest.raises(MisformedRegexError): Regex("(") def test_escaped_parenthesis(self): regex = Regex("\\(") - self.assertTrue(regex.accepts(["("])) + assert regex.accepts(["("]) def test_escaped_mid_bar(self): regex = Regex('a(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q' '|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|' 'S|T|U|V|W|X|Y|Z|!|"|#|\\$|%|&|\'|\\(|\\)|\\*|\\+|,|-|' '\\.|/|:|;|<|=|>|?|@|[|\\|]|^|_|`|{|\\||}|~|\\ | |)') - self.assertTrue(regex.accepts(["a", "|"])) + assert regex.accepts(["a", "|"]) def test_to_cfg(self): regex = Regex("a") cfg = regex.to_cfg() - self.assertTrue(cfg.contains(["a"])) + assert cfg.contains(["a"]) regex = Regex("a|b") cfg = regex.to_cfg() - self.assertTrue(cfg.contains(["b"])) + assert cfg.contains(["b"]) regex = Regex("a b") cfg = regex.to_cfg() - self.assertTrue(cfg.contains(["a", "b"])) + assert cfg.contains(["a", "b"]) regex = Regex("a*") cfg = regex.to_cfg() - self.assertTrue(cfg.contains([])) - self.assertTrue(cfg.contains(["a"])) - self.assertTrue(cfg.contains(["a", "a"])) + assert cfg.contains([]) + assert cfg.contains(["a"]) + assert cfg.contains(["a", "a"]) regex = Regex("epsilon") cfg = regex.to_cfg() - self.assertTrue(cfg.contains([])) + assert cfg.contains([]) regex = Regex("") cfg = regex.to_cfg() - self.assertTrue(cfg.is_empty()) + assert cfg.is_empty() regex = Regex("(a|b)* c") cfg = regex.to_cfg() - self.assertTrue(cfg.contains(["c"])) - self.assertTrue(cfg.contains(["a", "c"])) - self.assertTrue(cfg.contains(["a", "b", "c"])) + assert cfg.contains(["c"]) + assert cfg.contains(["a", "c"]) + assert cfg.contains(["a", "b", "c"]) def test_priority(self): - self.assertTrue(Regex('b a* | a').accepts('a')) - self.assertTrue(Regex('b a* | a').accepts('b')) - self.assertTrue(Regex('(b a*) | a').accepts('a')) + assert Regex('b a* | a').accepts('a') + assert Regex('b a* | a').accepts('b') + assert Regex('(b a*) | a').accepts('a') def test_backslash_b(self): - self.assertTrue(Regex("( a | \b )").accepts("\b")) - self.assertTrue(Regex("( a | \b )").accepts("a")) - self.assertFalse(Regex("( a | \b )").accepts("b")) + assert Regex("( a | \b )").accepts("\b") + assert Regex("( a | \b )").accepts("a") + assert not Regex("( a | \b )").accepts("b") diff --git a/pyformlang/rsa/tests/test_rsa.py b/pyformlang/rsa/tests/test_rsa.py index 8ed4721..0b6ff52 100644 --- a/pyformlang/rsa/tests/test_rsa.py +++ b/pyformlang/rsa/tests/test_rsa.py @@ -1,6 +1,4 @@ -""" Tests for RSA """ - -import unittest +""" Tests for the RSA """ from pyformlang.finite_automaton.symbol import Symbol from pyformlang.regular_expression import Regex @@ -9,8 +7,9 @@ from pyformlang.rsa.box import Box -class TestRSA(unittest.TestCase): - """ Test class for RSA """ +class TestRSA: + """ Tests for the RSA """ + def test_creation(self): """ Test the creation of an RSA """ # S -> a S b | a b @@ -20,14 +19,14 @@ def test_creation(self): box = Box(dfa, "S") rsa_1 = RecursiveAutomaton(box, set()) - self.assertEqual(rsa_1.get_number_boxes(), 1) - self.assertEqual(box, rsa_1.get_box_by_nonterminal("S")) - self.assertEqual(rsa_1.nonterminals, {Symbol("S")}) - self.assertEqual(rsa_1.start_nonterminal, Symbol("S")) + assert rsa_1.get_number_boxes() == 1 + assert box == rsa_1.get_box_by_nonterminal("S") + assert rsa_1.nonterminals == {Symbol("S")} + assert rsa_1.start_nonterminal == Symbol("S") rsa_2 = RecursiveAutomaton.from_regex(regex, "S") - self.assertEqual(rsa_2, rsa_1) + assert rsa_2 == rsa_1 def test_from_regex(self): """ Test creation of an RSA from a regex""" @@ -39,7 +38,7 @@ def test_from_regex(self): box = Box(dfa, "S") rsa_1 = RecursiveAutomaton(box, set()) - self.assertEqual(rsa_2, rsa_1) + assert rsa_2 == rsa_1 def test_is_equals_to(self): """ Test the equals of two RSAs""" @@ -49,7 +48,7 @@ def test_is_equals_to(self): # S -> a+ b+ rsa_2 = RecursiveAutomaton.from_regex(Regex("a a* b b*"), "S") - self.assertNotEqual(rsa_1, rsa_2) + assert rsa_1 != rsa_2 def test_from_ebnf(self): """ Test reading RSA from ebnf""" @@ -58,18 +57,18 @@ def test_from_ebnf(self): rsa2_g1 = RecursiveAutomaton.from_regex( Regex("a S b | a b"), "S") - self.assertEqual(rsa1_g1, rsa2_g1) + assert rsa1_g1 == rsa2_g1 # g2: S -> a V b # V -> c S d | c d rsa1_g2 = RecursiveAutomaton.from_ebnf(""" S -> a V b V -> c S d | c d""") - self.assertEqual(rsa1_g2.get_number_boxes(), 2) - self.assertEqual(rsa1_g2.nonterminals, {Symbol("S"), Symbol("V")}) + assert rsa1_g2.get_number_boxes() == 2 + assert rsa1_g2.nonterminals == {Symbol("S"), Symbol("V")} dfa_s = Regex("a V b").to_epsilon_nfa().minimize() - self.assertEqual(rsa1_g2.get_box_by_nonterminal("S"), Box(dfa_s, "S")) + assert rsa1_g2.get_box_by_nonterminal("S") == Box(dfa_s, "S") dfa_v = Regex("c S d | c d").to_epsilon_nfa().minimize() - self.assertEqual(rsa1_g2.get_box_by_nonterminal("V"), Box(dfa_v, "V")) + assert rsa1_g2.get_box_by_nonterminal("V") == Box(dfa_v, "V")