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 test & fix all ambiguities and unbound args #115

Merged
merged 10 commits into from
Mar 1, 2022
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vscode
*.swp
*.jl.cov
*.jl.*.cov
Expand Down
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ Requires = "0.5.0, 1"
julia = "1"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[targets]
test = ["QuadGK", "SpecialFunctions", "Statistics", "Test", "Unitful"]
test = ["Aqua", "QuadGK", "SpecialFunctions", "Statistics", "Test", "Unitful"]
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Measurements.jl

| **Documentation** | **Build Status** | **Code Coverage** |
|:---------------------------------------:|:-----------------------------------:|:-------------------------------:|
| [![][docs-stable-img]][docs-stable-url] | [![Build Status][gha-img]][gha-url] | [![][coveral-img]][coveral-url] |
| **Documentation** | **Build Status** | **Code Coverage** | **Quality** |
|:---------------------------------------:|:-----------------------------------:|:-------------------------------:|:-----------:|
| [![][docs-stable-img]][docs-stable-url] | [![Build Status][gha-img]][gha-url] | [![][coveral-img]][coveral-url] |[![Aqua QA][aqua-img]](aqua-url)|
| [![][docs-latest-img]][docs-latest-url] | | [![][codecov-img]][codecov-url] |

Introduction
Expand Down Expand Up @@ -219,3 +219,6 @@ is provided in the [`CITATION.bib`](CITATION.bib) file.

[codecov-img]: https://codecov.io/gh/JuliaPhysics/Measurements.jl/branch/master/graph/badge.svg
[codecov-url]: https://codecov.io/gh/JuliaPhysics/Measurements.jl

[aqua-img]: https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg
[aqua-url]: https://github.com/JuliaTesting/Aqua.jl
14 changes: 12 additions & 2 deletions src/Measurements.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,18 @@ function Measurement(val::V, err::E, tag::UInt64,
return Measurement(T(val), T(err), tag, Derivatives{T}(der))
end
Measurement{T}(x::Measurement{S}) where {T,S} = convert(Measurement{T}, x)
Measurement{T}(x::S) where {T,S} = convert(Measurement{T}, x)
Measurement{T}(x::S) where {T,S<:Rational} = convert(Measurement{T}, x)
Measurement{T}(x::S) where {T,S <: Real} = convert(Measurement{T}, x)

# disambiguities
Measurement{T}(x::S) where {T, S<:Rational} = convert(Measurement{T}, x)
Measurement{T}(x::S) where {T, S<:Complex} = convert(Measurement{T}, x)
Measurement{T}(x::S) where {T, S<:Base.TwicePrecision} = convert(Measurement{T}, x)
Measurement{T}(x::S) where {P, T, S<:Rational{P}} = convert(Measurement{T}, x)
Measurement{T}(x::S) where {T, S <: AbstractChar} = convert(Measurement{T}, x)

function Measurement{T}(::S) where {T, S}
throw(ArgumentError("cannot convert `$S` to `Measurement{$T}`"))
end
Comment on lines +72 to +74
Copy link
Member

Choose a reason for hiding this comment

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

I think this method isn't tested?


# Functions to quickly create an empty Derivatives object.
@generated empty_der1(x::Measurement{T}) where {T<:AbstractFloat} = Derivatives{T}()
Expand Down
4 changes: 4 additions & 0 deletions src/comparisons-tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ Base.:(==)(a::Measurement, b::Measurement) = (a.val==b.val && a.err==b.err)
Base.:(==)(a::Measurement, b::Irrational) = false
Base.:(==)(a::Measurement, b::Rational) = (a.val==b && iszero(a.err))
Base.:(==)(a::Measurement, b::Real) = (a.val==b && iszero(a.err))
Base.:(==)(a::Measurement, b::AbstractIrrational) = (a.val==b && iszero(b.err))
Base.:(==)(a::Irrational, b::Measurement) = false
Base.:(==)(a::Rational, b::Measurement) = (a==b.val && iszero(b.err))
Base.:(==)(a::Real, b::Measurement) = (a==b.val && iszero(b.err))
Base.:(==)(a::AbstractIrrational, b::Measurement) = (a==b.val && iszero(b.err))

# Create a hashing function that matches the same behaviour as `==`: only the
# `val` and `err` fields matter.
Expand All @@ -39,8 +41,10 @@ for cmp in (:<, :<=)
Base.$cmp(a::Measurement, b::Measurement) = ($cmp)(a.val, b.val)
Base.$cmp(a::Measurement, b::Rational) = ($cmp)(a.val, b)
Base.$cmp(a::Measurement, b::Real) = ($cmp)(a.val, b)
Base.$cmp(a::Measurement, b::AbstractIrrational) = ($cmp)(a.val, b)
Base.$cmp(a::Rational, b::Measurement) = ($cmp)(a, b.val)
Base.$cmp(a::Real, b::Measurement) = ($cmp)(a, b.val)
Base.$cmp(a::AbstractIrrational, b::Measurement) = ($cmp)(a, b.val)
end
end

Expand Down
12 changes: 12 additions & 0 deletions src/conversions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ Base.convert(::Type{Measurement{T}}, a::Rational{<:Integer}) where {T<:AbstractF
measurement(T(a))::Measurement{T}
Base.convert(::Type{Measurement{T}}, a::Real) where {T<:AbstractFloat} =
measurement(T(a))::Measurement{T}
Base.convert(::Type{Measurement{T}}, a::Base.TwicePrecision) where {T<:AbstractFloat} =
measurement(T(a))::Measurement{T}
Base.convert(::Type{Measurement{T}}, a::AbstractChar) where {T<:AbstractFloat} =
measurement(T(a))::Measurement{T}

function Base.convert(::Type{Measurement{T}}, a::Complex) where {T}
if isreal(a)
measurement(T(real(a)))
else
throw(InexactError(:convert, Measurement{T}, a))
end
end

Base.convert(::Type{Measurement{T}}, a::Measurement{T}) where {T<:AbstractFloat} = a
function Base.convert(::Type{Measurement{T}},
Expand Down
17 changes: 15 additions & 2 deletions src/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ end
# Get the common type parameter of a collection of Measurement objects. The first two
# methods are for the trivial cases of homogeneous tuples and arrays, the last, inefficient,
# method is for inhomogeneous collections (probably the least common case).
gettype(::Tuple{Vararg{Measurement{T}}}) where {T<:AbstractFloat} = T
gettype(::Tuple{Measurement{T}, Vararg{Measurement{T}}}) where {T<:AbstractFloat} = T
gettype(::AbstractArray{Measurement{T}}) where {T<:AbstractFloat} = T
_eltype(::Measurement{T}) where {T<:AbstractFloat} = T
gettype(collection) = promote_type(_eltype.(collection)...)
Expand Down Expand Up @@ -174,6 +174,7 @@ end
# Addition: +
Base.:+(a::Measurement, b::Measurement) = result(a.val + b.val, (1, 1), (a, b))
Base.:+(a::Real, b::Measurement) = result(a + b.val, 1, b)
Base.:+(a::Bool, b::Measurement) = result(a + b.val, 1, b)
Base.:+(a::Measurement, b::Bool) = result(a.val + b, 1, a)
Base.:+(a::Measurement, b::Real) = result(a.val + b, 1, a)

Expand Down Expand Up @@ -685,9 +686,12 @@ Base.sign(a::Measurement) = result(sign(a.val), 0, a)

Base.copysign(a::Measurement, b::Measurement) = ifelse(signbit(a)!=signbit(b), -a, a)
Base.copysign(a::Measurement, b::Real) = ifelse(signbit(a)!=signbit(b), -a, a)
Base.copysign(a::Measurement, b::Unsigned) = ifelse(signbit(a)!=signbit(b), -a, a)

Base.flipsign(a::Measurement, b::Measurement) = ifelse(signbit(b), -a, a)
Base.flipsign(a::Measurement, b::Real) = ifelse(signbit(b), -a, a)
for T in (Signed, Rational, Float32, Float64, Real)
Base.flipsign(a::Measurement, b::Unsigned) = ifelse(signbit(b), -a, a)
for T in (Signed, Unsigned, Rational, Float32, Float64, Real)
@eval Base.copysign(a::$T, b::Measurement) = copysign(a, b.val)
@eval Base.flipsign(a::$T, b::Measurement) = flipsign(a, b.val)
end
Expand Down Expand Up @@ -734,6 +738,15 @@ Base.round(a::Measurement, r::RoundingMode=RoundNearest; kwargs...) =
measurement(round(value(a), r; kwargs...), round(uncertainty(a); kwargs...))
Base.round(::Type{T}, a::Measurement, r::RoundingMode=RoundNearest) where {T<:Integer} =
round(T, a.val, r)

# disambiguities
Base.round(a::Measurement, r::RoundingMode{:NearestTiesAway}; kwargs...) =
measurement(round(value(a), r; kwargs...))
Base.round(a::Measurement, r::RoundingMode{:NearestTiesUp}; kwargs...) =
measurement(round(value(a), r; kwargs...))
Base.round(::Type{T}, a::Measurement, r::RoundingMode{:ToZero}) where {T<:Integer} =
measurement(round(T, value(a), r))

Base.floor(a::Measurement) = measurement(floor(a.val))
Base.floor(::Type{T}, a::Measurement) where {T<:Integer} = floor(T, a.val)
Base.ceil(a::Measurement) = measurement(ceil(a.val))
Expand Down
8 changes: 7 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Measurements, SpecialFunctions, QuadGK, Calculus
using Test, LinearAlgebra, Statistics, Unitful, Printf
using Test, LinearAlgebra, Statistics, Unitful, Printf, Aqua
Aqua.test_all(Measurements)

import Base: isapprox
import Measurements: value, uncertainty
Expand Down Expand Up @@ -104,6 +105,11 @@ end
Measurement{Float64}
@test promote_type(Measurement{BigFloat}, Measurement{Float64}) ==
Measurement{BigFloat}

@test convert(Measurement{Float64}, 1+0im) ≈ 1.0±0.0
@test_throws InexactError convert(Measurement{Float64}, 1+1im)
@test convert(Measurement{Float64}, Base.TwicePrecision(1.0, 0.0)) ≈ 1.0±0.0
@test convert(Measurement{Float64}, 'a') ≈ Float64('a') ± 0.0
end

@testset "Comparisons and Tests" begin
Expand Down