Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Towards full feature parity
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiasdiez committed Dec 21, 2020
1 parent 7b8be0d commit 1488582
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 109 deletions.
18 changes: 15 additions & 3 deletions src/conftest.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
from sage.misc.functional import category
import sage.all # TODO: Remove once categories can be used without previous sage.all import
from sage.categories.sets_cat import Sets
from sage.categories.enumerated_sets import EnumeratedSets
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
from _pytest.python import Metafunc, PyCollector
from sage.categories.test_sets_cat import SetsTests
from sage.categories.sets_cat_test import SetsTests
from sage.categories.enumerated_sets_test import EnumeratedSetsTests
from sage.categories.finite_enumerated_sets_test import FiniteEnumeratedSetsTests
from sage.categories.infinite_enumerated_sets_test import InfiniteEnumeratedSetsTests
import pytest
import inspect

# Dictionary relating the category to its test class
categories_with_tests = {
Sets: SetsTests
Sets: SetsTests,
EnumeratedSets: EnumeratedSetsTests,
FiniteEnumeratedSets: FiniteEnumeratedSetsTests,
InfiniteEnumeratedSets: InfiniteEnumeratedSetsTests
}

def pytest_pycollect_makeitem(collector: PyCollector, name: str, obj: type):
Expand Down Expand Up @@ -47,3 +55,7 @@ def pytest_generate_tests(metafunc: Metafunc):
def add_imports(doctest_namespace):
# TODO: Remove this workaround as soon as sage objects can be used without previous sage.all import
import sage.all

@pytest.fixture
def max_runs():
return 20
41 changes: 41 additions & 0 deletions src/sage/categories/enumerated_sets_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import pytest

class EnumeratedSetsTests:
"""
Generic tests for the category of enumerated sets.
"""

def test_enumerated_set_contains(self, category_instance, max_runs):
"""
Test that the methods :meth:`.__contains__` and :meth:`.__iter__` are consistent.
"""
i = 0
for w in category_instance:
assert w in category_instance

i += 1
if i > max_runs:
return

def test_enumerated_set_iter_list(self, category_instance, max_runs):
"""
Test that the methods :meth:`.list` and :meth:`.__iter__` are consistent.
.. NOTE::
This test does nothing if the cardinality of the set
is larger than the max_runs argument.
"""
if category_instance.list != category_instance._list_default:
# TODO: if self._cardinality is self._cardinality_from_iterator
# we could make sure to stop the counting at
# self.max_test_enumerated_set_loop
if category_instance.cardinality() > max_runs:
print("Enumerated set too big; skipping test; increase max_runs")
return
ls = category_instance.list()
i = 0
for obj in category_instance:
assert obj == ls[i]
i += 1
assert i == len(ls)
30 changes: 0 additions & 30 deletions src/sage/categories/examples/finite_semigroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,35 +73,6 @@ class LeftRegularBand(UniqueRepresentation, Parent):
Graphics object consisting of 60 graphics primitives
sage: S.j_transversal_of_idempotents() # random (arbitrary choice)
['acb', 'ac', 'ab', 'bc', 'a', 'c', 'b']
We conclude by running systematic tests on this semigroup::
sage: TestSuite(S).run(verbose = True)
running ._test_an_element() . . . pass
running ._test_associativity() . . . pass
running ._test_cardinality() . . . pass
running ._test_category() . . . pass
running ._test_construction() . . . pass
running ._test_elements() . . .
Running the test suite of self.an_element()
running ._test_category() . . . pass
running ._test_eq() . . . pass
running ._test_new() . . . pass
running ._test_not_implemented_methods() . . . pass
running ._test_pickling() . . . pass
pass
running ._test_elements_eq_reflexive() . . . pass
running ._test_elements_eq_symmetric() . . . pass
running ._test_elements_eq_transitive() . . . pass
running ._test_elements_neq() . . . pass
running ._test_enumerated_set_contains() . . . pass
running ._test_enumerated_set_iter_cardinality() . . . pass
running ._test_enumerated_set_iter_list() . . . pass
running ._test_eq() . . . pass
running ._test_new() . . . pass
running ._test_not_implemented_methods() . . . pass
running ._test_pickling() . . . pass
running ._test_some_elements() . . . pass
"""

def __init__(self, alphabet=('a','b','c','d')):
Expand All @@ -114,7 +85,6 @@ def __init__(self, alphabet=('a','b','c','d')):
An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')
sage: S = FiniteSemigroups().example(alphabet=('x','y')); S
An example of a finite semigroup: the left regular band generated by ('x', 'y')
sage: TestSuite(S).run()
"""
self.alphabet = alphabet
Parent.__init__(self, category = Semigroups().Finite().FinitelyGenerated())
Expand Down
20 changes: 20 additions & 0 deletions src/sage/categories/finite_enumerated_sets_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class FiniteEnumeratedSetsTests:
"""
Generic tests for the category of finite enumerated sets.
"""

def test_enumerated_set_iter_cardinality(self, category_instance, max_runs):
"""
Checks that the methods :meth:`.cardinality` and
:meth:`.__iter__` are consistent. Also checks that
:meth:`.cardinality` returns an ``Integer``.
For efficiency reasons, those tests are not run if
:meth:`.cardinality` is
:meth:`._cardinality_from_iterator`, or if ``category_instance`` is too
big.
"""
if category_instance.cardinality != category_instance._cardinality_from_iterator:
card = category_instance.cardinality()
if card <= max_runs:
assert card == category_instance._cardinality_from_iterator()
46 changes: 45 additions & 1 deletion src/sage/categories/finite_semigroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,51 @@ class FiniteSemigroups(CategoryWithAxiom):
TESTS::
sage: TestSuite(C).run()
sage: import pytest
sage: pytest.main(["-r", "test_finite_semigroups.py"])
======================================================================================================= test session starts =======================================================================================================
platform ...
rootdir: ...
collected 36 items
src/sage/categories/finite_semigroups_test.py ....................................
===================================================================================================== short test summary info =====================================================================================================
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_contains[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_contains[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_contains[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_iter_list[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_iter_list[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_iter_list[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_iter_cardinality[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_iter_cardinality[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_enumerated_set_iter_cardinality[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_associativity[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_associativity[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_associativity[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_an_element[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_an_element[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_an_element[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_an_element_idempotent[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_an_element_idempotent[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_an_element_idempotent[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_cardinality_return_type[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_cardinality_return_type[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_cardinality_return_type[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_construction[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_construction[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_construction[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_element_eq_reflexive[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_element_eq_reflexive[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_element_eq_reflexive[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_eq_symmetric[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_eq_symmetric[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_eq_symmetric[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_eq_transitive[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_eq_transitive[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_eq_transitive[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_neq[An example of a finite semigroup: the left regular band generated by ('a', 'b')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_neq[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c')]
PASSED src/sage/categories/finite_semigroups_test.py::TestFiniteSemigroup::test_elements_neq[An example of a finite semigroup: the left regular band generated by ('a', 'b', 'c', 'd')]
"""

class ParentMethods:
Expand Down
21 changes: 21 additions & 0 deletions src/sage/categories/finite_semigroups_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class TestFiniteSemigroup():
"""
Tests for finite semigroups.
"""

@staticmethod
def category_instances():
from sage.categories.examples.finite_semigroups import LeftRegularBand
return [
LeftRegularBand(alphabet = ('a','b')),
LeftRegularBand(alphabet = ('a','b','c')),
LeftRegularBand(alphabet = ('a','b','c', 'd'))
]

def test_associativity(self, set_elements, max_runs):
"""
Test associativity of multiplication of elements.
"""
from sage.misc.misc import some_tuples
for x, y, z in some_tuples(set_elements, 3, max_runs):
assert (x * y) * z == x * (y * z)
21 changes: 21 additions & 0 deletions src/sage/categories/infinite_enumerated_sets_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pytest
from sage.rings.infinity import infinity

class InfiniteEnumeratedSetsTests:
"""
Generic tests for the category of infinite enumerated sets.
"""
def test_enumerated_set_iter_cardinality(self, category_instance):
"""
Test that the methods :meth:`.cardinality` and
:meth:`.__iter__` are consistent.
For infinite enumerated sets:
* :meth:`.cardinality` is supposed to return `infinity`
* :meth:`.list` is supposed to raise a ``NotImplementedError``.
"""
assert category_instance.cardinality() == infinity
with pytest.raises(NotImplementedError):
category_instance.list
31 changes: 0 additions & 31 deletions src/sage/categories/semigroups.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,37 +89,6 @@ def example(self, choice="leftzero", **kwds):

class ParentMethods:

def _test_associativity(self, **options):
r"""
Test associativity for (not necessarily all) elements of this
semigroup.
INPUT:
- ``options`` -- any keyword arguments accepted by :meth:`_tester`
EXAMPLES:
By default, this method tests only the elements returned by
``self.some_elements()``::
sage: L = Semigroups().example(choice='leftzero')
sage: L._test_associativity()
However, the elements tested can be customized with the
``elements`` keyword argument::
sage: L._test_associativity(elements = (L(1), L(2), L(3)))
See the documentation for :class:`TestSuite` for more information.
"""
tester = self._tester(**options)
S = tester.some_elements()
from sage.misc.misc import some_tuples
for x, y, z in some_tuples(S, 3, tester._max_runs):
tester.assertEqual((x * y) * z, x * (y * z))

@abstract_method(optional=True)
def semigroup_generators(self):
"""
Expand Down
Loading

0 comments on commit 1488582

Please sign in to comment.