Skip to content

Commit

Permalink
Use methodswith to determine is_transformable (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
Glenn Moynihan authored Apr 20, 2021
1 parent eb9daee commit 5da6ca5
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 20 deletions.
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name = "FeatureTransforms"
uuid = "8fd68953-04b8-4117-ac19-158bf6de9782"
authors = ["Invenia Technical Computing Corporation"]
version = "0.3.3"
version = "0.3.4"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
NamedDims = "356022a1-0364-5f58-8944-0da4b18d706f"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
Expand Down
17 changes: 11 additions & 6 deletions src/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ Each fake [`Transform`](@ref) has different a different `cardinality`: `OneToOne
they only need to test against these 4 fakes to guarantee their type can support any
[`Transform`](@ref) in the package.
Similarly, `is_transformable` is used to check that the output of a `transform` pipeline is
a transformable type.
Similarly, [`is_transformable`](@ref) is used to check that the output of a `transform`
pipeline is a transformable type.
"""

module TestUtils

using ..FeatureTransforms
using ..FeatureTransforms: OneToOne, OneToMany, ManyToOne, ManyToMany
using InteractiveUtils: methodswith
using Tables

export FakeOneToOneTransform, FakeOneToManyTransform
Expand Down Expand Up @@ -56,10 +57,14 @@ end
is_transformable(x)
Determine if `x` is both a valid input and output of any [`Transform`](@ref), i.e. that it
follows the [`transform`](@ref) interface.
Currently, all subtypes of `Table`s and `AbstractArray`s are transformable.
has an `apply` method defined and therefore follows the [`transform`](@ref) interface.
"""
is_transformable(::AbstractArray) = true
is_transformable(x) = Tables.istable(x)
function is_transformable(T::Type)
Tables.istable(T) && return true # cannot directly check against the method with no type
return !isempty(methodswith(T, FeatureTransforms.apply; supertypes=true))
end
is_transformable(::T) where T = is_transformable(T)
# Need this to get around using methodswith, which would otherwise return true
is_transformable(::Type{<:Transform}) = false

end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ using Documenter: doctest
using FeatureTransforms
using FeatureTransforms: _periodic
using FeatureTransforms: cardinality, OneToOne, OneToMany, ManyToOne, ManyToMany
using Tables: rowtable, columntable
using Test
using TimeZones

Expand Down
38 changes: 25 additions & 13 deletions test/test_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,31 @@ using FeatureTransforms.TestUtils

@testset "is_transformable" begin

# Test that AbstractArrays and Tables are transformable
@test is_transformable([1, 2, 3, 4, 5])
@test is_transformable([1 2 3; 4 5 6])
@test is_transformable(AxisArray([1 2 3; 4 5 6], foo=["a", "b"], bar=["x", "y", "z"]))
@test is_transformable(KeyedArray([1 2 3; 4 5 6], foo=["a", "b"], bar=["x", "y", "z"]))
@test is_transformable((a = [1, 2, 3], b = [4, 5, 6]))
@test is_transformable(DataFrame(:a => [1, 2, 3], :b => [4, 5, 6]))

# Test types that are not transformable
@test is_transformable(1) == false
@test is_transformable("string") == false
@test is_transformable(true) == false
@test is_transformable(Dict(2 => 3)) == false
@testset "$(typeof(x)) is transformable" for x in (
[1, 2, 3, 4, 5],
[1 2 3; 4 5 6],
AxisArray([1 2 3; 4 5 6], foo=["a", "b"], bar=["x", "y", "z"]),
KeyedArray([1 2 3; 4 5 6], foo=["a", "b"], bar=["x", "y", "z"]),
rowtable((a=[1, 2, 3], b=[4, 5, 6])),
columntable((a=[1, 2, 3], b=[4, 5, 6])),
Dict(:a => [1, 2, 3], :b => [4, 5, 6]),
DataFrame(:a => [1, 2, 3], :b => [4, 5, 6]),
)
@test is_transformable(x)
@test is_transformable(typeof(x))
end

@testset "$(typeof(x)) is not transformable" for x in (
1,
"string",
true,
([1, 2, 3], [4, 5, 6]),
Dict(:a=>1, :b=>2),
FakeOneToOneTransform(),
)
@test !is_transformable(x)
@test !is_transformable(typeof(x))
end
end

end

2 comments on commit 5da6ca5

@glennmoy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/34750

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.3.4 -m "<description of version>" 5da6ca58fc2fb3969431ef1df6fcc9d22a09f24e
git push origin v0.3.4

Please sign in to comment.