Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Aqua.jl to tests #187

Merged
merged 2 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ coverage:
status:
project:
default:
threshold: 0.5%
threshold: 0.5%
patch:
default:
target: 80%
16 changes: 14 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,23 @@ ScientificTypesBase = "30f210dd-8aff-4c5f-94ba-8e64358c1161"
StatisticalTraits = "64bff920-2084-43da-a3e6-9bb72801c0c9"

[compat]
ScientificTypesBase = "3.0"
Aqua = "0.8"
CategoricalArrays = "0.10"
DataFrames = "1"
Distances = "0.10"
InteractiveUtils = "<0.0.1, 1"
Markdown = "<0.0.1, 1"
OrderedCollections = "1"
Random = "<0.0.1, 1"
ScientificTypes = "3"
ScientificTypesBase = "3"
StatisticalTraits = "3.2"
Tables = "1"
Test = "<0.0.1, 1"
julia = "1.6"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Expand All @@ -25,4 +37,4 @@ Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["CategoricalArrays", "DataFrames", "Distances", "InteractiveUtils", "Markdown", "OrderedCollections", "ScientificTypes", "Tables", "Test"]
test = ["Aqua", "CategoricalArrays", "DataFrames", "Distances", "InteractiveUtils", "Markdown", "OrderedCollections", "ScientificTypes", "Tables", "Test"]
6 changes: 3 additions & 3 deletions src/data_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ end
# int

"""
int(x; type=nothing)
int(x)

The positional integer of the `CategoricalString` or `CategoricalValue` `x`, in
the ordering defined by the pool of `x`. The type of `int(x)` is the reference
Expand Down Expand Up @@ -96,9 +96,9 @@ julia> int(v)
```
See also: [`decoder`](@ref).
"""
function int(x; type::Union{Nothing, Type{T}}=nothing) where T <: Real
function int(x; type=nothing)
type === nothing && return int(get_interface_mode(), x)
return convert.(T, int(get_interface_mode(), x))
return convert.(type, int(get_interface_mode(), x))
end

int(::LightInterface, x) = errlight("int")
Expand Down
5 changes: 3 additions & 2 deletions src/equality.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
is_same_except(
getproperty(m1, name),
getproperty(m2, name)
) ||
) ||
getproperty(m1, name) isa AbstractRNG ||
getproperty(m2, name) isa AbstractRNG
) || return false
Expand Down Expand Up @@ -155,7 +155,8 @@
end

Base.in(x::MLJType, itr::Set) = special_in(x, itr)
Base.in(x::MLJType, itr::AbstractVector) = special_in(x, itr)
Base.in(x::MLJType, itr::AbstractVector{<:MLJType}) = special_in(x, itr)
Base.in(x::MLJType, itr::AbstractRange{<:MLJType}) = special_in(x, itr)

Check warning on line 159 in src/equality.jl

View check run for this annotation

Codecov / codecov/patch

src/equality.jl#L159

Added line #L159 was not covered by tests
Base.in(x::MLJType, itr::Tuple) = special_in(x, itr)

# A version of `in` that actually uses `==`:
Expand Down
59 changes: 24 additions & 35 deletions src/model_traits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,50 +97,39 @@
# in `prediction_type` for models which, historically, have not
# implemented the trait.

# Actually, this has proven more trouble than it's worth and should be removed in 2.0.
# See https://discourse.julialang.org/t/deconstructing-unionall-types/108328 to appreciate
# some of the complications.

function StatTraits.predict_scitype(
M::Type{<:Union{Probabilistic, ProbabilisticDetector}}
)
return _density(target_scitype(M))
end

_density(::Any) = Unknown

for T in [:Continuous, :Count, :Textual]
eval(
quote
function _density(::Type{AbstractArray{$T, D}}) where D
return AbstractArray{Density{$T}, D}
end
end
)
end
const SCALAR_SCITYPES_EXS =
[:Finite, :Multiclass, :OrderedFactor, :Infinite, :Continuous, :Count, :Textual]

for T in [:Finite, :Multiclass, :OrderedFactor, :Infinite, :Continuous, :Count, :Textual]
eval(
quote
function _density(::Type{AbstractArray{<:$T, D}}) where D
return AbstractArray{Density{<:$T}, D}
end
const SCALAR_SCITYPES =
eval.([:Finite, :Multiclass, :OrderedFactor, :Infinite, :Continuous, :Count, :Textual])

_density(::Type{Table($T)}) = Table(Density{$T})
end
)
function _density(t)
for T in SCALAR_SCITYPES
t == AbstractVector{<:T} && return AbstractVector{Density{<:T}}
t == AbstractMatrix{<:T} && return AbstractMatrix{Density{<:T}}
t == Table(T) && return Table{<:AbstractVector{<:Density{<:T}}}
end
for T in [Finite, Multiclass, OrderedFactor]
t == Table(T{2}) && return Table(Density{<:T{2}})
end
return Unknown

Check warning on line 125 in src/model_traits.jl

View check run for this annotation

Codecov / codecov/patch

src/model_traits.jl#L125

Added line #L125 was not covered by tests
end


for T in [:Finite, :Multiclass, :OrderedFactor]
eval(
for T in SCALAR_SCITYPES_EXS
quote
function _density(::Type{AbstractArray{<:$T{N}, D}}) where {N, D}
return AbstractArray{Density{<:$T{N}}, D}
end

function _density(::Type{AbstractArray{$T{N}, D}}) where {N, D}
return AbstractArray{Density{$T{N}}, D}
end

_density(::Type{Table($T{N})}) where N = Table(Density{$T{N}})
end
)
_density(::Type{<:AbstractArray{W, D}}) where {W<:$T, D} =
AbstractArray{Density{W}, D}
_density(::Type{<:Table{<:AbstractVector{W}}}) where W<:$T =

Check warning on line 132 in src/model_traits.jl

View check run for this annotation

Codecov / codecov/patch

src/model_traits.jl#L132

Added line #L132 was not covered by tests
Table(Density{W})
end |> eval
end

4 changes: 4 additions & 0 deletions test/aqua.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Aqua
import MLJModelInterface

Aqua.test_all(MLJModelInterface, ambiguities=true)
27 changes: 14 additions & 13 deletions test/data_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ end
# needing the `FullInterface`.
X = (1, 2, 3)
@test_throws M.InterfaceError matrix(X)

X = (a=[1, 2, 3], b=[1, 2, 3])
@test_throws M.InterfaceError matrix(X)
end

@testset "matrix-full" begin
setfull()
M.matrix(::FI, ::Val{:table}, X; kw...) = Tables.matrix(X; kw...)
# next line commented out as already defined in test/mode.jl:
# M.matrix(::FI, ::Val{:table}, X; kw...) = Tables.matrix(X; kw...)
X = (a=[1, 2, 3], b=[1, 2, 3])
@test matrix(X) == hcat([1, 2, 3], [1, 2, 3])
end
Expand Down Expand Up @@ -120,14 +121,14 @@ end
# ------------------------------------------------------------------------
@testset "istable" begin
# Nothing stops someone from implementing a Tables.jl
# interface that subtypes `AbstractArray`, so therefore
# interface that subtypes `AbstractArray`, so therefore
# `istable` should throw an error for `LightInterface`
setlight()
X = rand(5)
@test_throws M.InterfaceError M.istable(X)
X = randn(5, 5)
@test_throws M.InterfaceError M.istable(X)

# The method runs in `FullInterface`
setfull()
X = rand(5)
Expand Down Expand Up @@ -184,10 +185,10 @@ end
X = ones(5)
@test nrows(X) == 5
X = ones(5, 3)
@test nrows(X) == 5
# It doesn't make sense to get the numbers of rows for
# `AbstractArray`'s of dimension 3 or more. Except if these are
# defined as Tables. Hence `FullInterface` would be required to check this
@test nrows(X) == 5
# It doesn't make sense to get the numbers of rows for
# `AbstractArray`'s of dimension 3 or more. Except if these are
# defined as Tables. Hence `FullInterface` would be required to check this
X = ones(5, 3, 2)
@test_throws ArgumentError nrows(X)
M.nrows(::FI, ::Val{:table}, X) = Tables.rowcount(X)
Expand Down Expand Up @@ -220,13 +221,13 @@ end

@testset "select-full" begin
setfull()

# test fallback
X = nothing
@test selectrows(X, 1) === nothing
@test selectcols(X, 1) === nothing
@test select(X, 1, 2) === nothing

# vector
X = ones(5)
@test selectrows(X, 1) == [1.0]
Expand Down Expand Up @@ -273,11 +274,11 @@ end

project(t::NamedTuple, label::Colon) = t
project(t::NamedTuple, label::Symbol) = project(t, [label,])

function project(t::NamedTuple, indices::AbstractArray{<:Integer})
return NamedTuple{tuple(keys(t)[indices]...)}(tuple([t[i] for i in indices]...))
end

project(t::NamedTuple, i::Integer) = project(t, [i,])

X = (x=[1, 2, 3], y=[4, 5, 6], z=[0, 0, 0])
Expand All @@ -292,7 +293,7 @@ end
@test select(X, :, 1) == [1, 2, 3]
@test selectcols(X, :x) == [1, 2, 3]
@test select(X, 1:2, :z) == [0, 0]

# extra tests by Anthony
X = (x=[1, 2, 3], y=[10, 20, 30], z= [:a, :b, :c])
@test select(X, 2, :y) == 20
Expand Down
6 changes: 0 additions & 6 deletions test/metadata_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,6 @@ metadata_pkg(FooRegressor2,
is_wrapper=false
)

# this is added in MLJBase but not in MLJModelInterface, to avoid
# InteractiveUtils as dependency:
setfull()
M.implemented_methods(::FI, M::Type{<:MLJType}) =
getfield.(methodswith(M), :name)

const HEADER2 = MLJModelInterface.doc_header(FooRegressor2, augment=true)

@doc """
Expand Down
12 changes: 2 additions & 10 deletions test/model_traits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,6 @@ M.human_name(::Type{<:U1}) = "funky model"

setfull()

function M.implemented_methods(::FI, M::Type{<:MLJType})
return getfield.(methodswith(M), :name)
end

@test Set(implemented_methods(mp)) == Set([:clean!,:bar,:foo])
end

Expand All @@ -140,19 +136,15 @@ end
M._density(AbstractVector{<:T}),
AbstractVector{Density{<:T}}
)
@test M._density(Table(T)) == Table(Density{T})
@test M._density(Table(T)) == Table(Density{<:T})
end

for T in [Finite, Multiclass, OrderedFactor]
@test ==(
M._density(AbstractArray{<:T{2},3}),
AbstractArray{Density{<:T{2}},3}
)
@test ==(
M._density(AbstractArray{T{2},3}),
AbstractArray{Density{T{2}},3}
)
@test M._density(Table(T{2})) == Table(Density{T{2}})
@test M._density(Table(T{2})) == Table(Density{<:T{2}})
end
end

Expand Down
43 changes: 35 additions & 8 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,45 @@ using Tables, Distances, CategoricalArrays, InteractiveUtils
import DataFrames: DataFrame
import Markdown
import OrderedCollections
import Aqua

const M = MLJModelInterface
const FI = M.FullInterface

setlight() = M.set_interface_mode(M.LightInterface())
setfull() = M.set_interface_mode(M.FullInterface())

include("mode.jl")
include("parameter_inspection.jl")
include("data_utils.jl")
include("metadata_utils.jl")
include("model_def.jl")
include("model_api.jl")
include("model_traits.jl")
include("equality.jl")
@testset "mode.jl" begin
include("mode.jl")
end

@testset "parameter_inspection.jl" begin
include("parameter_inspection.jl")
end

@testset "data_utils.jl" begin
include("data_utils.jl")
end

@testset "metadata_utils.jl" begin
include("metadata_utils.jl")
end
@testset "model_def.jl" begin
include("model_def.jl")
end

@testset "model_api.jl" begin
include("model_api.jl")
end

@testset "model_traits.jl" begin
include("model_traits.jl")
end

@testset "equality.jl" begin
include("equality.jl")
end

@testset "aqua.jl" begin
include("aqua.jl")
end
Loading