diff --git a/ext/TestExt/Mutating-ops.jl b/ext/TestExt/Mutating-ops.jl new file mode 100644 index 000000000..b70da0f72 --- /dev/null +++ b/ext/TestExt/Mutating-ops.jl @@ -0,0 +1,142 @@ +# The following functions should not expect that their input is a `NCRingElem` or similar. +# They should be usable in more general types, that don't even have a `parent/elem` correspondence + +function ConformanceTests.test_mutating_op_like_zero(f::Function, f!::Function, A) + a = deepcopy(A) + a = f!(a) + @test equality(a, f(A)) +end + +function ConformanceTests.test_mutating_op_like_neg(f::Function, f!::Function, A) + # initialize storage var with different values to check that its value is not used + for z in [zero(A), deepcopy(A)] + a = deepcopy(A) + z = f!(z, a) + @test equality(z, f(A)) + @test a == A + end + + a = deepcopy(A) + a = f!(a) + @test equality(a, f(A)) +end + +function ConformanceTests.test_mutating_op_like_add(f::Function, f!::Function, A, B, T = Any) + @req A isa T || B isa T "Invalid argument types" + + # initialize storage var with different values to check that its value is not used + storage_values = T[] + if A isa T + push!(storage_values, zero(A)) + push!(storage_values, deepcopy(A)) + end + if B isa T + push!(storage_values, zero(B)) + push!(storage_values, deepcopy(B)) + end + for z in storage_values + a = deepcopy(A) + b = deepcopy(B) + z = f!(z, a, b) + @test equality(z, f(A, B)) + @test a == A + @test b == B + end + + if A isa T + a = deepcopy(A) + b = deepcopy(B) + a = f!(a, a, b) + @test equality(a, f(A, B)) + @test b == B + + a = deepcopy(A) + b = deepcopy(B) + a = f!(a, b) + @test equality(a, f(A, B)) + @test b == B + end + + if B isa T + a = deepcopy(A) + b = deepcopy(B) + b = f!(b, a, b) + @test equality(b, f(A, B)) + @test a == A + end + + if A isa T && B isa T + # `f(B, B)` may fail if `!(A isa T)`, since we call it with different arguments than the intended `f(A, B)` (same for f!) + a = deepcopy(A) + b = deepcopy(B) + a = f!(a, b, b) + @test equality(a, f(B, B)) + @test b == B + + b = deepcopy(B) + b = f!(b, b, b) + @test equality(b, f(B, B)) + + b = deepcopy(B) + b = f!(b, b) + @test equality(b, f(B, B)) + end +end + +function ConformanceTests.test_mutating_op_like_addmul(f::Function, f!_::Function, Z, A, B, T = Any) + @req Z isa T "Invalid argument types" + @req A isa T || B isa T "Invalid argument types" + + f!(z, a, b, ::Nothing) = f!_(z, a, b) + f!(z, a, b, t) = f!_(z, a, b, t) + + # initialize storage var with different values to check that its value is not used + # and `nothing` for the three-arg dispatch + storage_values = Union{T,Nothing}[nothing] + if A isa T + push!(storage_values, zero(A)) + push!(storage_values, deepcopy(A)) + end + if B isa T + push!(storage_values, zero(B)) + push!(storage_values, deepcopy(B)) + end + for t in storage_values + z = deepcopy(Z) + a = deepcopy(A) + b = deepcopy(B) + z = f!(z, a, b, t) + @test equality(z, f(Z, A, B)) + @test a == A + @test b == B + + if A isa T + a = deepcopy(A) + b = deepcopy(B) + a = f!(a, a, b, t) + @test equality(a, f(A, A, B)) + @test b == B + end + + if B isa T + a = deepcopy(A) + b = deepcopy(B) + b = f!(b, a, b, t) + @test equality(b, f(B, A, B)) + @test a == A + end + + if A isa T && B isa T + # `f(B, B)` may fail if `!(A isa T)`, since we call it with different arguments than the intended `f(A, B)` (same for f!) + a = deepcopy(A) + b = deepcopy(B) + a = f!(a, b, b, t) + @test equality(a, f(A, B, B)) + @test b == B + + b = deepcopy(B) + b = f!(b, b, b, t) + @test equality(b, f(B, B, B)) + end + end +end diff --git a/ext/TestExt/Rings-conformance-tests.jl b/ext/TestExt/Rings-conformance-tests.jl new file mode 100644 index 000000000..69209c83f --- /dev/null +++ b/ext/TestExt/Rings-conformance-tests.jl @@ -0,0 +1,784 @@ +# very generic testing: just define test_elem(R) to produce elements of R, +# then invoke one of these functions, as appropriate: +# - test_NCRing_interface(R) +# - test_Ring_interface(R) +# - test_Ring_interface_recursive(R) +# - test_Field_interface(R) +# - test_Field_interface_recursive(R) +# +# The "recursive" variants perform additional tests on algebraic +# structures derived from the original ring, by calling these helpers: +# - test_EuclideanRing_interface(R) +# - test_Poly_interface(R) +# - test_MPoly_interface(R) +# - test_MatSpace_interface(R) +# - test_MatAlgebra_interface(R) + + +function ConformanceTests.test_NCRing_interface(R::AbstractAlgebra.NCRing; reps = 50) + + T = elem_type(R) + + @testset "NCRing interface for $(R) of type $(typeof(R))" begin + + @test T <: NCRingElem || T <: RingElement + + @testset "Functions for types and parents of rings" begin + @test elem_type(typeof(R)) == T + @test parent_type(T) == typeof(R) + for i in 1:reps + a = test_elem(R)::T + @test parent(a) == R + end + @test is_domain_type(T) isa Bool + @test is_exact_type(T) isa Bool + + # if the ring supports base_ring, verify it also supports base_ring_type and is consistent + if applicable(base_ring, R) + @test base_ring_type(R) == typeof(base_ring(R)) + @test base_ring_type(zero(R)) == typeof(base_ring(zero(R))) + @test base_ring_type(typeof(R)) == typeof(base_ring(R)) + @test base_ring_type(T) == typeof(base_ring(zero(R))) + end + + # some rings don't support characteristic and raise an exception (see issue #993) + try ch = characteristic(R) + @test iszero(R(characteristic(R))) + @test iszero(characteristic(R) * one(R)) + @test iszero(one(R) * characteristic(R)) + catch + end + end + + @testset "Constructors" begin + @test R() isa T + @test R(true) isa T + @test R(false) isa T + @test R(0) isa T + @test R(1) isa T + @test R(-2) isa T + @test R(BigInt(0)) isa T + @test R(BigInt(1)) isa T + @test R(BigInt(-2)) isa T + @test R(BigInt(3)^100) isa T + for i in 1:reps + a = test_elem(R)::T + @test R(a) isa T + end + end + + @testset "Basic functions" begin + @test iszero(R()) # R() is supposed to construct 0 ? + @test iszero(zero(R)) + @test isone(one(R)) + @test iszero(R(0)) + @test isone(R(1)) + @test isone(R(0)) || !is_unit(R(0)) + @test is_unit(R(1)) + for i in 1:reps + a = test_elem(R)::T + @test hash(a) isa UInt + A = deepcopy(a) + @test !ismutable(a) || a !== A + @test equality(a, A) + @test hash(a) == hash(A) + @test parent(a) === parent(A) + @test sprint(show, "text/plain", a) isa String + end + @test sprint(show, "text/plain", R) isa String + + for i in 1:reps + a = test_elem(R)::T + b = test_elem(R)::T + c = test_elem(R)::T + A = deepcopy(a) + B = deepcopy(b) + C = deepcopy(c) + @test equality(+(a), a) + @test equality(*(a), a) + @test equality(a^1, a) + @test equality(a^2, a*a) + @test equality(a^3, a*a*a) + @test equality(a^4, a*a*a*a) + @test equality((a + b) + c, a + (b + c)) + @test equality(a + b, b + a) + @test equality(a - c, a + (-c)) + @test equality(a + zero(R), a) + @test equality(a + (-a), zero(R)) + @test equality((a*b)*c, a*(b*c)) + @test equality(a*one(R), a) + @test equality(one(R)*a, a) + @test equality(a*(b + c), a*b + a*c) + @test equality((a + b)*c, a*c + b*c) + @test iszero(a*zero(R)) + @test iszero(zero(R)*a) + @test A == a + @test B == b + @test C == c + end + end + + if is_exact_type(T) + @testset "Adhoc operations with $S" for S in adhoc_partner_rings(R) + s0 = zero(S) + r0 = zero(R) + s1 = one(S) + r1 = one(R) + for i in 1:reps + s2 = test_elem(S) + r2 = R(s2) + x = test_elem(R) + + for (s,r) in ((s0, r0), (s1, r1), (s2, r2)) + @test equality(r, s) + @test equality(s, r) + + @test equality(x + s, x + r) + @test equality(s + x, r + x) + + @test equality(x - s, x - r) + @test equality(s - x, r - x) + + @test equality(x * s, x * r) + @test equality(s * x, r * x) + end + end + end + end + + if !(R isa AbstractAlgebra.Ring) + @testset "Basic functionality for noncommutative rings only" begin + for i in 1:reps + a = test_elem(R)::T + b = test_elem(R)::T + A = deepcopy(a) + B = deepcopy(b) + # documentation is not clear on divexact + if is_domain_type(T) + @test iszero(b) || equality(divexact_left(b*a, b), a) + @test iszero(b) || equality(divexact_left(b*a, b, check = true), a) + @test iszero(b) || equality(divexact_left(b*a, b, check = false), a) + @test iszero(b) || equality(b \ (b*a), a) + + @test iszero(b) || equality(divexact_right(a*b, b), a) + @test iszero(b) || equality(divexact_right(a*b, b, check = true), a) + @test iszero(b) || equality(divexact_right(a*b, b, check = false), a) + @test iszero(b) || equality((a*b) / b, a) + else + try + t = divexact_left(b*a, b) + @test equality(b*t, b*a) + t = divexact_left(b*a, b, check = true) + @test equality(b*t, b*a) + t = divexact_left(b*a, b, check = false) + @test equality(b*t, b*a) + t = b \ (b*a) + @test equality(b*t, b*a) + catch + end + try + t = divexact_right(a*b, b) + @test equality(t*b, a*b) + t = divexact_right(a*b, b, check = true) + @test equality(t*b, a*b) + t = divexact_right(a*b, b, check = false) + @test equality(t*b, a*b) + t = (a*b) / b + @test equality(t*b, a*b) + catch + end + end + @test A == a + @test B == b + end + end + end + + @testset "Unsafe ring operators" begin + for i in 1:reps + a = test_elem(R)::T + b = test_elem(R)::T + c = test_elem(R)::T + + ConformanceTests.test_mutating_op_like_zero(zero, zero!, a) + ConformanceTests.test_mutating_op_like_zero(one, one!, a) + + ConformanceTests.test_mutating_op_like_neg(-, neg!, a) + + ConformanceTests.test_mutating_op_like_add(+, add!, a, b) + ConformanceTests.test_mutating_op_like_add(-, sub!, a, b) + ConformanceTests.test_mutating_op_like_add(*, mul!, a, b) + + ConformanceTests.test_mutating_op_like_addmul((a, b, c) -> a + b*c, addmul!, a, b, c) + ConformanceTests.test_mutating_op_like_addmul((a, b, c) -> a - b*c, submul!, a, b, c) + end + end + end + + return nothing +end + + +function ConformanceTests.test_Ring_interface(R::AbstractAlgebra.Ring; reps = 50) + + T = elem_type(R) + + @testset "Ring interface for $(R) of type $(typeof(R))" begin + + @test T <: RingElement + + ConformanceTests.test_NCRing_interface(R; reps = reps) + + @testset "Basic functionality for commutative rings only" begin + @test isone(AbstractAlgebra.inv(one(R))) + ConformanceTests.test_mutating_op_like_neg(AbstractAlgebra.inv, inv!, one(R)) + ConformanceTests.test_mutating_op_like_neg(AbstractAlgebra.inv, inv!, -one(R)) + for i in 1:reps + a = test_elem(R)::T + b = test_elem(R)::T + A = deepcopy(a) + B = deepcopy(b) + @test a*b == b*a + # documentation is not clear on divexact + if is_domain_type(T) + @test iszero(b) || equality(divexact(b*a, b), a) + @test iszero(b) || equality(divexact(b*a, b, check = true), a) + @test iszero(b) || equality(divexact(b*a, b, check = false), a) + if T isa RingElem + @test iszero(b) || equality((b*a) / b, a) + end + iszero(b) || ConformanceTests.test_mutating_op_like_add(divexact, divexact!, b*a, b) + else + try + t = divexact(b*a, b) + @test equality(t*b, a*b) + t = divexact(b*a, b, check = true) + @test equality(t*b, a*b) + t = divexact(b*a, b, check = false) + @test equality(t*b, a*b) + if T isa RingElem + t = (b*a) / b + @test equality(t*b, a*b) + end + catch + end + end + try + (f, h) = is_zero_divisor_with_annihilator(a) + @test parent(h) == R + @test f == is_zero_divisor(a) + if f + @test !is_zero(h) + @test is_zero(a*h) + end + catch + end + @test A == a + @test B == b + end + end + end + + return nothing +end + +function ConformanceTests.test_Field_interface(R::AbstractAlgebra.Field; reps = 50) + + T = elem_type(R) + + @testset "Field interface for $(R) of type $(typeof(R))" begin + + ConformanceTests.test_Ring_interface(R, reps = reps) + + @test iszero(R(characteristic(R))) + @test iszero(characteristic(R) * one(R)) + @test iszero(one(R) * characteristic(R)) + + for i in 1:reps + a = test_elem(R)::T + A = deepcopy(a) + @test is_unit(a) == !iszero(a) + if !is_zero(a) + @test is_one(a * inv(a)) + @test is_one(inv(a) * a) + ConformanceTests.test_mutating_op_like_neg(inv, inv!, a) + end + @test A == a + end + end + + return nothing +end + +function ConformanceTests.test_EuclideanRing_interface(R::AbstractAlgebra.Ring; reps = 20) + + T = elem_type(R) + + is_exact_type(T) || return + + @testset "Euclidean Ring interface for $(R) of type $(typeof(R))" begin + + for i in 1:reps + f = test_elem(R)::T + g = test_elem(R)::T + m = test_elem(R)::T + if iszero(m) + m = one(R) + end + + @test (AbstractAlgebra.div(f, m), mod(f, m)) == AbstractAlgebra.divrem(f, m) + @test divides(mulmod(f, g, m) - mod(f*g, m), m)[1] + + fi = one(R) + for i in 1:5 + fi *= f + @test divides(fi - powermod(f, i, m), m)[1] + @test divides(fi - mod(f^i, m), m)[1] + end + + if is_unit(gcd(f, m)) + a = invmod(f, m) + @test divides(mulmod(a, f, m) - one(R), m)[1] + @test divides(powermod(f, -1, m) - a^1, m)[1] + @test divides(powermod(f, -2, m) - a^2, m)[1] + @test divides(powermod(f, -3, m) - a^3, m)[1] + end + + @test divides(f*m, m) == (true, f) + (a, b) = divides(f*m + g, m) + @test !a || b*m == f*m + g + + @test_throws Exception remove(f, zero(R)) + @test_throws Exception valuation(f, zero(R)) + + if !is_unit(m) && !iszero(f) + n = rand(0:3) + f *= m^n + (v, q) = remove(f, m) + @test valuation(f, m) == v + @test v >= n + @test q*m^v == f + @test remove(q, m) == (0, q) + @test valuation(q, m) == 0 + end + + @test !(iszero(f) && iszero(g)) || iszero(gcd(f, g)) + @test equality_up_to_units(gcd(f, g)*lcm(f, g), f*g) + + g1 = gcd(f, gcd(g, m)) + g2 = gcd(gcd(f, g), m) + g3 = gcd(f, g, m) + g4 = gcd([f, g, m]) + @test equality_up_to_units(g1, g2) + @test equality_up_to_units(g2, g3) + @test equality_up_to_units(g3, g4) + + l1 = lcm(f, lcm(g, m)) + l2 = lcm(lcm(f, g), m) + l3 = lcm(f, g, m) + l4 = lcm([f, g, m]) + @test equality_up_to_units(l1, l2) + @test equality_up_to_units(l2, l3) + @test equality_up_to_units(l3, l4) + + (d, s, t) = gcdx(f, g) + @test d == gcd(f, g) + @test d == s*f + t*g + @test gcdinv(f, g) == (d, s) + + ConformanceTests.test_mutating_op_like_add(AbstractAlgebra.div, div!, f, m) + ConformanceTests.test_mutating_op_like_add(mod, mod!, f, m) + ConformanceTests.test_mutating_op_like_add(gcd, gcd!, f, m) + ConformanceTests.test_mutating_op_like_add(lcm, lcm!, f, m) + end + + end + + return nothing +end + + +function ConformanceTests.test_Poly_interface(Rx::AbstractAlgebra.PolyRing; reps = 30) + + T = elem_type(Rx) + + @testset "Poly interface for $(Rx) of type $(typeof(Rx))" begin + + ConformanceTests.test_Ring_interface(Rx; reps = reps) + + x = gen(Rx) + R = base_ring(Rx) + + @testset "Polynomial Constructors" begin + for i in 1:reps + a = test_elem(Rx)::T + for b in coefficients(a) + @assert Rx(b) isa T + end + @test a == Rx(collect(coefficients(a))) + + B = MPolyBuildCtx(Rx) # TODO rename to BuildCtx + for (c, e) in zip(AbstractAlgebra.coefficients(a), AbstractAlgebra.exponent_vectors(a)) + push_term!(B, c, e) + end + @test finish(B) == a + end + @test Rx(Int[]) == zero(Rx) + @test Rx([0, 1, 2]) == x + 2*x^2 + @test Rx([big(0), big(1), big(2)]) == x + 2*x^2 + @test Rx(map(R, [0, 1, 2])) == x + 2*x^2 + end + + if R isa AbstractAlgebra.Field + ConformanceTests.test_EuclideanRing_interface(Rx, reps = 2 + fld(reps, 2)) + @testset "Half-GCD" begin + for i in 1:reps + a = test_elem(Rx) + b = test_elem(Rx) + for j in 1:8 + q = test_elem(Rx) + a, b = q*a + b, a + end + g, s, t = gcdx(a, b) + @test g == gcd(a, b) + @test g == s*a + t*b + @test (g, s) == gcdinv(a, b) + if degree(a) < degree(b) + a, b = b, a + end + degree(a) > degree(b) >= 0 || continue + (A, B, m11, m12, m21, m22, s) = hgcd(a, b) + @test degree(A) >= cld(degree(a), 2) > degree(B) + @test m11*A + m12*B == a + @test m21*A + m22*B == b + @test m11*m22 - m21*m12 == s + @test s^2 == 1 + end + end + end + + @testset "Basic functionality" begin + @test var(Rx) isa Symbol + @test symbols(Rx) isa Vector{Symbol} + @test length(symbols(Rx)) == 1 + @test is_gen(gen(Rx)) + @test is_gen(x) + @test is_monic(x) + @test is_trivial(Rx) || !is_gen(x^2) + for i in 1:reps + a = test_elem(Rx) + @test iszero(a) || degree(a) >= 0 + @test equality(a, leading_coefficient(a)*x^max(0, degree(a)) + tail(a)) + @test constant_coefficient(a) isa elem_type(R) + @test trailing_coefficient(a) isa elem_type(R) + @test is_monic(a) == isone(leading_coefficient(a)) + end + end + end + + return nothing +end + + +function ConformanceTests.test_MPoly_interface(Rxy::AbstractAlgebra.MPolyRing; reps = 30) + + # for simplicity, these tests for now assume exactly two generators + @assert ngens(Rxy) == 2 + + T = elem_type(Rxy) + + @testset "MPoly interface for $(Rxy) of type $(typeof(Rxy))" begin + + ConformanceTests.test_Ring_interface(Rxy; reps = reps) + + @testset "Basic functionality" begin + @test symbols(Rxy) isa Vector{Symbol} + @test length(symbols(Rxy)) == ngens(Rxy) + @test length(gens(Rxy)) == ngens(Rxy) + @test gens(Rxy) == [gen(Rxy, i) for i in 1:ngens(Rxy)] + @test all(is_gen, gens(Rxy)) || is_trivial(Rxy) + end + + @testset "Polynomial Constructors" begin + for i in 1:reps + a = test_elem(Rxy)::T + for b in coefficients(a) + @assert Rxy(b) isa T + end + + # test MPolyBuildCtx + B = MPolyBuildCtx(Rxy) + for (c, e) in zip(AbstractAlgebra.coefficients(a), AbstractAlgebra.exponent_vectors(a)) + push_term!(B, c, e) + end + @test finish(B) == a + end + x, y = gens(Rxy) + f = 13*x^3*y^4 + 2*x - 7 + #@test Rxy([2,-7,13], [[1,0],[0,0],[3,4]]) == f # FIXME: interface spec does not say this is required? + + R = base_ring(Rxy) + @test Rxy(R.([2,-7,13]), [[1,0],[0,0],[3,4]]) == f + end + + # skip trivial rings after this, it is not worth the bother + is_trivial(Rxy) && return + + @testset "Element properties" begin + R = base_ring(Rxy) + x, y = gens(Rxy) + + a = zero(Rxy) + @test !is_monomial(a) + @test !is_term(a) + @test is_constant(a) + @test !is_gen(a) + @test !is_unit(a) + @test is_nilpotent(a) + @test length(a) == 0 + @test total_degree(a) < 0 + @test all(is_negative, degrees(a)) + + a = one(Rxy) + @test is_monomial(a) + @test is_term(a) + @test is_constant(a) + @test !is_gen(a) + @test is_unit(a) + @test !is_nilpotent(a) + @test length(a) == 1 + @test total_degree(a) == 0 + @test degrees(a) == [0, 0] + + a = x + @test is_monomial(a) + @test is_term(a) + @test !is_constant(a) + @test is_gen(a) + @test !is_unit(a) + @test !is_nilpotent(a) + @test length(a) == 1 + @test total_degree(a) == 1 + @test degrees(a) == [1, 0] + + a = x^2 + @test is_monomial(a) + @test is_term(a) + @test !is_constant(a) + @test !is_gen(a) + @test !is_unit(a) + @test !is_nilpotent(a) + @test length(a) == 1 + @test total_degree(a) == 2 + @test degrees(a) == [2, 0] + + if !is_zero(R(2)) + a = 2*x + @test !is_monomial(a) + @test is_term(a) + @test !is_constant(a) + @test !is_gen(a) + @test !is_unit(a) + @test is_nilpotent(a) == is_nilpotent(R(2)) + @test length(a) == 1 + @test total_degree(a) == 1 + @test degrees(a) == [1, 0] + end + + a = x^3 + y^4 + @test !is_monomial(a) + @test !is_term(a) + @test !is_constant(a) + @test !is_gen(a) + @test !is_unit(a) + @test !is_nilpotent(a) + @test length(a) == 2 + @test total_degree(a) == 4 + @test degrees(a) == [3, 4] + + for i in 1:reps + a = test_elem(Rxy) + iszero(a) && continue + @test length(a) >= 0 + @test sum(degrees(a)) >= total_degree(a) + end + + end + + # TODO: add more tests, covering everything described in the manual, see + # https://nemocas.github.io/AbstractAlgebra.jl/dev/mpoly_interface/ + # https://nemocas.github.io/AbstractAlgebra.jl/dev/mpolynomial/ + end + + return nothing +end + + +function ConformanceTests.test_MatSpace_interface(S::MatSpace; reps = 20) + + ST = elem_type(S) + R = base_ring(S) + T = elem_type(R) + + @test base_ring_type(S) == typeof(R) + @test parent_type(ST) == typeof(S) + @test dense_matrix_type(R) == ST + + @testset "MatSpace interface for $(S) of type $(typeof(S))" begin + + @testset "Constructors" begin + for k in 1:reps + a = test_elem(S)::ST + @test nrows(a) == nrows(S) + @test ncols(a) == ncols(S) + @test a == S(T[a[i, j] for i in 1:nrows(a), j in 1:ncols(a)]) + @test a == S(T[a[i, j] for i in 1:nrows(a) for j in 1:ncols(a)]) + @test a == matrix(R, T[a[i, j] for i in 1:nrows(a), j in 1:ncols(a)]) + @test a == matrix(R, nrows(S), ncols(S), + T[a[i, j] for i in 1:nrows(a) for j in 1:ncols(a)]) + + b = similar(a) + @test b isa ST + @test nrows(b) == nrows(S) + @test ncols(b) == ncols(S) + + b = similar(a, nrows(S)+1, ncols(S)+1) + @test b isa ST + @test nrows(b) == nrows(S)+1 + @test ncols(b) == ncols(S)+1 + + b = similar(a, R) + @test b isa MatElem + #@test b isa ST # undefined + @test nrows(b) == nrows(S) + @test ncols(b) == ncols(S) + + b = similar(a, R, nrows(S)+1, ncols(S)+1) + @test b isa MatElem + #@test b isa ST # undefined + @test nrows(b) == nrows(S)+1 + @test ncols(b) == ncols(S)+1 + + end + @test iszero(zero_matrix(R, nrows(S), ncols(S))) + end + + @testset "Views" begin + M = matrix(R, 3, 3, BigInt[1, 2, 3, 2, 3, 4, 3, 4, 5]) + N1 = @view M[1:2, :] + N2 = @view M[:, 1:2] + @test N1*N2 == matrix(R, 2, 2, BigInt[14, 20, 20, 29]) + end + + @testset "Basic manipulation of matrices" begin + for k in 1:reps + a = test_elem(S)::ST + A = deepcopy(a) + @test A isa ST + + b = zero_matrix(R, nrows(a), ncols(a)) + @test b isa ST + for i in 1:nrows(a), j in 1:ncols(a) + b[i, j] = a[i, j] + end + @test b == a + + t = transpose(a) + @test t isa ST + @test nrows(t) == ncols(S) + @test ncols(t) == nrows(S) + @test transpose(t) == a + @test a == A + end + end + + @testset "Row & column permutations" begin + a = matrix(R, [1 2 ; 3 4]) + b = swap_rows(a, 1, 2) + @test b == matrix(R, [3 4 ; 1 2]) + @test a == matrix(R, [1 2 ; 3 4]) + + a = matrix(R, [1 2 ; 3 4]) + b = swap_cols(a, 1, 2) + @test b == matrix(R, [2 1 ; 4 3]) + @test a == matrix(R, [1 2 ; 3 4]) + + # TODO: reverse_rows, reverse_cols + # TODO: add_column, add_row + # TODO: multiply_column, multiply_row + # TODO: ! variants (such as `swap_cols!` etc.) of all of the above + end + + end + + return nothing +end + +function ConformanceTests.test_MatAlgebra_interface(S::MatRing; reps = 20) + + ST = elem_type(S) + R = base_ring(S) + T = elem_type(R) + + @test nrows(S) == ncols(S) + + @testset "MatRing interface for $(S) of type $(typeof(S))" begin + + ConformanceTests.test_NCRing_interface(S, reps = reps) + + @testset "Constructors" begin + for k in 1:reps + a = test_elem(S)::ST + @test nrows(a) == nrows(S) + @test ncols(a) == ncols(S) + @test a == S(T[a[i, j] for i in 1:nrows(a), j in 1:ncols(a)]) + @test a == S(T[a[i, j] for i in 1:nrows(a) for j in 1:ncols(a)]) + end + end + + @testset "Basic manipulation of matrices" begin + for k in 1:reps + a = test_elem(S)::ST + A = deepcopy(a) + b = zero(S) + for i in 1:nrows(a), j in 1:ncols(a) + b[i, j] = a[i, j] + end + @test b == a + @test transpose(transpose(a)) == a + @test a == A + end + end + + @testset "Determinant" begin + for k in 1:reps + a = test_elem(S)::ST + b = test_elem(S)::ST + A = deepcopy(a) + B = deepcopy(b) + @test det(a*b) == det(a)*det(b) + @test a == A + @test b == B + end + end + end + + return nothing +end + +function ConformanceTests.test_Ring_interface_recursive(R::AbstractAlgebra.Ring; reps = 50) + ConformanceTests.test_Ring_interface(R; reps = reps) + Rx, _ = polynomial_ring(R, :x) + ConformanceTests.test_Poly_interface(Rx, reps = 2 + fld(reps, 2)) + Rxy, _ = polynomial_ring(R, [:x, :y]) + ConformanceTests.test_MPoly_interface(Rxy, reps = 2 + fld(reps, 2)) + S = matrix_ring(R, rand(0:3)) + ConformanceTests.test_MatAlgebra_interface(S, reps = 2 + fld(reps, 2)) + S = matrix_space(R, rand(0:3), rand(0:3)) + ConformanceTests.test_MatSpace_interface(S, reps = 2 + fld(reps, 2)) +end + +function ConformanceTests.test_Field_interface_recursive(R::AbstractAlgebra.Field; reps = 50) + ConformanceTests.test_Ring_interface_recursive(R, reps = reps) + ConformanceTests.test_Field_interface(R, reps = reps) +end diff --git a/ext/TestExt/TestExt.jl b/ext/TestExt/TestExt.jl index a61384d6a..b512f9fbc 100644 --- a/ext/TestExt/TestExt.jl +++ b/ext/TestExt/TestExt.jl @@ -3,8 +3,15 @@ module TestExt using AbstractAlgebra isdefined(Base, :get_extension) ? (using Test) : (using ..Test) +using .ConformanceTests: + equality, + equality_up_to_units, + adhoc_partner_rings, + test_elem include("Groups-conformance-tests.jl") +include("Mutating-ops.jl") +include("Rings-conformance-tests.jl") function ConformanceTests.test_iterate(F::FinField) diff --git a/src/ConformanceTests.jl b/src/ConformanceTests.jl index bb109c900..7de0c2631 100644 --- a/src/ConformanceTests.jl +++ b/src/ConformanceTests.jl @@ -1,13 +1,148 @@ module ConformanceTests -# This file only contains function stubs. +using ..AbstractAlgebra + +# This file mostly contains function stubs. # The actual implementation are in the folder `ext/TestExt/`. + +# helper +function equality(a, b) + if is_exact_type(typeof(a)) && is_exact_type(typeof(b)) + return a == b + else + return isapprox(a, b) + end +end + +function equality_up_to_units(a, b) + iszero(a) && return iszero(b) + iszero(b) && return iszero(a) + return divides(a, b)[1] && divides(b, a)[1] +end + +const default_adhoc_partner_rings = [ + AbstractAlgebra.Integers{BigInt}(), + AbstractAlgebra.Integers{Int}(), + AbstractAlgebra.Integers{UInt}(), + AbstractAlgebra.Integers{UInt8}(), + ] + +adhoc_partner_rings(R::NCRing) = default_adhoc_partner_rings + + +# +# add methods for test_elem on ring elements here +# +function test_elem(R::AbstractAlgebra.Integers{T}) where {T <: Signed} + n = T(2)^rand((1,1,1,2,3,10,31,32,33,63,64,65,100)) + return rand(R, -n:n) +end + +function test_elem(R::AbstractAlgebra.Integers{T}) where {T <: Unsigned} + n = T(2)^rand((1,1,1,2,3,10,31,32,33,63,64,65,100)) + return rand(R, 0:n) +end + +function test_elem(R::AbstractAlgebra.Rationals) + B = base_ring(R) + n = test_elem(B) + d = test_elem(B) + return is_zero(d) ? R(n) : R(n, d) +end + +function test_elem(R::AbstractAlgebra.FinField) + return rand(R) +end + +function test_elem(R::AbstractAlgebra.Floats{T}) where T + return rand(T)*rand(-100:100) +end + +function test_elem(Rx::AbstractAlgebra.PolyRing) + R = base_ring(Rx) + return Rx(elem_type(R)[test_elem(R) for i in 1:rand(0:6)]) +end + +function test_elem(Rx::AbstractAlgebra.MPolyRing) + R = base_ring(Rx) + num_gens = ngens(Rx) + iszero(num_gens) && return Rx(test_elem(R)) + len_bound = 8 + exp_bound = rand(1:5) + len = rand(0:len_bound) + coeffs = [test_elem(R) for _ in 1:len] + exps = [[rand(0:exp_bound) for _ in 1:num_gens] for _ in 1:len] + return Rx(coeffs, exps) +end + +function test_elem(S::Union{AbstractAlgebra.MatSpace, + AbstractAlgebra.MatRing}) + R = base_ring(S) + return S(elem_type(R)[test_elem(R) for i in 1:nrows(S), j in 1:ncols(S)]) +end + +function test_elem(R::AbstractAlgebra.EuclideanRingResidueRing) + return R(test_elem(base_ring(R))) +end + +function test_elem(Rx::AbstractAlgebra.SeriesRing) + R = base_ring(Rx) + prec = rand(3:10) + len = rand(0:prec-1) + val = rand(0:prec-len) + # FIXME: constructors don't seem to catch use of negative val + @assert val >= 0 + A = elem_type(R)[test_elem(R) for i in 1:len] + if len > 0 && is_zero(A[1]) + A[1] = one(R) + end + if elem_type(Rx) <: RelPowerSeriesRingElem + @assert prec >= len + val + return Rx(A, len, prec, val) + else + @assert prec >= len + return Rx(A, len, prec) + end +end + +function test_elem(S::AbstractAlgebra.FreeAssociativeAlgebra) + f = S() + g = gens(S) + R = base_ring(S) + isempty(g) && return S(test_elem(R)) + len_bound = 8 + exp_bound = 6 + for i in 1:rand(0:len_bound) + f += test_elem(R) * prod(rand(g) for _ in 1:rand(0:exp_bound); init = S(1)) + end + return f +end + + function test_iterate end # Groups-conformance-tests.jl function test_Group_interface end function test_GroupElem_interface end +# Mutating-ops.jl +function test_mutating_op_like_zero end +function test_mutating_op_like_neg end +function test_mutating_op_like_add end +function test_mutating_op_like_addmul end + +# Rings-conformance-tests.jl +function test_NCRing_interface end +function test_Ring_interface end +function test_Field_interface end +function test_EuclideanRing_interface end +function test_Poly_interface end +function test_MPoly_interface end +function test_MatSpace_interface end +function test_MatAlgebra_interface end +function test_Ring_interface_recursive end +function test_Field_interface_recursive end + end # module diff --git a/test/Rings-conformance-tests.jl b/test/Rings-conformance-tests.jl index 0e9aa4097..a6b5d11cc 100644 --- a/test/Rings-conformance-tests.jl +++ b/test/Rings-conformance-tests.jl @@ -1,1041 +1,23 @@ -# very generic testing: just define test_elem(R) to produce elements of R, -# then invoke one of these functions, as appropriate: -# - test_NCRing_interface(R) -# - test_Ring_interface(R) -# - test_Ring_interface_recursive(R) -# - test_Field_interface(R) -# - test_Field_interface_recursive(R) -# -# The "recursive" variants perform additional tests on algebraic -# structures derived from the original ring, by calling these helpers: -# - test_EuclideanRing_interface(R) -# - test_Poly_interface(R) -# - test_MatSpace_interface(R) -# - test_MatAlgebra_interface(R) - -# -# -# -const default_adhoc_partner_rings = [ - AbstractAlgebra.Integers{BigInt}(), - AbstractAlgebra.Integers{Int}(), - AbstractAlgebra.Integers{UInt}(), - AbstractAlgebra.Integers{UInt8}(), - ] - -adhoc_partner_rings(R::NCRing) = default_adhoc_partner_rings - -# -# add methods for test_elem on ring elements here -# - -function test_elem(R::AbstractAlgebra.Integers{T}) where {T <: Signed} - n = T(2)^rand((1,1,1,2,3,10,31,32,33,63,64,65,100)) - return rand(R, -n:n) -end - -function test_elem(R::AbstractAlgebra.Integers{T}) where {T <: Unsigned} - n = T(2)^rand((1,1,1,2,3,10,31,32,33,63,64,65,100)) - return rand(R, 0:n) -end - -function test_elem(R::AbstractAlgebra.Rationals) - B = base_ring(R) - n = test_elem(B) - d = test_elem(B) - return is_zero(d) ? R(n) : R(n, d) -end - -function test_elem(R::AbstractAlgebra.FinField) - return rand(R) -end - -function test_elem(R::AbstractAlgebra.Floats{T}) where T - return rand(T)*rand(-100:100) -end - -function test_elem(Rx::AbstractAlgebra.PolyRing) - R = base_ring(Rx) - return Rx(elem_type(R)[test_elem(R) for i in 1:rand(0:6)]) -end - -function test_elem(Rx::AbstractAlgebra.MPolyRing) - R = base_ring(Rx) - num_gens = ngens(Rx) - iszero(num_gens) && return Rx(test_elem(R)) - len_bound = 8 - exp_bound = rand(1:5) - len = rand(0:len_bound) - coeffs = [test_elem(R) for _ in 1:len] - exps = [[rand(0:exp_bound) for _ in 1:num_gens] for _ in 1:len] - return Rx(coeffs, exps) -end - -function test_elem(S::Union{AbstractAlgebra.MatSpace, - AbstractAlgebra.MatRing}) - R = base_ring(S) - return S(elem_type(R)[test_elem(R) for i in 1:nrows(S), j in 1:ncols(S)]) -end - -function test_elem(R::AbstractAlgebra.EuclideanRingResidueRing) - return R(test_elem(base_ring(R))) -end - -function test_elem(Rx::AbstractAlgebra.SeriesRing) - R = base_ring(Rx) - prec = rand(3:10) - len = rand(0:prec-1) - val = rand(0:prec-len) - # FIXME: constructors don't seem to catch use of negative val - @assert val >= 0 - A = elem_type(R)[test_elem(R) for i in 1:len] - if len > 0 && is_zero(A[1]) - A[1] = one(R) - end - if elem_type(Rx) <: RelPowerSeriesRingElem - @assert prec >= len + val - return Rx(A, len, prec, val) - else - @assert prec >= len - return Rx(A, len, prec) - end -end - -function test_elem(S::AbstractAlgebra.FreeAssociativeAlgebra) - f = S() - g = gens(S) - R = base_ring(S) - isempty(g) && return S(test_elem(R)) - len_bound = 8 - exp_bound = 6 - for i in 1:rand(0:len_bound) - f += test_elem(R) * prod(rand(g) for _ in 1:rand(0:exp_bound); init = S(1)) - end - return f -end - - -# helper -function equality(a, b) - if is_exact_type(typeof(a)) && is_exact_type(typeof(b)) - return a == b - else - return isapprox(a, b) - end -end - -# The following functions should not expect that their input is a `NCRingElem` or similar. -# They should be usable in more general types, that don't even have a `parent/elem` correspondence -function test_mutating_op_like_zero(f::Function, f!::Function, A) - a = deepcopy(A) - a = f!(a) - @test equality(a, f(A)) -end - -function test_mutating_op_like_neg(f::Function, f!::Function, A) - # initialize storage var with different values to check that its value is not used - for z in [zero(A), deepcopy(A)] - a = deepcopy(A) - z = f!(z, a) - @test equality(z, f(A)) - @test a == A - end - - a = deepcopy(A) - a = f!(a) - @test equality(a, f(A)) -end - -function test_mutating_op_like_add(f::Function, f!::Function, A, B, T = Any) - @req A isa T || B isa T "Invalid argument types" - - # initialize storage var with different values to check that its value is not used - storage_values = T[] - if A isa T - push!(storage_values, zero(A)) - push!(storage_values, deepcopy(A)) - end - if B isa T - push!(storage_values, zero(B)) - push!(storage_values, deepcopy(B)) - end - for z in storage_values - a = deepcopy(A) - b = deepcopy(B) - z = f!(z, a, b) - @test equality(z, f(A, B)) - @test a == A - @test b == B - end - - if A isa T - a = deepcopy(A) - b = deepcopy(B) - a = f!(a, a, b) - @test equality(a, f(A, B)) - @test b == B - - a = deepcopy(A) - b = deepcopy(B) - a = f!(a, b) - @test equality(a, f(A, B)) - @test b == B - end - - if B isa T - a = deepcopy(A) - b = deepcopy(B) - b = f!(b, a, b) - @test equality(b, f(A, B)) - @test a == A - end - - if A isa T && B isa T - # `f(B, B)` may fail if `!(A isa T)`, since we call it with different arguments than the intended `f(A, B)` (same for f!) - a = deepcopy(A) - b = deepcopy(B) - a = f!(a, b, b) - @test equality(a, f(B, B)) - @test b == B - - b = deepcopy(B) - b = f!(b, b, b) - @test equality(b, f(B, B)) - - b = deepcopy(B) - b = f!(b, b) - @test equality(b, f(B, B)) - end -end - -function test_mutating_op_like_addmul(f::Function, f!_::Function, Z, A, B, T = Any) - @req Z isa T "Invalid argument types" - @req A isa T || B isa T "Invalid argument types" - - f!(z, a, b, ::Nothing) = f!_(z, a, b) - f!(z, a, b, t) = f!_(z, a, b, t) - - # initialize storage var with different values to check that its value is not used - # and `nothing` for the three-arg dispatch - storage_values = Union{T,Nothing}[nothing] - if A isa T - push!(storage_values, zero(A)) - push!(storage_values, deepcopy(A)) - end - if B isa T - push!(storage_values, zero(B)) - push!(storage_values, deepcopy(B)) - end - for t in storage_values - z = deepcopy(Z) - a = deepcopy(A) - b = deepcopy(B) - z = f!(z, a, b, t) - @test equality(z, f(Z, A, B)) - @test a == A - @test b == B - - if A isa T - a = deepcopy(A) - b = deepcopy(B) - a = f!(a, a, b, t) - @test equality(a, f(A, A, B)) - @test b == B - end - - if B isa T - a = deepcopy(A) - b = deepcopy(B) - b = f!(b, a, b, t) - @test equality(b, f(B, A, B)) - @test a == A - end - - if A isa T && B isa T - # `f(B, B)` may fail if `!(A isa T)`, since we call it with different arguments than the intended `f(A, B)` (same for f!) - a = deepcopy(A) - b = deepcopy(B) - a = f!(a, b, b, t) - @test equality(a, f(A, B, B)) - @test b == B - - b = deepcopy(B) - b = f!(b, b, b, t) - @test equality(b, f(B, B, B)) - end - end -end - -function test_NCRing_interface(R::AbstractAlgebra.NCRing; reps = 50) - - T = elem_type(R) - - @testset "NCRing interface for $(R) of type $(typeof(R))" begin - - @test T <: NCRingElem || T <: RingElement - - @testset "Functions for types and parents of rings" begin - @test elem_type(typeof(R)) == T - @test parent_type(T) == typeof(R) - for i in 1:reps - a = test_elem(R)::T - @test parent(a) == R - end - @test is_domain_type(T) isa Bool - @test is_exact_type(T) isa Bool - - # if the ring supports base_ring, verify it also supports base_ring_type and is consistent - if applicable(base_ring, R) - @test base_ring_type(R) == typeof(base_ring(R)) - @test base_ring_type(zero(R)) == typeof(base_ring(zero(R))) - @test base_ring_type(typeof(R)) == typeof(base_ring(R)) - @test base_ring_type(T) == typeof(base_ring(zero(R))) - end - - # some rings don't support characteristic and raise an exception (see issue #993) - try ch = characteristic(R) - @test iszero(R(characteristic(R))) - @test iszero(characteristic(R) * one(R)) - @test iszero(one(R) * characteristic(R)) - catch - end - end - - @testset "Constructors" begin - @test R() isa T - @test R(true) isa T - @test R(false) isa T - @test R(0) isa T - @test R(1) isa T - @test R(-2) isa T - @test R(BigInt(0)) isa T - @test R(BigInt(1)) isa T - @test R(BigInt(-2)) isa T - @test R(BigInt(3)^100) isa T - for i in 1:reps - a = test_elem(R)::T - @test R(a) isa T - end - end - - @testset "Basic functions" begin - @test iszero(R()) # R() is supposed to construct 0 ? - @test iszero(zero(R)) - @test isone(one(R)) - @test iszero(R(0)) - @test isone(R(1)) - @test isone(R(0)) || !is_unit(R(0)) - @test is_unit(R(1)) - for i in 1:reps - a = test_elem(R)::T - @test hash(a) isa UInt - A = deepcopy(a) - @test !ismutable(a) || a !== A - @test equality(a, A) - @test hash(a) == hash(A) - @test parent(a) === parent(A) - @test sprint(show, "text/plain", a) isa String - end - @test sprint(show, "text/plain", R) isa String - - for i in 1:reps - a = test_elem(R)::T - b = test_elem(R)::T - c = test_elem(R)::T - A = deepcopy(a) - B = deepcopy(b) - C = deepcopy(c) - @test equality(+(a), a) - @test equality(*(a), a) - @test equality(a^1, a) - @test equality(a^2, a*a) - @test equality(a^3, a*a*a) - @test equality(a^4, a*a*a*a) - @test equality((a + b) + c, a + (b + c)) - @test equality(a + b, b + a) - @test equality(a - c, a + (-c)) - @test equality(a + zero(R), a) - @test equality(a + (-a), zero(R)) - @test equality((a*b)*c, a*(b*c)) - @test equality(a*one(R), a) - @test equality(one(R)*a, a) - @test equality(a*(b + c), a*b + a*c) - @test equality((a + b)*c, a*c + b*c) - @test iszero(a*zero(R)) - @test iszero(zero(R)*a) - @test A == a - @test B == b - @test C == c - end - end - - if is_exact_type(T) - @testset "Adhoc operations with $S" for S in adhoc_partner_rings(R) - s0 = zero(S) - r0 = zero(R) - s1 = one(S) - r1 = one(R) - for i in 1:reps - s2 = test_elem(S) - r2 = R(s2) - x = test_elem(R) - - for (s,r) in ((s0, r0), (s1, r1), (s2, r2)) - @test equality(r, s) - @test equality(s, r) - - @test equality(x + s, x + r) - @test equality(s + x, r + x) - - @test equality(x - s, x - r) - @test equality(s - x, r - x) - - @test equality(x * s, x * r) - @test equality(s * x, r * x) - end - end - end - end - - if !(R isa AbstractAlgebra.Ring) - @testset "Basic functionality for noncommutative rings only" begin - for i in 1:reps - a = test_elem(R)::T - b = test_elem(R)::T - A = deepcopy(a) - B = deepcopy(b) - # documentation is not clear on divexact - if is_domain_type(T) - @test iszero(b) || equality(divexact_left(b*a, b), a) - @test iszero(b) || equality(divexact_left(b*a, b, check = true), a) - @test iszero(b) || equality(divexact_left(b*a, b, check = false), a) - @test iszero(b) || equality(b \ (b*a), a) - - @test iszero(b) || equality(divexact_right(a*b, b), a) - @test iszero(b) || equality(divexact_right(a*b, b, check = true), a) - @test iszero(b) || equality(divexact_right(a*b, b, check = false), a) - @test iszero(b) || equality((a*b) / b, a) - else - try - t = divexact_left(b*a, b) - @test equality(b*t, b*a) - t = divexact_left(b*a, b, check = true) - @test equality(b*t, b*a) - t = divexact_left(b*a, b, check = false) - @test equality(b*t, b*a) - t = b \ (b*a) - @test equality(b*t, b*a) - catch - end - try - t = divexact_right(a*b, b) - @test equality(t*b, a*b) - t = divexact_right(a*b, b, check = true) - @test equality(t*b, a*b) - t = divexact_right(a*b, b, check = false) - @test equality(t*b, a*b) - t = (a*b) / b - @test equality(t*b, a*b) - catch - end - end - @test A == a - @test B == b - end - end - end - - @testset "Unsafe ring operators" begin - for i in 1:reps - a = test_elem(R)::T - b = test_elem(R)::T - c = test_elem(R)::T - - test_mutating_op_like_zero(zero, zero!, a) - test_mutating_op_like_zero(one, one!, a) - - test_mutating_op_like_neg(-, neg!, a) - - test_mutating_op_like_add(+, add!, a, b) - test_mutating_op_like_add(-, sub!, a, b) - test_mutating_op_like_add(*, mul!, a, b) - - test_mutating_op_like_addmul((a, b, c) -> a + b*c, addmul!, a, b, c) - test_mutating_op_like_addmul((a, b, c) -> a - b*c, submul!, a, b, c) - end - end - end - - return nothing -end - - -function test_Ring_interface(R::AbstractAlgebra.Ring; reps = 50) - - T = elem_type(R) - - @testset "Ring interface for $(R) of type $(typeof(R))" begin - - @test T <: RingElement - - test_NCRing_interface(R; reps = reps) - - @testset "Basic functionality for commutative rings only" begin - @test isone(AbstractAlgebra.inv(one(R))) - test_mutating_op_like_neg(AbstractAlgebra.inv, inv!, one(R)) - test_mutating_op_like_neg(AbstractAlgebra.inv, inv!, -one(R)) - for i in 1:reps - a = test_elem(R)::T - b = test_elem(R)::T - A = deepcopy(a) - B = deepcopy(b) - @test a*b == b*a - # documentation is not clear on divexact - if is_domain_type(T) - @test iszero(b) || equality(divexact(b*a, b), a) - @test iszero(b) || equality(divexact(b*a, b, check = true), a) - @test iszero(b) || equality(divexact(b*a, b, check = false), a) - if T isa RingElem - @test iszero(b) || equality((b*a) / b, a) - end - iszero(b) || test_mutating_op_like_add(divexact, divexact!, b*a, b) - else - try - t = divexact(b*a, b) - @test equality(t*b, a*b) - t = divexact(b*a, b, check = true) - @test equality(t*b, a*b) - t = divexact(b*a, b, check = false) - @test equality(t*b, a*b) - if T isa RingElem - t = (b*a) / b - @test equality(t*b, a*b) - end - catch - end - end - try - (f, h) = is_zero_divisor_with_annihilator(a) - @test parent(h) == R - @test f == is_zero_divisor(a) - if f - @test !is_zero(h) - @test is_zero(a*h) - end - catch - end - @test A == a - @test B == b - end - end - end - - return nothing -end - -function test_Field_interface(R::AbstractAlgebra.Field; reps = 50) - - T = elem_type(R) - - @testset "Field interface for $(R) of type $(typeof(R))" begin - - test_Ring_interface(R, reps = reps) - - @test iszero(R(characteristic(R))) - @test iszero(characteristic(R) * one(R)) - @test iszero(one(R) * characteristic(R)) - - for i in 1:reps - a = test_elem(R)::T - A = deepcopy(a) - @test is_unit(a) == !iszero(a) - if !is_zero(a) - @test is_one(a * inv(a)) - @test is_one(inv(a) * a) - test_mutating_op_like_neg(inv, inv!, a) - end - @test A == a - end - end - - return nothing -end - -function equality_up_to_units(a, b) - iszero(a) && return iszero(b) - iszero(b) && return iszero(a) - return divides(a, b)[1] && divides(b, a)[1] -end - -function test_EuclideanRing_interface(R::AbstractAlgebra.Ring; reps = 20) - - T = elem_type(R) - - is_exact_type(T) || return - - @testset "Euclidean Ring interface for $(R) of type $(typeof(R))" begin - - for i in 1:reps - f = test_elem(R)::T - g = test_elem(R)::T - m = test_elem(R)::T - if iszero(m) - m = one(R) - end - - @test (AbstractAlgebra.div(f, m), mod(f, m)) == AbstractAlgebra.divrem(f, m) - @test divides(mulmod(f, g, m) - mod(f*g, m), m)[1] - - fi = one(R) - for i in 1:5 - fi *= f - @test divides(fi - powermod(f, i, m), m)[1] - @test divides(fi - mod(f^i, m), m)[1] - end - - if is_unit(gcd(f, m)) - a = invmod(f, m) - @test divides(mulmod(a, f, m) - one(R), m)[1] - @test divides(powermod(f, -1, m) - a^1, m)[1] - @test divides(powermod(f, -2, m) - a^2, m)[1] - @test divides(powermod(f, -3, m) - a^3, m)[1] - end - - @test divides(f*m, m) == (true, f) - (a, b) = divides(f*m + g, m) - @test !a || b*m == f*m + g - - @test_throws Exception remove(f, zero(R)) - @test_throws Exception valuation(f, zero(R)) - - if !is_unit(m) && !iszero(f) - n = rand(0:3) - f *= m^n - (v, q) = remove(f, m) - @test valuation(f, m) == v - @test v >= n - @test q*m^v == f - @test remove(q, m) == (0, q) - @test valuation(q, m) == 0 - end - - @test !(iszero(f) && iszero(g)) || iszero(gcd(f, g)) - @test equality_up_to_units(gcd(f, g)*lcm(f, g), f*g) - - g1 = gcd(f, gcd(g, m)) - g2 = gcd(gcd(f, g), m) - g3 = gcd(f, g, m) - g4 = gcd([f, g, m]) - @test equality_up_to_units(g1, g2) - @test equality_up_to_units(g2, g3) - @test equality_up_to_units(g3, g4) - - l1 = lcm(f, lcm(g, m)) - l2 = lcm(lcm(f, g), m) - l3 = lcm(f, g, m) - l4 = lcm([f, g, m]) - @test equality_up_to_units(l1, l2) - @test equality_up_to_units(l2, l3) - @test equality_up_to_units(l3, l4) - - (d, s, t) = gcdx(f, g) - @test d == gcd(f, g) - @test d == s*f + t*g - @test gcdinv(f, g) == (d, s) - - test_mutating_op_like_add(AbstractAlgebra.div, div!, f, m) - test_mutating_op_like_add(mod, mod!, f, m) - test_mutating_op_like_add(gcd, gcd!, f, m) - test_mutating_op_like_add(lcm, lcm!, f, m) - end - - end - - return nothing -end - - -function test_Poly_interface(Rx::AbstractAlgebra.PolyRing; reps = 30) - - T = elem_type(Rx) - - @testset "Poly interface for $(Rx) of type $(typeof(Rx))" begin - - test_Ring_interface(Rx; reps = reps) - - x = gen(Rx) - R = base_ring(Rx) - - @testset "Polynomial Constructors" begin - for i in 1:reps - a = test_elem(Rx)::T - for b in coefficients(a) - @assert Rx(b) isa T - end - @test a == Rx(collect(coefficients(a))) - - B = MPolyBuildCtx(Rx) # TODO rename to BuildCtx - for (c, e) in zip(AbstractAlgebra.coefficients(a), AbstractAlgebra.exponent_vectors(a)) - push_term!(B, c, e) - end - @test finish(B) == a - end - @test Rx(Int[]) == zero(Rx) - @test Rx([0, 1, 2]) == x + 2*x^2 - @test Rx([big(0), big(1), big(2)]) == x + 2*x^2 - @test Rx(map(R, [0, 1, 2])) == x + 2*x^2 - end - - if R isa AbstractAlgebra.Field - test_EuclideanRing_interface(Rx, reps = 2 + fld(reps, 2)) - @testset "Half-GCD" begin - for i in 1:reps - a = test_elem(Rx) - b = test_elem(Rx) - for j in 1:8 - q = test_elem(Rx) - a, b = q*a + b, a - end - g, s, t = gcdx(a, b) - @test g == gcd(a, b) - @test g == s*a + t*b - @test (g, s) == gcdinv(a, b) - if degree(a) < degree(b) - a, b = b, a - end - degree(a) > degree(b) >= 0 || continue - (A, B, m11, m12, m21, m22, s) = hgcd(a, b) - @test degree(A) >= cld(degree(a), 2) > degree(B) - @test m11*A + m12*B == a - @test m21*A + m22*B == b - @test m11*m22 - m21*m12 == s - @test s^2 == 1 - end - end - end - - @testset "Basic functionality" begin - @test var(Rx) isa Symbol - @test symbols(Rx) isa Vector{Symbol} - @test length(symbols(Rx)) == 1 - @test is_gen(gen(Rx)) - @test is_gen(x) - @test is_monic(x) - @test is_trivial(Rx) || !is_gen(x^2) - for i in 1:reps - a = test_elem(Rx) - @test iszero(a) || degree(a) >= 0 - @test equality(a, leading_coefficient(a)*x^max(0, degree(a)) + tail(a)) - @test constant_coefficient(a) isa elem_type(R) - @test trailing_coefficient(a) isa elem_type(R) - @test is_monic(a) == isone(leading_coefficient(a)) - end - end - end - - return nothing -end - - -function test_MPoly_interface(Rxy::AbstractAlgebra.MPolyRing; reps = 30) - - # for simplicity, these tests for now assume exactly two generators - @assert ngens(Rxy) == 2 - - T = elem_type(Rxy) - - @testset "MPoly interface for $(Rxy) of type $(typeof(Rxy))" begin - - test_Ring_interface(Rxy; reps = reps) - - @testset "Basic functionality" begin - @test symbols(Rxy) isa Vector{Symbol} - @test length(symbols(Rxy)) == ngens(Rxy) - @test length(gens(Rxy)) == ngens(Rxy) - @test gens(Rxy) == [gen(Rxy, i) for i in 1:ngens(Rxy)] - @test all(is_gen, gens(Rxy)) || is_trivial(Rxy) - end - - @testset "Polynomial Constructors" begin - for i in 1:reps - a = test_elem(Rxy)::T - for b in coefficients(a) - @assert Rxy(b) isa T - end - - # test MPolyBuildCtx - B = MPolyBuildCtx(Rxy) - for (c, e) in zip(AbstractAlgebra.coefficients(a), AbstractAlgebra.exponent_vectors(a)) - push_term!(B, c, e) - end - @test finish(B) == a - end - x, y = gens(Rxy) - f = 13*x^3*y^4 + 2*x - 7 - #@test Rxy([2,-7,13], [[1,0],[0,0],[3,4]]) == f # FIXME: interface spec does not say this is required? - - R = base_ring(Rxy) - @test Rxy(R.([2,-7,13]), [[1,0],[0,0],[3,4]]) == f - end - - # skip trivial rings after this, it is not worth the bother - is_trivial(Rxy) && return - - @testset "Element properties" begin - R = base_ring(Rxy) - x, y = gens(Rxy) - - a = zero(Rxy) - @test !is_monomial(a) - @test !is_term(a) - @test is_constant(a) - @test !is_gen(a) - @test !is_unit(a) - @test is_nilpotent(a) - @test length(a) == 0 - @test total_degree(a) < 0 - @test all(is_negative, degrees(a)) - - a = one(Rxy) - @test is_monomial(a) - @test is_term(a) - @test is_constant(a) - @test !is_gen(a) - @test is_unit(a) - @test !is_nilpotent(a) - @test length(a) == 1 - @test total_degree(a) == 0 - @test degrees(a) == [0, 0] - - a = x - @test is_monomial(a) - @test is_term(a) - @test !is_constant(a) - @test is_gen(a) - @test !is_unit(a) - @test !is_nilpotent(a) - @test length(a) == 1 - @test total_degree(a) == 1 - @test degrees(a) == [1, 0] - - a = x^2 - @test is_monomial(a) - @test is_term(a) - @test !is_constant(a) - @test !is_gen(a) - @test !is_unit(a) - @test !is_nilpotent(a) - @test length(a) == 1 - @test total_degree(a) == 2 - @test degrees(a) == [2, 0] - - if !is_zero(R(2)) - a = 2*x - @test !is_monomial(a) - @test is_term(a) - @test !is_constant(a) - @test !is_gen(a) - @test !is_unit(a) - @test is_nilpotent(a) == is_nilpotent(R(2)) - @test length(a) == 1 - @test total_degree(a) == 1 - @test degrees(a) == [1, 0] - end - - a = x^3 + y^4 - @test !is_monomial(a) - @test !is_term(a) - @test !is_constant(a) - @test !is_gen(a) - @test !is_unit(a) - @test !is_nilpotent(a) - @test length(a) == 2 - @test total_degree(a) == 4 - @test degrees(a) == [3, 4] - - for i in 1:reps - a = test_elem(Rxy) - iszero(a) && continue - @test length(a) >= 0 - @test sum(degrees(a)) >= total_degree(a) - end - - end - - # TODO: add more tests, covering everything described in the manual, see - # https://nemocas.github.io/AbstractAlgebra.jl/dev/mpoly_interface/ - # https://nemocas.github.io/AbstractAlgebra.jl/dev/mpolynomial/ - end - - return nothing -end - - -function test_MatSpace_interface(S::MatSpace; reps = 20) - - ST = elem_type(S) - R = base_ring(S) - T = elem_type(R) - - @test base_ring_type(S) == typeof(R) - @test parent_type(ST) == typeof(S) - @test dense_matrix_type(R) == ST - - @testset "MatSpace interface for $(S) of type $(typeof(S))" begin - - @testset "Constructors" begin - for k in 1:reps - a = test_elem(S)::ST - @test nrows(a) == nrows(S) - @test ncols(a) == ncols(S) - @test a == S(T[a[i, j] for i in 1:nrows(a), j in 1:ncols(a)]) - @test a == S(T[a[i, j] for i in 1:nrows(a) for j in 1:ncols(a)]) - @test a == matrix(R, T[a[i, j] for i in 1:nrows(a), j in 1:ncols(a)]) - @test a == matrix(R, nrows(S), ncols(S), - T[a[i, j] for i in 1:nrows(a) for j in 1:ncols(a)]) - - b = similar(a) - @test b isa ST - @test nrows(b) == nrows(S) - @test ncols(b) == ncols(S) - - b = similar(a, nrows(S)+1, ncols(S)+1) - @test b isa ST - @test nrows(b) == nrows(S)+1 - @test ncols(b) == ncols(S)+1 - - b = similar(a, R) - @test b isa MatElem - #@test b isa ST # undefined - @test nrows(b) == nrows(S) - @test ncols(b) == ncols(S) - - b = similar(a, R, nrows(S)+1, ncols(S)+1) - @test b isa MatElem - #@test b isa ST # undefined - @test nrows(b) == nrows(S)+1 - @test ncols(b) == ncols(S)+1 - - end - @test iszero(zero_matrix(R, nrows(S), ncols(S))) - end - - @testset "Views" begin - M = matrix(R, 3, 3, BigInt[1, 2, 3, 2, 3, 4, 3, 4, 5]) - N1 = @view M[1:2, :] - N2 = @view M[:, 1:2] - @test N1*N2 == matrix(R, 2, 2, BigInt[14, 20, 20, 29]) - end - - @testset "Basic manipulation of matrices" begin - for k in 1:reps - a = test_elem(S)::ST - A = deepcopy(a) - @test A isa ST - - b = zero_matrix(R, nrows(a), ncols(a)) - @test b isa ST - for i in 1:nrows(a), j in 1:ncols(a) - b[i, j] = a[i, j] - end - @test b == a - - t = transpose(a) - @test t isa ST - @test nrows(t) == ncols(S) - @test ncols(t) == nrows(S) - @test transpose(t) == a - @test a == A - end - end - - @testset "Row & column permutations" begin - a = matrix(R, [1 2 ; 3 4]) - b = swap_rows(a, 1, 2) - @test b == matrix(R, [3 4 ; 1 2]) - @test a == matrix(R, [1 2 ; 3 4]) - - a = matrix(R, [1 2 ; 3 4]) - b = swap_cols(a, 1, 2) - @test b == matrix(R, [2 1 ; 4 3]) - @test a == matrix(R, [1 2 ; 3 4]) - - # TODO: reverse_rows, reverse_cols - # TODO: add_column, add_row - # TODO: multiply_column, multiply_row - # TODO: ! variants (such as `swap_cols!` etc.) of all of the above - end - - end - - return nothing -end - -function test_MatAlgebra_interface(S::MatRing; reps = 20) - - ST = elem_type(S) - R = base_ring(S) - T = elem_type(R) - - @test nrows(S) == ncols(S) - - @testset "MatRing interface for $(S) of type $(typeof(S))" begin - - test_NCRing_interface(S, reps = reps) - - @testset "Constructors" begin - for k in 1:reps - a = test_elem(S)::ST - @test nrows(a) == nrows(S) - @test ncols(a) == ncols(S) - @test a == S(T[a[i, j] for i in 1:nrows(a), j in 1:ncols(a)]) - @test a == S(T[a[i, j] for i in 1:nrows(a) for j in 1:ncols(a)]) - end - end - - @testset "Basic manipulation of matrices" begin - for k in 1:reps - a = test_elem(S)::ST - A = deepcopy(a) - b = zero(S) - for i in 1:nrows(a), j in 1:ncols(a) - b[i, j] = a[i, j] - end - @test b == a - @test transpose(transpose(a)) == a - @test a == A - end - end - - @testset "Determinant" begin - for k in 1:reps - a = test_elem(S)::ST - b = test_elem(S)::ST - A = deepcopy(a) - B = deepcopy(b) - @test det(a*b) == det(a)*det(b) - @test a == A - @test b == B - end - end - end - - return nothing -end - -function test_Ring_interface_recursive(R::AbstractAlgebra.Ring; reps = 50) - test_Ring_interface(R; reps = reps) - Rx, _ = polynomial_ring(R, :x) - test_Poly_interface(Rx, reps = 2 + fld(reps, 2)) - Rxy, _ = polynomial_ring(R, [:x, :y]) - test_MPoly_interface(Rxy, reps = 2 + fld(reps, 2)) - S = matrix_ring(R, rand(0:3)) - test_MatAlgebra_interface(S, reps = 2 + fld(reps, 2)) - S = matrix_space(R, rand(0:3), rand(0:3)) - test_MatSpace_interface(S, reps = 2 + fld(reps, 2)) -end - -function test_Field_interface_recursive(R::AbstractAlgebra.Field; reps = 50) - test_Ring_interface_recursive(R, reps = reps) - test_Field_interface(R, reps = reps) -end +# This file is just for backwards compatibility and should be removed in the future. + +# Assumptions (as that was already required with the previous setup): +# - `AbstractAlgebra` is already loaded +# - `Test` is available in the environment + +# load TestExt +using Test + +import ConformanceTests: test_elem as test_elem +import ConformanceTests: adhoc_partner_rings as adhoc_partner_rings +import ConformanceTests: equality as equality + +test_NCRing_interface = ConformanceTests.test_NCRing_interface +test_Ring_interface = ConformanceTests.test_Ring_interface +test_Field_interface = ConformanceTests.test_Field_interface +test_EuclideanRing_interface = ConformanceTests.test_EuclideanRing_interface +test_Poly_interface = ConformanceTests.test_Poly_interface +test_MPoly_interface = ConformanceTests.test_MPoly_interface +test_MatSpace_interface = ConformanceTests.test_MatSpace_interface +test_MatAlgebra_interface = ConformanceTests.test_MatAlgebra_interface +test_Ring_interface_recursive = ConformanceTests.test_Ring_interface_recursive +test_Field_interface_recursive = ConformanceTests.test_Field_interface_recursive diff --git a/test/generic/AbsMSeries-test.jl b/test/generic/AbsMSeries-test.jl index a41d49469..45e8887d0 100644 --- a/test/generic/AbsMSeries-test.jl +++ b/test/generic/AbsMSeries-test.jl @@ -4,7 +4,7 @@ end @testset "Generic.AbsMSeries.conformance" begin R, (x, y) = power_series_ring(ZZ, [5, 3], ["x", "y"]) - test_Ring_interface(R) + ConformanceTests.test_Ring_interface(R) end @testset "Generic.AbsMSeries.constructors" begin diff --git a/test/generic/AbsSeries-test.jl b/test/generic/AbsSeries-test.jl index 442c91788..67de078a5 100644 --- a/test/generic/AbsSeries-test.jl +++ b/test/generic/AbsSeries-test.jl @@ -18,7 +18,7 @@ @testset "Generic.AbsSeries.conformance" begin R, x = power_series_ring(ZZ, 30, "x", model=:capped_absolute) - test_Ring_interface(R) + ConformanceTests.test_Ring_interface(R) end @testset "Generic.AbsSeries.types" begin diff --git a/test/generic/FactoredFraction-test.jl b/test/generic/FactoredFraction-test.jl index db22cd09d..d5faadef6 100644 --- a/test/generic/FactoredFraction-test.jl +++ b/test/generic/FactoredFraction-test.jl @@ -11,7 +11,7 @@ end @testset "Generic.FactoredFracFieldElem.ZZ.conformance" begin FF = FactoredFractionField(ZZ) - test_Field_interface(FF) + ConformanceTests.test_Field_interface(FF) end @testset "Generic.FactoredFracFieldElem.ZZ.adhoc" begin diff --git a/test/generic/FreeAssociativeAlgebra-test.jl b/test/generic/FreeAssociativeAlgebra-test.jl index a89e3e363..a581a55b7 100644 --- a/test/generic/FreeAssociativeAlgebra-test.jl +++ b/test/generic/FreeAssociativeAlgebra-test.jl @@ -276,10 +276,10 @@ end @testset "Generic.FreeAssociativeAlgebra.NCRing_interface" begin S, = free_associative_algebra(ZZ, 3) - test_NCRing_interface(S) + ConformanceTests.test_NCRing_interface(S) R, = QQ[:x, :y] S, = free_associative_algebra(R, :z => 1:3) - test_NCRing_interface(S) + ConformanceTests.test_NCRing_interface(S) end diff --git a/test/generic/FunctionField-test.jl b/test/generic/FunctionField-test.jl index c533c788b..1e5dd76b7 100644 --- a/test/generic/FunctionField-test.jl +++ b/test/generic/FunctionField-test.jl @@ -18,7 +18,7 @@ P2 = [(x2 + 1)*z2 + (x2 + 2), z2 + (x2 + 1)//(x2 + 2), z2^2 + 3z2 + 1, # #@testset "Generic.FunctionField.conformance" begin # S, y = function_field(P1[4], "y") -# test_Ring_interface(S) +# ConformanceTests.test_Ring_interface(S) #end @testset "Generic.FunctionField.constructors" begin diff --git a/test/generic/LaurentMPoly-test.jl b/test/generic/LaurentMPoly-test.jl index 213f5f20c..ca6df1947 100644 --- a/test/generic/LaurentMPoly-test.jl +++ b/test/generic/LaurentMPoly-test.jl @@ -16,11 +16,11 @@ end @testset "Generic.LaurentMPoly.conformance" begin L, (x, y) = laurent_polynomial_ring(ZZ, ["x", "y"]) - test_Ring_interface(L) - test_Ring_interface_recursive(L) + ConformanceTests.test_Ring_interface(L) + ConformanceTests.test_Ring_interface_recursive(L) L, (x, y) = laurent_polynomial_ring(residue_ring(ZZ, ZZ(6))[1], ["x", "y"]) - test_Ring_interface(L) + ConformanceTests.test_Ring_interface(L) end @testset "Generic.LaurentMPoly.constructors" begin diff --git a/test/generic/LaurentPoly-test.jl b/test/generic/LaurentPoly-test.jl index 98b3cd570..17c1240ce 100644 --- a/test/generic/LaurentPoly-test.jl +++ b/test/generic/LaurentPoly-test.jl @@ -481,12 +481,12 @@ end @testset "conformance" begin L, y = laurent_polynomial_ring(QQ, "y") - test_Ring_interface(L) - test_EuclideanRing_interface(L) - test_Ring_interface_recursive(L) + ConformanceTests.test_Ring_interface(L) + ConformanceTests.test_EuclideanRing_interface(L) + ConformanceTests.test_Ring_interface_recursive(L) L, y = laurent_polynomial_ring(residue_ring(ZZ, ZZ(6))[1], "y") - test_Ring_interface(L) + ConformanceTests.test_Ring_interface(L) end end diff --git a/test/generic/LaurentSeries-test.jl b/test/generic/LaurentSeries-test.jl index 3b87119b0..56a80b6c1 100644 --- a/test/generic/LaurentSeries-test.jl +++ b/test/generic/LaurentSeries-test.jl @@ -22,7 +22,7 @@ end @testset "Generic.LaurentSeries.conformance" begin R, x = laurent_series_ring(ZZ, 10, "x") - test_Ring_interface(R) + ConformanceTests.test_Ring_interface(R) end @testset "Generic.LaurentSeries.constructors" begin diff --git a/test/generic/MPoly-test.jl b/test/generic/MPoly-test.jl index f2e0f12c5..97b830faa 100644 --- a/test/generic/MPoly-test.jl +++ b/test/generic/MPoly-test.jl @@ -1694,17 +1694,17 @@ end @testset "Generic.MPoly.Ring_interface" begin S, = polynomial_ring(QQ, 0) - test_Ring_interface_recursive(S) + ConformanceTests.test_Ring_interface_recursive(S) S, = polynomial_ring(QQ, 1) - test_Ring_interface_recursive(S) + ConformanceTests.test_Ring_interface_recursive(S) S, = polynomial_ring(ZZ, 2) - test_Ring_interface_recursive(S) + ConformanceTests.test_Ring_interface_recursive(S) R, = QQ[:x] S, = polynomial_ring(R, :z => 1:3) - test_Ring_interface(S) # _recursive needs too many ressources + ConformanceTests.test_Ring_interface(S) # _recursive needs too many ressources end @testset "Generic.MPoly.zero_rings" begin @@ -1712,7 +1712,7 @@ end S, = polynomial_ring(R, 2) @test is_zero(gen(S, 1)) && is_one(gen(S, 1)) @test is_zero(one(S)) - test_Ring_interface_recursive(S) + ConformanceTests.test_Ring_interface_recursive(S) end # ------------------------------------------------------- diff --git a/test/generic/Poly-test.jl b/test/generic/Poly-test.jl index 9ab0fe8d8..f653c2dc3 100644 --- a/test/generic/Poly-test.jl +++ b/test/generic/Poly-test.jl @@ -142,11 +142,11 @@ end @testset "Generic.Poly.conformance" begin R, x = polynomial_ring(ZZ, "x") - test_Poly_interface(R) + ConformanceTests.test_Poly_interface(R) R, x = polynomial_ring(QQ, "x") - test_Poly_interface(R) + ConformanceTests.test_Poly_interface(R) R, x = polynomial_ring(GF(5), "x") - test_Poly_interface(R) + ConformanceTests.test_Poly_interface(R) end @testset "Generic.Poly.printing" begin @@ -3039,5 +3039,5 @@ end R, = residue_ring(ZZ, 1) Rx, = R[:x] @test is_zero(gen(Rx)) && is_one(gen(Rx)) - test_Ring_interface_recursive(Rx) + ConformanceTests.test_Ring_interface_recursive(Rx) end diff --git a/test/generic/PuiseuxSeries-test.jl b/test/generic/PuiseuxSeries-test.jl index c983393f9..a44f29e4f 100644 --- a/test/generic/PuiseuxSeries-test.jl +++ b/test/generic/PuiseuxSeries-test.jl @@ -22,7 +22,7 @@ end @testset "Generic.PuiseuxSeries.conformance" begin R, x = puiseux_series_ring(ZZ, 10, "x") - test_Ring_interface(R) + ConformanceTests.test_Ring_interface(R) end @testset "Generic.PuiseuxSeries.constructors" begin diff --git a/test/generic/RationalFunctionField-test.jl b/test/generic/RationalFunctionField-test.jl index e56b8ad82..602b769ce 100644 --- a/test/generic/RationalFunctionField-test.jl +++ b/test/generic/RationalFunctionField-test.jl @@ -4,7 +4,7 @@ end @testset "Generic.FunctionField.conformance" begin S, x = rational_function_field(QQ, "x") - test_Ring_interface(S) + ConformanceTests.test_Ring_interface(S) end @testset "Generic.RationalFunctionField.constructors" begin diff --git a/test/generic/RelSeries-test.jl b/test/generic/RelSeries-test.jl index 8c0992d3d..6cd5dab01 100644 --- a/test/generic/RelSeries-test.jl +++ b/test/generic/RelSeries-test.jl @@ -18,7 +18,7 @@ @testset "Generic.RelSeries.conformance" begin R, x = power_series_ring(ZZ, 10, "x") - test_Ring_interface(R) + ConformanceTests.test_Ring_interface(R) end @testset "Generic.RelSeries.types" begin diff --git a/test/generic/Residue-test.jl b/test/generic/Residue-test.jl index ec607dd58..ddc7507ce 100644 --- a/test/generic/Residue-test.jl +++ b/test/generic/Residue-test.jl @@ -1,20 +1,20 @@ @testset "EuclideanRingResidueRingElem.conformance_tests" begin - test_Ring_interface(residue_ring(ZZ, 1)[1]) # is_gen fails on polys - test_Ring_interface_recursive(residue_ring(ZZ, -4)[1]) + ConformanceTests.test_Ring_interface(residue_ring(ZZ, 1)[1]) # is_gen fails on polys + ConformanceTests.test_Ring_interface_recursive(residue_ring(ZZ, -4)[1]) # R, = residue_ring(ZZ, 16453889) - test_Ring_interface_recursive(R) + ConformanceTests.test_Ring_interface_recursive(R) # S, x = polynomial_ring(R, "x") T, = residue_ring(S, x^3 + 3x + 1) - test_Ring_interface_recursive(T) + ConformanceTests.test_Ring_interface_recursive(T) # S, x = polynomial_ring(QQ, "x") T, = residue_ring(S, x^2 + 1) - test_Ring_interface_recursive(T) + ConformanceTests.test_Ring_interface_recursive(T) @test !occursin("\n", sprint(show, T)) end diff --git a/test/generic/UnivPoly-test.jl b/test/generic/UnivPoly-test.jl index 23dfd47ce..8641f93c2 100644 --- a/test/generic/UnivPoly-test.jl +++ b/test/generic/UnivPoly-test.jl @@ -134,7 +134,7 @@ end @testset "Generic.UnivPoly.conformance" begin S = universal_polynomial_ring(residue_ring(ZZ, ZZ(6))[1]) gen(S, "x") - test_Ring_interface(S) + ConformanceTests.test_Ring_interface(S) end @testset "Generic.UnivPoly.printing" begin diff --git a/test/julia/Floats-test.jl b/test/julia/Floats-test.jl index 270abf5bd..2ad98f933 100644 --- a/test/julia/Floats-test.jl +++ b/test/julia/Floats-test.jl @@ -1,6 +1,6 @@ @testset "Julia.Floats.conformance_tests" begin - test_Ring_interface(RDF) - test_Ring_interface(RealField) + ConformanceTests.test_Ring_interface(RDF) + ConformanceTests.test_Ring_interface(RealField) end @testset "Julia.Floats.printing" begin diff --git a/test/julia/GFElem-test.jl b/test/julia/GFElem-test.jl index b4bf2e868..20ec32b44 100644 --- a/test/julia/GFElem-test.jl +++ b/test/julia/GFElem-test.jl @@ -1,8 +1,8 @@ @testset "Julia.GFElem.conformance_tests" begin - test_Field_interface_recursive(GF(3)) - test_Field_interface_recursive(GF(13)) - test_Field_interface_recursive(GF(big(13))) - test_Field_interface_recursive(GF(big(10)^20 + 39)) + ConformanceTests.test_Field_interface_recursive(GF(3)) + ConformanceTests.test_Field_interface_recursive(GF(13)) + ConformanceTests.test_Field_interface_recursive(GF(big(13))) + ConformanceTests.test_Field_interface_recursive(GF(big(10)^20 + 39)) end @testset "Julia.GFElem.constructors" begin diff --git a/test/julia/Integers-test.jl b/test/julia/Integers-test.jl index b55d96d7c..c51551bc8 100644 --- a/test/julia/Integers-test.jl +++ b/test/julia/Integers-test.jl @@ -1,6 +1,6 @@ @testset "Julia.Integers.conformance_tests" begin - test_Ring_interface_recursive(ZZ) - test_EuclideanRing_interface(ZZ) + ConformanceTests.test_Ring_interface_recursive(ZZ) + ConformanceTests.test_EuclideanRing_interface(ZZ) end @testset "Julia.Integers.manipulation" begin diff --git a/test/julia/Rationals-test.jl b/test/julia/Rationals-test.jl index b80cea244..116c51ffd 100644 --- a/test/julia/Rationals-test.jl +++ b/test/julia/Rationals-test.jl @@ -1,5 +1,5 @@ @testset "Julia.Rationals.conformance_tests" begin - test_Field_interface_recursive(QQ) + ConformanceTests.test_Field_interface_recursive(QQ) end @testset "Julia.Rationals.constructors" begin