Skip to content

Commit

Permalink
Add tests for 'Fraction' struct
Browse files Browse the repository at this point in the history
  • Loading branch information
lycantropos committed Jul 10, 2023
1 parent a9152bc commit 18078f6
Show file tree
Hide file tree
Showing 17 changed files with 572 additions and 3 deletions.
Empty file.
17 changes: 17 additions & 0 deletions tests/fraction_tests/strategies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from hypothesis import strategies as _st

from tests.binding import (BigInteger as _BigInteger,
Fractions as _Fractions)

zero_integers = _st.just(_BigInteger(0))
big_integers = numerators = _st.integers().map(_BigInteger)
negative_integers = _st.integers(max_value=-1).map(_BigInteger)
positive_integers = _st.integers(min_value=1).map(_BigInteger)
denominators = non_zero_integers = negative_integers | positive_integers
zero_fractions = _st.builds(_Fractions.Fraction)
fractions = _st.builds(_Fractions.Fraction, numerators, denominators)
non_zero_fractions = _st.builds(_Fractions.Fraction, non_zero_integers,
denominators)
rationals = big_integers | fractions
non_zero_rationals = non_zero_integers | non_zero_fractions
zero_rationals = zero_integers | zero_fractions
72 changes: 72 additions & 0 deletions tests/fraction_tests/test_Abs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import typing as t

from hypothesis import given

from tests.binding import (BigInteger,
Fractions)
from tests.utils import (equivalence,
is_fraction_valid)
from . import strategies


@given(strategies.fractions)
def test_basic(fraction: Fractions.Fraction) -> None:
result = Fractions.Fraction.Abs(fraction)

assert isinstance(result, Fractions.Fraction)
assert is_fraction_valid(result)


@given(strategies.fractions)
def test_idempotence(fraction: Fractions.Fraction) -> None:
result = Fractions.Fraction.Abs(fraction)

assert result == Fractions.Fraction.Abs(result)


@given(strategies.fractions)
def test_positive_definiteness(fraction: Fractions.Fraction) -> None:
result = Fractions.Fraction.Abs(fraction)

assert equivalence(result.IsZero, fraction.IsZero)


@given(strategies.fractions)
def test_evenness(fraction: Fractions.Fraction) -> None:
result = Fractions.Fraction.Abs(fraction)

assert result == Fractions.Fraction.Abs(-fraction)


@given(strategies.fractions, strategies.fractions)
def test_multiplicativity(
first: Fractions.Fraction,
second: t.Union[BigInteger, Fractions.Fraction]
) -> None:
result = Fractions.Fraction.Abs(first * second)

assert (result
== Fractions.Fraction.Abs(first) * Fractions.Fraction.Abs(second))


@given(strategies.fractions, strategies.fractions)
def test_triangle_inequality(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
result = Fractions.Fraction.Abs(first + second)

assert (result
<= Fractions.Fraction.Abs(first) + Fractions.Fraction.Abs(second))


@given(strategies.fractions, strategies.fractions)
def test_op_Multiply_operand(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert (Fractions.Fraction.Abs(first * second)
== Fractions.Fraction.Abs(first) * Fractions.Fraction.Abs(second))


@given(strategies.fractions, strategies.non_zero_fractions)
def test_op_Division_operand(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert (Fractions.Fraction.Abs(first / second)
== Fractions.Fraction.Abs(first) / Fractions.Fraction.Abs(second))
35 changes: 35 additions & 0 deletions tests/fraction_tests/test_GreaterThan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from hypothesis import given

from tests.binding import Fractions
from tests.utils import (equivalence,
implication)
from . import strategies


@given(strategies.fractions)
def test_irreflexivity(fraction: Fractions.Fraction) -> None:
assert not fraction > fraction


@given(strategies.fractions, strategies.fractions)
def test_asymmetry(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert implication(first > second, not second > first)


@given(strategies.fractions, strategies.fractions, strategies.fractions)
def test_transitivity(first: Fractions.Fraction,
second: Fractions.Fraction,
third: Fractions.Fraction) -> None:
assert implication(first > second > third,
first > third)


@given(strategies.fractions, strategies.fractions)
def test_equivalents(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
result = first > second

assert equivalence(result, second < first)
assert equivalence(result, second <= first != second)
assert equivalence(result, first >= second != first)
34 changes: 34 additions & 0 deletions tests/fraction_tests/test_GreaterThanOrEqual.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from hypothesis import given

from tests.binding import Fractions
from tests.utils import (equivalence,
implication)
from . import strategies


@given(strategies.fractions)
def test_reflexivity(fraction: Fractions.Fraction) -> None:
assert fraction >= fraction


@given(strategies.fractions, strategies.fractions)
def test_antisymmetry(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert equivalence(first >= second >= first, first == second)


@given(strategies.fractions, strategies.fractions, strategies.fractions)
def test_transitivity(first: Fractions.Fraction,
second: Fractions.Fraction,
third: Fractions.Fraction) -> None:
assert implication(first >= second >= third, first >= third)


@given(strategies.fractions, strategies.fractions)
def test_equivalents(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
result = first >= second

assert equivalence(result, second <= first)
assert equivalence(result, first > second or first == second)
assert equivalence(result, second < first or first == second)
47 changes: 47 additions & 0 deletions tests/fraction_tests/test_constructor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import pytest
from hypothesis import given

from tests.binding import (BigInteger,
Fractions,
System)
from tests.utils import equivalence
from . import strategies


@given(strategies.numerators, strategies.denominators)
def test_basic(numerator: BigInteger, denominator: BigInteger) -> None:
result = Fractions.Fraction(numerator, denominator)

assert (numerator.IsZero and result.numerator.IsZero
or (numerator % result.numerator).IsZero)
assert (numerator.IsZero and result.numerator.IsZero
or (denominator % result.denominator).IsZero)


def test_no_argument() -> None:
result = Fractions.Fraction()

assert result == Fractions.Fraction(0, 1)


@given(strategies.fractions)
def test_copy_constructor(fraction: Fractions.Fraction) -> None:
result = Fractions.Fraction(fraction)

assert result == fraction


@given(strategies.numerators, strategies.denominators)
def test_properties(numerator: int, denominator: int) -> None:
result = Fractions.Fraction(numerator, denominator)

assert equivalence(numerator.IsZero, result.numerator.IsZero)
assert numerator * result.denominator == result.numerator * denominator
assert result.denominator > BigInteger.Zero


@given(strategies.numerators, strategies.zero_integers)
def test_zero_denominator(numerator: BigInteger,
denominator: BigInteger) -> None:
with pytest.raises(System.DivideByZeroException):
Fractions.Fraction(numerator, denominator)
43 changes: 43 additions & 0 deletions tests/fraction_tests/test_op_Addition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from numbers import Rational

from hypothesis import given

from tests.binding import (BigInteger,
Fractions)
from tests.utils import is_fraction_valid
from . import strategies


@given(strategies.fractions, strategies.rationals)
def test_basic(first: Fractions.Fraction, second: Rational) -> None:
result = first + second

assert isinstance(result, Fractions.Fraction)
assert is_fraction_valid(result)


@given(strategies.fractions, strategies.big_integers)
def test_integer_argument(first: Fractions.Fraction,
second: BigInteger) -> None:
result = first + second

assert result == first + Fractions.Fraction(second)


@given(strategies.fractions, strategies.fractions)
def test_commutativity(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert first + second == second + first


@given(strategies.fractions, strategies.zero_fractions)
def test_neutral_element(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert first + second == first == second + first


@given(strategies.fractions, strategies.fractions, strategies.fractions)
def test_associativity(first: Fractions.Fraction,
second: Fractions.Fraction,
third: Fractions.Fraction) -> None:
assert (first + second) + third == first + (second + third)
48 changes: 48 additions & 0 deletions tests/fraction_tests/test_op_Division.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import pytest
from hypothesis import given

from tests.binding import (BigInteger,
Fractions,
System)
from tests.hints import Rational
from tests.utils import (equivalence,
is_fraction_valid)
from . import strategies


@given(strategies.fractions, strategies.non_zero_fractions)
def test_basic(dividend: Fractions.Fraction,
divisor: Fractions.Fraction) -> None:
result = dividend / divisor

assert isinstance(result, Fractions.Fraction)
assert is_fraction_valid(result)


@given(strategies.non_zero_fractions, strategies.non_zero_fractions)
def test_commutative_case(dividend: Fractions.Fraction,
divisor: Fractions.Fraction) -> None:
assert equivalence(
dividend / divisor == divisor / dividend,
Fractions.Fraction.Abs(dividend) == Fractions.Fraction.Abs(divisor)
)


@given(strategies.zero_fractions, strategies.non_zero_fractions)
def test_left_absorbing_element(dividend: Fractions.Fraction,
divisor: Fractions.Fraction) -> None:
assert dividend / divisor == dividend


@given(strategies.fractions, strategies.non_zero_integers)
def test_big_integer_argument(dividend: Fractions.Fraction,
divisor: BigInteger) -> None:
result = dividend / divisor

assert result == dividend / Fractions.Fraction(divisor)


@given(strategies.fractions, strategies.zero_rationals)
def test_zero_divisor(dividend: Fractions.Fraction, divisor: Rational) -> None:
with pytest.raises(System.DivideByZeroException):
dividend / divisor
31 changes: 31 additions & 0 deletions tests/fraction_tests/test_op_Equality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from hypothesis import given

from tests.binding import Fractions
from tests.hints import Rational
from tests.utils import (equivalence,
implication)
from . import strategies


@given(strategies.fractions)
def test_reflexivity(fraction: Fractions.Fraction) -> None:
assert fraction == fraction


@given(strategies.fractions, strategies.fractions)
def test_symmetry(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert equivalence(first == second, second == first)


@given(strategies.fractions, strategies.fractions, strategies.fractions)
def test_transitivity(first: Fractions.Fraction,
second: Fractions.Fraction,
third: Fractions.Fraction) -> None:
assert implication(first == second and second == third, first == third)


@given(strategies.fractions, strategies.rationals)
def test_connection_with_inequality(first: Fractions.Fraction,
second: Rational) -> None:
assert equivalence(not first == second, first != second)
35 changes: 35 additions & 0 deletions tests/fraction_tests/test_op_LessThan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from hypothesis import given

from tests.binding import Fractions
from tests.utils import (equivalence,
implication)
from . import strategies


@given(strategies.fractions)
def test_irreflexivity(fraction: Fractions.Fraction) -> None:
assert not fraction < fraction


@given(strategies.fractions, strategies.fractions)
def test_asymmetry(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
assert implication(first < second, not second < first)


@given(strategies.fractions, strategies.fractions, strategies.fractions)
def test_transitivity(first: Fractions.Fraction,
second: Fractions.Fraction,
third: Fractions.Fraction) -> None:
assert implication(first < second < third,
first < third)


@given(strategies.fractions, strategies.fractions)
def test_equivalents(first: Fractions.Fraction,
second: Fractions.Fraction) -> None:
result = first < second

assert equivalence(result, second > first)
assert equivalence(result, second >= first != second)
assert equivalence(result, first <= second != first)
Loading

0 comments on commit 18078f6

Please sign in to comment.