using Test
using LinearAlgebra
using GenericLinearAlgebra
using GenericLinearAlgebra: qrBlocked!

@testset "The QR decomposition" begin
    @testset "Problem dimension ($m,$n) with block size $bz" for (m, n) in (
            (10, 5),
            (10, 10),
            (5, 10),
            (100, 50),
            (100, 100),
            (50, 100),
        ),
        bz in (1, 2, 3, 4, 7, 8, 9, 15, 16, 17, 31, 32, 33)

        A = randn(m, n)
        Aqr = qrBlocked!(copy(A), bz)
        AqrQ = Aqr[Tuple{:QBlocked}]
        if m >= n
            @test (AqrQ'A)[1:min(m, n), :] ≈ Aqr[Tuple{:R}]
        else # For type stability getindex(,Tuple{:R}) throw when the output is trapezoid
            @test (AqrQ'A) ≈ triu(Aqr.factors)
        end
        @test AqrQ' * (AqrQ * A) ≈ A
    end

    @testset "Error paths" begin
        @test_throws DimensionMismatch LinearAlgebra.reflectorApply!(
            zeros(5, 5),
            zeros(4),
            1.0,
        )
        @test_throws ArgumentError qrBlocked!(randn(5, 10))[Tuple{:R}]
    end
end
