diff --git a/README.md b/README.md index c65c8da8c..bb98344c1 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,12 @@ Currently, the `@compat` macro supports the following syntaxes: `Sys.islinux`, `Sys.isunix`, and `Sys.iswindows`, respectively. These are available in the `Compat.Sys` submodule. ([#22182]) +* `readstring` is replaced by methods of `read`. ([#22864]) + + `read(::IO, ::Type{String})`, `read(::AbstractString, ::Type{String})`, + and `read(::Cmd, ::Type{String})` are defined for 0.6 and below. + + ## New macros * `@__DIR__` has been added ([#18380]) @@ -183,6 +189,8 @@ Currently, the `@compat` macro supports the following syntaxes: vectorized function have migrated. These macros will be dropped when the support for `0.6` is dropped from `Compat`. +* `@nospecialize` has been added ([#22666]). + ## Other changes * On versions of Julia that do not contain a Base.Threads module, Compat defines a Threads module containing a no-op `@threads` macro. @@ -305,3 +313,5 @@ includes this fix. Find the minimum version from there. [#22475]: https://github.com/JuliaLang/julia/issues/22475 [#22633]: https://github.com/JuliaLang/julia/issues/22633 [#22629]: https://github.com/JuliaLang/julia/issues/22629 +[#22666]: https://github.com/JuliaLang/julia/pull/22666 +[#22864]: https://github.com/JuliaLang/julia/pull/22864 diff --git a/src/Compat.jl b/src/Compat.jl index c0c82d441..a8e66026f 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -4,6 +4,18 @@ module Compat using Base.Meta +if !isdefined(Base, Symbol("@nospecialize")) + # 0.7 + macro nospecialize(arg) + earg = esc(arg) + if isa(arg, Symbol) + return :($earg::ANY) + end + return earg + end + export @nospecialize +end + """Get just the function part of a function declaration.""" withincurly(ex) = isexpr(ex, :curly) ? ex.args[1] : ex @@ -11,119 +23,12 @@ if VERSION < v"0.6.0-dev.2043" Base.take!(t::Task) = consume(t) end -function rewrite_show(ex) - if isexpr(ex, :call) - Expr(:call, rewrite_show(ex.args[1]), ex.args[2:end]...) - elseif isexpr(ex, :curly) - Expr(:curly, rewrite_show(ex.args[1]), ex.args[2:end]...) - else - :(Base.writemime) - end -end - -function rewrite_dict(ex) - length(ex.args) == 1 && return ex - - f = ex.args[1] - if isexpr(f, :curly) - newex = Expr(:typed_dict, :($(f.args[2])=>$(f.args[3]))) - else - newex = Expr(:dict) - end - - for i = 2:length(ex.args) - pair = ex.args[i] - !isexpr(pair, :(=>)) && return ex - push!(newex.args, pair) - end - newex -end - -function rewrite_ordereddict(ex) - length(ex.args) == 1 && return ex - - f = ex.args[1] - newex = Expr(:call, f, :[]) - - for i = 2:length(ex.args) - pair = ex.args[i] - !isexpr(pair, :(=>)) && return ex - push!(newex.args[2].args, Expr(:tuple, pair.args...)) - end - - newex -end - -# rewrites all subexpressions of the form `a => b` to `(a, b)` -function rewrite_pairs_to_tuples!(expr::Expr) - if expr.head == :(=>) - expr.head = :tuple - end - for subexpr in expr.args - isa(subexpr, Expr) && rewrite_pairs_to_tuples!(subexpr) - end - return expr -end - -function is_quote_symbol(ex::ANY, val::Symbol) - if isa(ex, QuoteNode) - return (ex::QuoteNode).value === val - elseif isa(ex, Expr) - ex = ex::Expr - return ex.head === :quote && length(ex.args) == 1 && ex.args[1] === val - end - return false -end - is_index_style(ex::Expr) = ex == :(Compat.IndexStyle) || ex == :(Base.IndexStyle) || (ex.head == :(.) && (ex.args[1] == :Compat || ex.args[1] == :Base) && ex.args[2] == Expr(:quote, :IndexStyle)) is_index_style(arg) = false -# rewrites accesses to IOContext dicts -function rewrite_iocontext!(expr::Expr) - args = expr.args - nargs = length(args) - if nargs == 4 && expr.head === :call && args[1] === :get && args[4] === false - key = args[3] - if is_quote_symbol(key, :limit) || is_quote_symbol(key, :compact) - if VERSION >= v"0.5.0-dev+1936" && VERSION < v"0.5.0-dev+4305" - args[1] = :(Base.limit_output) - deleteat!(args, 3:4) - elseif VERSION < v"0.5.0-dev+1936" - expr.head = :quote - args[1] = false - deleteat!(args, 3:4) - end - elseif is_quote_symbol(key, :multiline) - if VERSION < v"0.5.0-dev+4305" - expr.head = :quote - args[1] = false - deleteat!(args, 3:4) - end - end - end -end - -# JuliaLang/julia#10543 -if !isdefined(Base, :tryparse) - function tryparse{T}(::Type{T}, args...) - try - Nullable(Base.parse(T, args...)) - catch - Nullable{T}() - end - end -end - -import Base.unsafe_convert - -function new_style_call_overload(ex::Expr) - Base.depwarn("new_style_call_overload is deprecated.", :new_style_call_overload) - false -end - istopsymbol(ex, mod, sym) = ex in (sym, Expr(:(.), mod, Expr(:quote, sym))) if VERSION < v"0.6.0-dev.2782" @@ -145,18 +50,13 @@ function _compat(ex::Expr) end elseif ex.head === :curly f = ex.args[1] - if ex == :(Ptr{Void}) - # Do not change Ptr{Void} to Ptr{Nothing}: 0.4.0-dev+768 - return ex - elseif VERSION < v"0.6.0-dev.2575" #20414 + if VERSION < v"0.6.0-dev.2575" #20414 ex = Expr(:curly, map(a -> isexpr(a, :call, 2) && a.args[1] == :(<:) ? :($TypeVar($(QuoteNode(gensym(:T))), $(a.args[2]), false)) : isexpr(a, :call, 2) && a.args[1] == :(>:) ? :($TypeVar($(QuoteNode(gensym(:T))), $(a.args[2]), $Any, false)) : a, ex.args)...) end - elseif ex.head === :macrocall - f = ex.args[1] elseif ex.head === :quote && isa(ex.args[1], Symbol) # Passthrough return ex @@ -240,98 +140,7 @@ macro compat(ex...) esc(_compat(ex[1])) end -export @compat, @inline, @noinline - -import Base.@irrational - -import Base: remotecall, remotecall_fetch, remotecall_wait, remote_do - -import Base.Filesystem - -if !isdefined(Base, :istextmime) - export istextmime - istextmime(m::@compat(Union{MIME,AbstractString})) = istext(m) -end - -function primarytype(t::ANY) - tn = t.name - if isdefined(tn, :primary) - return tn.primary - else - return tn.wrapper - end -end - -if !isdefined(Base, :Threads) - @eval module Threads - macro threads(expr) - return esc(expr) - end - threadid() = 1 - nthreads() = 1 - export @threads, threadid, nthreads - end - export Threads -end - -if !isdefined(Base, :normalize) - function normalize!(v::AbstractVector, p::Real=2) - nrm = norm(v, p) - __normalize!(v, nrm) - end - - @inline function __normalize!(v::AbstractVector, nrm::AbstractFloat) - #The largest positive floating point number whose inverse is less than - #infinity - δ = inv(prevfloat(typemax(nrm))) - if nrm ≥ δ #Safe to multiply with inverse - invnrm = inv(nrm) - scale!(v, invnrm) - else # scale elements to avoid overflow - εδ = eps(one(nrm))/δ - scale!(v, εδ) - scale!(v, inv(nrm*εδ)) - end - v - end - - copy_oftype{T,N}(A::AbstractArray{T,N}, ::Type{T}) = copy(A) - copy_oftype{T,N,S}(A::AbstractArray{T,N}, ::Type{S}) = convert(AbstractArray{S,N}, A) - - function normalize(v::AbstractVector, p::Real = 2) - nrm = norm(v, p) - if !isempty(v) - vv = copy_oftype(v, typeof(v[1]/nrm)) - return __normalize!(vv, nrm) - else - T = typeof(zero(eltype(v))/nrm) - return T[] - end - end - - export normalize, normalize! -end - -import Base.AsyncCondition -import Base: srand, rand, rand! - - -if !isdefined(Base, :pointer_to_string) - - function pointer_to_string(p::Ptr{UInt8}, len::Integer, own::Bool=false) - a = ccall(:jl_ptr_to_array_1d, Vector{UInt8}, - (Any, Ptr{UInt8}, Csize_t, Cint), Vector{UInt8}, p, len, own) - ccall(:jl_array_to_string, Ref{String}, (Any,), a) - end - - pointer_to_string(p::Ptr{UInt8}, own::Bool=false) = - pointer_to_string(p, ccall(:strlen, Csize_t, (Cstring,), p), own) - -end - -import Base.promote_eltype_op - -import Base.LinAlg.BLAS.@blasfunc +export @compat import Base: redirect_stdin, redirect_stdout, redirect_stderr if VERSION < v"0.6.0-dev.374" @@ -412,6 +221,7 @@ end # julia#18977 if !isdefined(Base, :xor) + # 0.6 const xor = $ const ⊻ = xor export xor, ⊻ @@ -419,6 +229,7 @@ end # julia#19246 if !isdefined(Base, :numerator) + # 0.6 const numerator = num const denominator = den export numerator, denominator @@ -426,6 +237,7 @@ end # julia #19950 if !isdefined(Base, :iszero) + # 0.6 iszero(x) = x == zero(x) iszero(x::Number) = x == 0 iszero(x::AbstractArray) = all(iszero, x) @@ -434,6 +246,7 @@ end # julia #20407 if !isdefined(Base, :(>:)) + # 0.6 const >: = let _issupertype(a::ANY, b::ANY) = issubtype(b, a) end @@ -568,6 +381,7 @@ end # https://github.com/JuliaLang/julia/pull/22064 if !isdefined(Base, Symbol("@__MODULE__")) + # 0.7 export @__MODULE__ macro __MODULE__() return current_module() @@ -582,6 +396,7 @@ end # https://github.com/JuliaLang/julia/pull/19784 if isdefined(Base, :invokelatest) + # 0.6 import Base.invokelatest else invokelatest(f, args...) = eval(current_module(), Expr(:call, f, map(QuoteNode, args)...)) @@ -662,6 +477,12 @@ module Sys end end +if VERSION < v"0.7.0-DEV.1053" + Base.read(obj::IO, ::Type{String}) = readstring(obj) + Base.read(obj::AbstractString, ::Type{String}) = readstring(obj) + Base.read(obj::Cmd, ::Type{String}) = readstring(obj) +end + include("deprecated.jl") end # module Compat diff --git a/src/deprecated.jl b/src/deprecated.jl index 36b54ec84..a38b450e4 100644 --- a/src/deprecated.jl +++ b/src/deprecated.jl @@ -143,6 +143,15 @@ end using .CompatCartesian export @ngenerate, @nsplat +function primarytype(@nospecialize(t)) + tn = t.name + if isdefined(tn, :primary) + return tn.primary + else + return tn.wrapper + end +end + export @functorize macro functorize(f) code = f === :scalarmax ? :(Base.scalarmax) : @@ -160,13 +169,22 @@ if VERSION >= v"0.6.0" Base.@deprecate_binding KERNEL Sys.KERNEL Base.@deprecate_binding UTF8String Core.String Base.@deprecate_binding ASCIIString Core.String + Base.@deprecate_binding unsafe_convert Base.unsafe_convert + Base.@deprecate_binding remote_do Base.remote_do + Base.@deprecate_binding Filesystem Base.Filesystem + Base.@deprecate_binding AsyncCondition Base.AsyncCondition + Base.@deprecate_binding promote_eltype_op Base.promote_eltype_op + @eval Base.@deprecate_binding $(Symbol("@irrational")) Base.$(Symbol("@irrational")) + @eval Base.@deprecate_binding $(Symbol("@blasfunc")) Base.LinAlg.BLAS.$(Symbol("@blasfunc")) else const KERNEL = Sys.KERNEL const UTF8String = Core.String const ASCIIString = Core.String + import Base.unsafe_convert + import Base.remote_do + import Base.Filesystem + import Base.AsyncCondition + import Base.promote_eltype_op + import Base.@irrational + import Base.LinAlg.BLAS.@blasfunc end - -# More things that could be removed in Compat.jl -# - new_style_call_overload -# - import Base.Filesystem -# - import Base.LinAlg.BLAS.@blasfunc diff --git a/test/deprecated.jl b/test/deprecated.jl index 32ba79f8f..d6cfa38ab 100644 --- a/test/deprecated.jl +++ b/test/deprecated.jl @@ -7,46 +7,11 @@ d[1] = 1 @test Compat.@Dict(1 => 1) == d @test Compat.@Dict(1 => v) == d -@test typeof(@compat(Dict(1 => 1))) == Dict{Int,Int} -@test @compat(Dict(1 => 1)) == d -@test @compat(Dict(1 => v)) == d - ad = Dict{Any,Any}() ad[1] = 1 @test Compat.@AnyDict(1 => 1) == ad @test Compat.@AnyDict(1 => v) == ad -@test typeof(@compat(Dict{Any,Any}(1 => 1))) == Dict{Any,Any} -@test @compat(Dict{Any,Any}(1 => 1)) == ad -@test @compat(Dict{Any,Any}(1 => v)) == ad - -td = Dict{Int,Float64}() -td[1] = 1.0 - -@test typeof(@compat(Dict{Int,Float64}(1 => 1))) == Dict{Int,Float64} -@test @compat(Dict{Int,Float64}(1 => 1)) == td -@test @compat(Dict{Int,Float64}(1 => v)) == td - -@test @compat(Dict()) == Dict() -@test @compat(Dict{Any,Any}()) == Dict{Any,Any}() -@test @compat(Dict([(1, 1)])) == d -@test @compat(Dict(:Void => :Nothing)) == Dict([(:Void, :Nothing)]) - -d2 = Dict{Symbol,Dict{Symbol,Int}}() -d2[:a] = Dict{Symbol,Int}() -d2[:a][:b] = 1 -@test @compat(Dict(:a => Dict(:b => 1))) == d2 - -d = Dict(zip([1, 2], [3, 4])) -@test d == @compat Dict(1=>3, 2=>4) - -@compat function f() - a = :a - b = Dict(:b => 1) - Dict(a => b) -end -@test f() == d2 - module CartesianTest using Base.Cartesian, Compat @ngenerate N NTuple{N,Int} function f(X::NTuple{N,Int}...) @@ -64,12 +29,81 @@ end @test String == @compat(Union{Compat.UTF8String,Compat.ASCIIString}) -let x = fill!(StringVector(5), 0x61) - @test pointer(x) == pointer(Compat.UTF8String(x)) -end - -foostring(::String) = 1 -@test foostring("hello") == 1 -@test foostring("λ") == 1 @test isa("hello", Compat.ASCIIString) @test isa("λ", Compat.UTF8String) + +# @functorize +function checkfunc(Fun, func) + @eval @test @functorize($(func)) === Base.$(func) +end + +for (Fun, func) in [(:IdFun, :identity), + (:AbsFun, :abs), + (:Abs2Fun, :abs2), + (:ExpFun, :exp), + (:LogFun, :log), + (:ConjFun, :conj)] + begin + if isdefined(Base, func) + checkfunc(Fun, func) + a = rand(1:10, 10) + @eval @test mapreduce($(func), +, $(a)) == mapreduce(@functorize($(func)), +, $(a)) + end + end +end + +dotfunctors = [(:DotAddFun, :.+), + (:DotSubFun, :.-), + (:DotMulFun, :.*), + (:DotRDivFun, :./), + (:DotIDivFun, Symbol(".÷")), + (:DotRemFun, :.%), + (:DotLSFun, :.<<), + (:DotRSFun, :.>>)] + +functors = [(:AndFun, :&), + (:OrFun, :|), + (:XorFun, :⊻), + (:AddFun, :+), + (:SubFun, :-), + (:MulFun, :*), + (:RDivFun, :/), + (:LDivFun, :\ ), + (:IDivFun, :div), + (:ModFun, :mod), + (:RemFun, :rem), + (:PowFun, :^), + (:MaxFun, :scalarmax), + (:MinFun, :scalarmin), + (:LessFun, :<), + (:MoreFun, :>), + (:ElementwiseMaxFun, :max), + (:ElementwiseMinFun, :min)] + +# since #17623, dot functions are no longer function objects +append!(functors, dotfunctors) + +for (Fun, func) in functors + begin + if isdefined(Base, func) + checkfunc(Fun, func) + a = rand(1:10, 10) + @eval @test mapreduce(identity, Base.$(func), $(a)) == mapreduce(identity, @functorize($(func)), $(a)) + end + end +end + +@test @functorize(complex) === complex +@test @functorize(dot) === dot +let a = rand(1:10, 10) + @test mapreduce(identity, dot, a) == mapreduce(identity, @functorize(dot), a) +end + +@test isa(@functorize(centralizedabs2fun)(1), @functorize(centralizedabs2fun)) +@test isa(@functorize(centralizedabs2fun)(1.0), @functorize(centralizedabs2fun)) +let a = rand(1:10, 10) + @eval @test mapreduce(x -> abs2(x - 1), +, $(a)) == mapreduce(@functorize(centralizedabs2fun)(1), +, $(a)) +end + +@test Compat.promote_eltype_op(@functorize(+), ones(2,2), 1) === Float64 +@test Compat.promote_eltype_op(@functorize(*), ones(Int, 2), zeros(Int16,2)) === Int diff --git a/test/runtests.jl b/test/runtests.jl index 45aed189f..f4085757f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,1355 +1,17 @@ using Compat -import Compat.String -import Compat.view -@compat import Base.show using Base.Test -v = 1 -@test_throws AssertionError @assert(v < 1) - -eval(Expr(:type, true, :TestCustomShowType, quote end)) -@compat function show(io::IO, ::MIME"text/plain", ::TestCustomShowType) - print(io, "MyTestCustomShowType") -end -myio = IOBuffer() -display(TextDisplay(myio), MIME"text/plain"(), TestCustomShowType()) -@test @compat String(myio) == "MyTestCustomShowType" - -eval(Expr(:type, true, :TestCustomShowType2, quote end)) -@compat Base.show(io::IO, ::MIME"text/plain", ::TestCustomShowType2) = print(io, "MyTestCustomShowType2") -myio = IOBuffer() -display(TextDisplay(myio), MIME"text/plain"(), TestCustomShowType2()) -@test @compat String(myio) == "MyTestCustomShowType2" - -eval(Expr(:type, true, :TestCustomShowType3, quote end)) -@compat show(io::IO, ::TestCustomShowType3) = print(io, "2-Argument-show") -myio = IOBuffer() -display(TextDisplay(myio), TestCustomShowType3()) -@test @compat String(myio) == "2-Argument-show" - -eval(Expr(:type, false, :(ParameterizedShowType{T}), quote - _::T -end)) -myio = IOBuffer() -@compat show{T}(io::IO, ::MIME"text/html", ::ParameterizedShowType{T}) = - print(io, "::", T, "") -@compat show(myio, MIME("text/html"), ParameterizedShowType(0.0)) -@test @compat String(myio) == "::Float64" - -d = Dict(zip([1, 2], [3, 4])) -ns = length(d.slots) -@test length(sizehint!(d, ns + 1).slots) > ns - -@test @compat split("a,b,,c", ',', limit=2) == ["a", "b,,c"] -@test @compat split("a,b,,c", ',', limit=2,keep=true) == ["a", "b,,c"] -@test @compat split("a,b,,c", ',', keep=false) == ["a", "b", "c"] -@test @compat split("a,b,,c", ',', keep=true) == ["a", "b", "", "c"] - -@test @compat rsplit("a,b,,c", ',', limit=2) == ["a,b,", "c"] -@test @compat rsplit("a,b,,c", ',', limit=2,keep=true) == ["a,b,", "c"] -@test @compat rsplit("a,b,,c", ',', keep=false) == ["a", "b", "c"] -@test @compat rsplit("a,b,,c", ',', keep=true) == ["a", "b", "", "c"] - -if VERSION < v"0.4.0-dev+1387" - @test isdefined(Main, :AbstractString) -end - -@test round(Int, 3//4) == 1 -@test round(Int, 1) == 1 -@test round(Int, 1.1) == 1 -@test ceil(Int, 1) == 1 -@test ceil(Int, 1.1) == 2 -@test floor(Int, 1) == 1 -@test floor(Int, 1.1) == 1 -@test trunc(Int, 1) == 1 -@test trunc(Int, 1.1) == 1 - -if VERSION < v"0.6.0-dev.1825" - @test round(Int, [1, 1]) == [1, 1] - @test round(Int, [1.1, 1.1]) == [1, 1] - @test round(Int, [1 1]) == [1 1] - @test round(Int, [1.1 1.1]) == [1 1] - @test round(Int, fill(1.1, 2, 3, 4)) == fill(1, 2, 3, 4) - @test ceil(Int, [1, 1]) == [1, 1] - @test ceil(Int, [1.1, 1.1]) == [2, 2] - @test ceil(Int, [1 1]) == [1 1] - @test ceil(Int, [1.1 1.1]) == [2 2] - @test ceil(Int, fill(1.1, 2, 3, 4)) == fill(2, 2, 3, 4) - @test floor(Int, [1, 1]) == [1, 1] - @test floor(Int, [1.1, 1.1]) == [1, 1] - @test floor(Int, [1 1]) == [1 1] - @test floor(Int, [1.1 1.1]) == [1 1] - @test floor(Int, fill(1.1, 2, 3, 4)) == fill(1, 2, 3, 4) - @test trunc(Int, [1, 1]) == [1, 1] - @test trunc(Int, [1.1, 1.1]) == [1, 1] - @test trunc(Int, [1 1]) == [1 1] - @test trunc(Int, [1.1 1.1]) == [1 1] - @test trunc(Int, fill(1.1, 2, 3, 4)) == fill(1, 2, 3, 4) -end - -# n % Type -for T in Any[Int16, Int32, UInt32, Int64, UInt64] - if !(T <: Unsigned) - @test convert(T, -200) % Int8 === @compat Int8(56) - @test convert(T, -200) % UInt8 === 0x38 - @test convert(T, -300) % Int8 === @compat Int8(-44) - @test convert(T, -300) % UInt8 === 0xd4 - @test convert(T, -128) % Int8 === @compat Int8(-128) - @test convert(T, -128) % UInt8 === 0x80 - end - @test convert(T, 127) % Int8 === @compat Int8(127) - @test convert(T, 127) % UInt8 === 0x7f - @test convert(T, 128) % Int8 === @compat Int8(-128) - @test convert(T, 128) % UInt8 === 0x80 - @test convert(T, 200) % Int8 === @compat Int8(-56) - @test convert(T, 300) % UInt8 === 0x2c -end - -@test IPv4("1.2.3.4") == ip"1.2.3.4" -@test IPv6("2001:1:2:3::1") == ip"2001:1:2:3::1" -@test isless(ip"1.2.3.4", ip"1.2.3.5") - -@test startswith("abcdef","abc") == true -@test startswith("abcdef","def") == false - -@test size(bitrand(3, 4)) == (3, 4) -@test size(bitrand((3, 4))) == (3, 4) -@test size(bitrand(MersenneTwister(0), 3, 4)) == (3, 4) -@test size(bitrand(MersenneTwister(0), (3, 4))) == (3, 4) -@test rand(Bool) in [false, true] - -rng = MersenneTwister(0) -srand() -srand(rng, UInt32[0,0]) -srand(rng) -for Tr in (Int8,UInt8,Int32,UInt32,Int64,UInt64,Int128,UInt128,Float16,Float32,Float64) - for T in (Tr, Complex{Tr}) - @test isa(rand(rng, T), T) - let x = rand(rng, T, 3,4) - @test isa(x, Array{T,2}) - @test size(x) == (3,4) - rand!(rng, x) - end - end -end -srand(rng, 0) -let x = rand(rng, Int64, 3,4) - srand(rng, 0) - @test x == rand(rng, Int64, (3,4)) -end - -extrapath = Compat.Sys.iswindows() ? joinpath(JULIA_HOME,"..","Git","usr","bin")*";" : "" -@compat withenv("PATH" => extrapath * ENV["PATH"]) do - cmd1 = pipeline(`echo hello`, `sort`) - cmd2 = pipeline(`true`, `true`) - if Compat.Sys.iswindows() - try # use busybox-w32 - success(`busybox`) - cmd1 = pipeline(`busybox echo hello`, `busybox sort`) - cmd2 = pipeline(`busybox true`, `busybox true`) - end - end - @test readstring(cmd1) == "hello\n" - @test success(cmd2) -end - -let convert_funcs_and_types = - ((:integer, :Integer), (:signed, :Signed), (:unsigned, :Unsigned), - (:int, :Int), (:int8, :Int8), (:int16, :Int16), (:int32, :Int32), - (:int64, :Int64), (:int128, :Int128), (:uint, :UInt), - (:uint8, :UInt8), (:uint16, :UInt16), (:uint32, :UInt32), - (:uint64, :UInt64), (:uint128, :UInt128), - (:float16, :Float16), (:float32, :Float32), (:float64, :Float64), - (:complex32,:Complex32), (:complex64,:Complex64),(:complex128,:Complex128), - (:char,:Char)) - - for (df,t) in convert_funcs_and_types - x = @compat UInt8(10) - r1 = eval(:(@compat($t($x)))) - ty = eval(t) - if ty.abstract - @test issubtype(typeof(r1),ty) - else - @test typeof(r1) === ty - end - if VERSION < v"0.4.0-dev+3732" - r2 = eval(df)(x) - @test r1 === r2 - if t === :Signed || t === :Complex32 - continue - end - x = fill(x, 10) - r1 = eval(:(@compat map($t, $x))) - r2 = eval(df)(x) - @test r1 == r2 - @test typeof(r1) === typeof(r2) - end - end - @test (@compat Bool(1)) - @test !(@compat Bool(0)) - - # issue #54 - c = @compat Complex128(1) - @test c.re == 1 - @test c.im == 0 - - c = @compat Complex128(1,2) - @test c.re == 1 - @test c.im == 2 - - c = @compat Complex128(1+2im) - @test c.re == 1 - @test c.im == 2 -end - -eval(Expr(:type, true, :Test3609, quote - a - b -end)) - -if VERSION < v"0.4.0-dev+3609" - let v = Test3609(1,2) - @test fieldnames(Test3609) == fieldnames(v) == Symbol[:a, :b] - end -end - -@test fieldoffset(Complex{Float32}, 2) === @compat UInt(4) - -@test parse(Int8, '9') == convert(Int8, 9) -@test parse(Int, 'a', 16) == 10 -@test parse(Int, "200") == 200 -@test parse(Int16, "1101", 2) == convert(Int16, 13) -@test parse(Float64, "222") == 222.0 -@test parse(Float32, "1.1") == convert(Float32, 1.1) -@test parse(BigFloat, "1.125") == convert(BigFloat, 1.125) -@test isa(tryparse(Float32, "1.1"), Nullable) -@test get(tryparse(Float32, "1.1")) == 1.1f0 -@test isa(tryparse(Float32, "a"), Nullable{Float32}) -@test isa(tryparse(Float64, "1.1"), Nullable) -@test get(tryparse(Float64, "1.1")) == 1.1 -@test isa(tryparse(Float64, "a"), Nullable{Float64}) -@test get(tryparse(Int32, "1")) == 1 -@test isa(tryparse(Int32, "a"), Nullable{Int32}) -@test get(tryparse(Int64, "1")) == 1 -@test isa(tryparse(Int64, "a"), Nullable{Int64}) - -@test_throws ArgumentError tryparse(Int32, "0", 1) -@test tryparse(Int32, "12345", 16) === Nullable{Int32}(@compat Int32(74565)) -@test tryparse(Int64, "12345", 10) === Nullable{Int64}(@compat Int64(12345)) -@test tryparse(Int64, "12345", 6) === Nullable{Int64}(@compat Int64(1865)) -@test isnull(tryparse(Int64, "nonsense", 10)) -@test tryparse(Int64, "nonsense", 36) === Nullable{Int64}(@compat Int64(1856056985582)) - -# Make sure exports from Libc and Libdl are defined -for x in [:strftime,:systemsleep,:getpid,:FILE,:malloc,:flush_cstdio,:realloc,:strptime,:Libc,:errno,:TmStruct,:calloc,:time,:strerror,:gethostname,:free] - getfield(Libc, x) -end -for x in [:RTLD_LOCAL,:RTLD_GLOBAL,:find_library,:dlsym,:RTLD_LAZY,:RTLD_NODELETE,:DL_LOAD_PATH,:RTLD_NOW,:Libdl,:dlext,:dlsym_e,:RTLD_FIRST,:dlopen,:dllist,:dlpath,:RTLD_NOLOAD,:dlclose,:dlopen_e,:RTLD_DEEPBIND] - getfield(Libdl, x) -end - -# Test unsafe_convert -eval(Expr(:type, true, :Au_c, quote end)) -x = "abc" -@test @compat String(unsafe_string(Compat.unsafe_convert(Ptr{UInt8}, x))) == x -Compat.unsafe_convert(::Ptr{Au_c}, x) = x -@test Compat.unsafe_convert(pointer([Au_c()]), 1) == 1 - -# Test Ptr{T}(0) -@test @compat(Ptr{Int}(0)) == C_NULL - -# Test Tuple{} syntax -if VERSION < v"0.4.0-dev+4319" - @test @compat Tuple{1} == (1,) - @test @compat Tuple{:a, :b} == (:a, :b) - @test @compat Tuple{:a, Tuple{:b}} == (:a, (:b,)) - @test @compat Tuple{:a, Tuple{:b, :c}} == (:a, (:b, :c)) - @test @compat Tuple{Int} == (Int,) - @test @compat Tuple{Int, Float64} == (Int, Float64) - @test @compat Tuple{Int, Tuple{Float64}} == (Int, (Float64,)) - @test @compat Tuple{Int, Tuple{Float64, Char}} == (Int, (Float64, Char)) - @test @compat Tuple{Int, Vararg{Float64}} == (Int, Float64...) - # Issue 81 - a81 = [Int, Int] - b81 = (Int, Int) - @test @compat Tuple{a81..., Vararg{Float64}} == (Int, Int, Float64...) - @test @compat Tuple{b81..., Vararg{Float64}} == (Int, Int, Float64...) -end - -# Ensure eachindex iterates over the whole array -let A, B, s - A = reshape(1:20,4,5) - s = 0 - for i in eachindex(A) - s += A[i] - end - @test s == 210 - B = sparse(A) - s = 0 - for i in eachindex(B) - s += B[i] - end - @test s == 210 -end - -let - d = @compat Dict(1=>2, 3=>4) - d[5] = 6 - val = 0 - for I in eachindex(d) - val += d[I] - end - @test val == 12 - empty!(d) - for I in eachindex(d) - val += d[I] - end - @test val == 12 -end - -# findlast, findprev -let a = [0,1,2,3,0,1,2,3] - @test findlast(a) == 8 - @test findlast(a.==0) == 5 - @test findlast(a.==5) == 0 - @test findlast([1,2,4,1,2,3,4], 3) == 6 - @test findlast(isodd, [2,4,6,3,9,2,0]) == 5 - @test findlast(isodd, [2,4,6,2,0]) == 0 - @test findprev(a,4) == 4 - @test findprev(a,5) == 4 - @test findprev(a,1) == 0 - @test findprev(a,1,4) == 2 - @test findprev(a,1,8) == 6 - @test findprev(isodd, [2,4,5,3,9,2,0], 7) == 5 - @test findprev(isodd, [2,4,5,3,9,2,0], 2) == 0 -end - -# isdiag -@test isdiag(diagm([1,2,3,4])) -@test !isdiag([1 2; 3 4]) -@test isdiag(5) - -# keytype & valtype -if VERSION < v"0.4.0-dev+4502" - @test keytype(@compat(Dict(1 => 1.))) == Int - @test valtype(@compat(Dict(1 => 1.))) == Float64 -end - -# Val -begin - local firstlast - firstlast(::Val{true}) = "First" - firstlast(::Val{false}) = "Last" - - @test firstlast(Val(true)) == "First" - @test firstlast(Val(false)) == "Last" -end - -# The constructors for some linear algebra stuff changed to take Val{x} -# instead of Type{Val{x}} -const valtrue = VERSION < v"0.7.0-DEV.843" ? Val{true} : Val(true) -const valfalse = VERSION < v"0.7.0-DEV.843" ? Val{false} : Val(false) - -# qr, qrfact, qrfact! -let A = [1.0 2.0; 3.0 4.0] - Q, R = qr(A, valfalse) - @test Q*R ≈ A - Q, R, p = qr(A, valtrue) - @test Q*R ≈ A[:,p] - F = qrfact(A, valfalse) - @test F[:Q]*F[:R] ≈ A - F = qrfact(A, valtrue) - @test F[:Q]*F[:R] ≈ A[:,F[:p]] - A_copy = copy(A) - F = qrfact!(A_copy, valfalse) - @test F[:Q]*F[:R] ≈ A - A_copy = copy(A) - F = qrfact!(A_copy, valtrue) - @test F[:Q]*F[:R] ≈ A[:,F[:p]] -end - -# Cstring -let s = "foo" - # note: need cconvert in 0.5 because of JuliaLang/julia#16893 - @test reinterpret(Ptr{Cchar}, Compat.unsafe_convert(Cstring, VERSION < v"0.4" ? s : Base.cconvert(Cstring, s))) == pointer(s) - if VERSION < v"0.5.0-dev+4859" - let w = wstring("foo") - @test reinterpret(Ptr{Cwchar_t}, Compat.unsafe_convert(Cwstring, w)) == pointer(w) - end - end -end - -# fma and muladd -@test fma(3,4,5) == 3*4+5 == muladd(3,4,5) - -if VERSION < v"0.5.0-dev+5271" - # is_valid_utf32 - s = utf32("abc") - @test isvalid(s) - s = utf32(UInt32[65,0x110000]) - @test !isvalid(s) - - # isvalid - let s = "abcdef", u8 = "abcdef\uff", u16 = utf16(u8), u32 = utf32(u8), - bad32 = utf32(UInt32[65,0x110000]), badch = Char[0x110000][1] - - @test !isvalid(bad32) - @test !isvalid(badch) - @test isvalid(s) - @test isvalid(u8) - @test isvalid(u16) - @test isvalid(u32) - @test isvalid(Compat.ASCIIString, s) - @test isvalid(Compat.UTF8String, u8) - @test isvalid(UTF16String, u16) - @test isvalid(UTF32String, u32) - end -end - -if VERSION < v"0.5.0-dev+907" - # chol - let A = rand(2,2) - B = A'*A - U = @compat chol(B, Val{:U}) - @test U'*U ≈ B - end -end - -# @generated -if VERSION > v"0.3.99" - let - @compat @generated function foo(x) - T = x - :(return $T) - end - @test foo(5) == Int - end -end - -# Timer -let c = 0, f, g, t - @compat f(t::Timer) = (c += 1) - @compat g(t::Base.Timer) = (c += 1) - t = Timer(f, 0.0, 0.05) - sleep(0.05) - @test c >= 1 - sleep(0.1) - @test c >= 3 - close(t) - sleep(0.1) - val = c - sleep(0.1) - @test val == c - t = Timer(g, 0.0, 0.05) - sleep(0.05) - @test c >= 2 - close(t) -end - -# MathConst -> Irrational -f(::Irrational) = true -@test f(π) -Compat.@irrational mathconst_one 1.0 big(1.) -@test f(mathconst_one) - -# gc_enable(::Bool) -@test gc_enable(false) -@test !gc_enable(true) - -# Vector{Int}(), Array{Int} - -@test @compat typeof(Vector{Int}()) == Array{Int,1} -@test @compat length(Vector{Int}()) == 0 - -@test @compat typeof(Vector{Int8}(10)) == Array{Int8,1} -@test @compat length(Vector{Int8}(10)) == 10 - -@test @compat typeof(Array{UInt16}()) == Array{UInt16,0} -@test @compat length(Array{UInt16}()) == 1 - -@test @compat typeof(Array{UInt16}(0)) == Array{UInt16,1} -@test @compat length(Array{UInt16}(0)) == 0 - -@test @compat typeof(Array{Float16}(5)) == Array{Float16,1} -@test @compat length(Array{Float16}(5)) == 5 - -@test @compat typeof(Array{AbstractString}(2,2)) == Array{AbstractString,2} -@test @compat size(Array{AbstractString}(2,2)) == (2,2) - -@test @compat typeof(Array{Rational{Int}}(2,2,2,2,2)) == Array{Rational{Int},5} -@test @compat size(Array{Rational{Int}}(2,2,2,2,2)) == (2,2,2,2,2) - -@compat String(Mmap.mmap(@__FILE__(),Vector{UInt8},11,1)) == "sing Compat" - -@test base64encode("hello world") == "aGVsbG8gd29ybGQ=" - -@test nothing === __precompile__(false) # tests should never be precompiled -@test nothing === __precompile__() -@test nothing === include_dependency("foo") - -@test real(Int) == real(Complex{Int}) == Int - -@test isa(1.2, AbstractFloat) - -@test [1,2,3] ≈ [1,2,3+1e-9] -@test [0,1] ≈ [1e-9, 1] -@test [0,1] ≉ [1e-3, 1] - -# linspace (some of the julia 0.4 tests) -@test [Compat.linspace(0.1,0.3,3);] == [1:3;]./10 -@test [Compat.linspace(0.0,0.3,4);] == [0:3;]./10 -@test [Compat.linspace(0.3,-0.1,5);] == [3:-1:-1;]./10 -@test [Compat.linspace(0.1,-0.3,5);] == [1:-1:-3;]./10 -@test [Compat.linspace(0.0,1.0,11);] == [0:10;]./10 -@test [Compat.linspace(0.0,1.0,0);] == [] -@test [Compat.linspace(0.0,-1.0,0);] == [] -@test [Compat.linspace(0.0,-1.0,11);] == [0:-1:-10;]./10 -@test [Compat.linspace(1.0,27.0,1275);] == [49:1323;]./49 -@test [Compat.linspace(0.0,2.1,4);] == [0:7:21;]./10 -@test [Compat.linspace(0.0,3.3,4);] == [0:11:33;]./10 -@test [Compat.linspace(0.1,3.4,4);] == [1:11:34;]./10 -@test [Compat.linspace(0.0,3.9,4);] == [0:13:39;]./10 -@test [Compat.linspace(0.1,4.0,4);] == [1:13:40;]./10 -@test [Compat.linspace(1.1,3.3,3);] == [11:11:33;]./10 -@test [Compat.linspace(0.3,1.1,9);] == [3:1:11;]./10 -@test [Compat.linspace(0.0,0.0,1);] == [0.0] -@test [Compat.linspace(0.0,0.0,1);] == [0.0] - -for T = (Float32, Float64) - z = zero(T) - u = eps(z) - @test first(Compat.linspace(u,u,0)) == u - @test last(Compat.linspace(u,u,0)) == u - @test first(Compat.linspace(-u,u,0)) == -u - @test last(Compat.linspace(-u,u,0)) == u - @test [Compat.linspace(-u,u,0);] == [] - @test [Compat.linspace(-u,-u,1);] == [-u] - @test [Compat.linspace(-u,u,2);] == [-u,u] - @test [Compat.linspace(-u,u,3);] == [-u,0,u] - @test first(Compat.linspace(-u,-u,0)) == -u - @test last(Compat.linspace(-u,-u,0)) == -u - @test first(Compat.linspace(u,-u,0)) == u - @test last(Compat.linspace(u,-u,0)) == -u - @test [Compat.linspace(u,-u,0);] == [] - @test [Compat.linspace(u,u,1);] == [u] - @test [Compat.linspace(u,-u,2);] == [u,-u] - @test [Compat.linspace(u,-u,3);] == [u,0,-u] - v = [Compat.linspace(-u,u,12);] - @test length(v) == 12 - @test [-3u:u:3u;] == [Compat.linspace(-3u,3u,7);] == [-3:3;].*u - @test [3u:-u:-3u;] == [Compat.linspace(3u,-3u,7);] == [3:-1:-3;].*u -end - -if VERSION < v"0.4.0-dev+768" - @test @compat(Void) === Nothing -else - @test @compat(Void) === Void -end -@test Ptr{Void} == @compat(Ptr{Void}) - -# MemoryError -> OutOfMemoryError -# Base64Pipe -> Base64EncodePipe -# UdpSocket -> UDPSocket -f141(::Type{OutOfMemoryError}) = true -f141(::Type{Base64EncodePipe}) = true -f141(::Type{UDPSocket}) = true -f141(::Type{TCPSocket}) = true - -@test f141(OutOfMemoryError) -@test f141(Base64EncodePipe) -@test f141(UDPSocket) -@test f141(TCPSocket) - -# Union syntax -if VERSION < v"0.4.0-dev+5379" - @test @compat(Union{}) == None - @test @compat(Union{Int,Float64}) == Union(Int,Float64) - @test @compat(:(Union{})) == :(Union()) -end - -@test fetch(remotecall(() -> true, 1)) -@test remotecall_fetch(() -> true, 1) -@test fetch(remotecall_wait(() -> true, 1)) -Base.remote_do(() -> true, 1) # Doesn't return anything so cannot be `@test`ed but should print some output if it fails - -# JuliaLang/julia#13440 -@test isa(SparseArrays, Module) - -# JuliaLang/julia#12819 -@test Compat.Filesystem.JL_O_RDWR == Compat.Filesystem.JL_O_RDWR - -# JuliaLang/julia#14338 -@test supertype(Int) == Signed - -# withenv -@test "1234" == @compat withenv(() -> ENV["_TESTVAR"], "_TESTVAR" => 1234) -@test "1234" == @compat withenv("_TESTVAR" => 1234) do - return ENV["_TESTVAR"] -end - -# Test functional form of mktemp and mktempdir -let - tmp_path = mktemp() do p, io - @test isfile(p) - print(io, "鴨かも?") - p - end - @test tmp_path != "" - @test !isfile(tmp_path) -end - -let - tmpdir = mktempdir() do d - @test isdir(d) - d - end - @test tmpdir != "" - @test !isdir(tmpdir) -end - -# https://github.com/JuliaLang/julia/pull/14660 -mktempdir() do dir - - verbose = false - - # Create test file... - filename = joinpath(dir, "file.txt") - text = "C1,C2\n1,2\na,b\n" - - # List of IO producers... - l = [ - ("IOStream", (text) -> begin - write(filename, text) - open(filename) - end), - ("IOBuffer", (text)->IOBuffer(text)) - ] - - open_streams = Any[] - function cleanup() - for s in open_streams - try close(s) end - end - end - - for (name, f) in l - - io = ()->(s=f(text); push!(open_streams, s); s) - - write(filename, text) - - verbose && println("$name read...") - @test read(io(), UInt8) == read(IOBuffer(text), UInt8) - @test read(io(), UInt8) == read(filename, UInt8) - @test read(io(), Int) == read(IOBuffer(text), Int) - @test read(io(), Int) == read(filename,Int) - s1 = io() - s2 = IOBuffer(text) - @test read(s1, UInt32, 2) == read(s2, UInt32, 2) - @test !eof(s1) - @test read(s1, UInt8, 5) == read(s2, UInt8, 5) - @test !eof(s1) - @test read(s1, UInt8, 1) == read(s2, UInt8, 1) - @test eof(s1) - @test_throws EOFError read(s1, UInt8) - @test eof(s1) - close(s1) - close(s2) - - verbose && println("$name eof...") - n = length(text) - 1 - @test @compat read!(io(), Vector{UInt8}(n)) == - read!(IOBuffer(text), Vector{UInt8}(n)) - @test @compat (s = io(); read!(s, Vector{UInt8}(n)); !eof(s)) - n = length(text) - @test @compat read!(io(), Vector{UInt8}(n)) == - read!(IOBuffer(text), Vector{UInt8}(n)) - @test @compat (s = io(); read!(s, Vector{UInt8}(n)); eof(s)) - n = length(text) + 1 - @test_throws EOFError @compat read!(io(), Vector{UInt8}(n)) - @test_throws EOFError @compat read!(io(), Vector{UInt8}(n)) - - old_text = text - cleanup() - const SZ_UNBUFFERED_IO = 65536 - - for text in [ - old_text, - convert(String, Char['A' + i % 52 for i in 1:(div(SZ_UNBUFFERED_IO,2))]), - convert(String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO -1)]), - convert(String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO )]), - convert(String, Char['A' + i % 52 for i in 1:( SZ_UNBUFFERED_IO +1)]) - ] - - write(filename, text) - - verbose && println("$name readstring...") - @test readstring(io()) == text - - @test readstring(io()) == readstring(filename) - - - verbose && println("$name read...") - @test @compat read(io()) == UInt8[convert(UInt8, x) for x in text] - - @test read(io()) == read(filename) - - cleanup() - - - verbose && println("$name readbytes!...") - l = length(text) - for n = [1, 2, l-2, l-1, l, l+1, l+2] - @compat a1 = Vector{UInt8}(n); - @compat a2 = Vector{UInt8}(n) - s1 = io() - s2 = IOBuffer(text) - n1 = readbytes!(s1, a1) - n2 = readbytes!(s2, a2) - @test n1 == n2 - @test length(a1) == length(a2) - @test a1[1:n1] == a2[1:n2] - @test n <= length(text) || eof(s1) - @test n <= length(text) || eof(s2) - - cleanup() - end - - verbose && println("$name read!...") - l = length(text) - for n = [1, 2, l-2, l-1, l] - @test @compat read!(io(), Vector{UInt8}(n)) == - read!(IOBuffer(text), Vector{UInt8}(n)) - @test @compat read!(io(), Vector{UInt8}(n)) == - read!(filename, Vector{UInt8}(n)) - - cleanup() - end - @test_throws EOFError @compat read!(io(), Vector{UInt8}(length(text)+1)) - - - verbose && println("$name readuntil...") - @test readuntil(io(), '\n') == readuntil(IOBuffer(text),'\n') - @test readuntil(io(), '\n') == readuntil(filename,'\n') - @test readuntil(io(), "\n") == readuntil(IOBuffer(text),"\n") - @test readuntil(io(), "\n") == readuntil(filename,"\n") - @test readuntil(io(), ',') == readuntil(IOBuffer(text),',') - @test readuntil(io(), ',') == readuntil(filename,',') - - cleanup() - - verbose && println("$name readline...") - @test readline(io()) == readline(IOBuffer(text)) - @test readline(io()) == readline(filename) - - verbose && println("$name readlines...") - @test readlines(io()) == readlines(IOBuffer(text)) - @test readlines(io()) == readlines(filename) - @test collect(eachline(io())) == collect(eachline(IOBuffer(text))) - @test collect(eachline(io())) == collect(eachline(filename)) - - cleanup() - - verbose && println("$name countlines...") - @test countlines(io()) == countlines(IOBuffer(text)) - - # verbose && println("$name readcsv...") - # @test readcsv(io()) == readcsv(IOBuffer(text)) - # @test readcsv(io()) == readcsv(filename) - - cleanup() - end - - text = old_text - write(filename, text) - - verbose && println("$name position...") - @test @compat (s = io(); read!(s, Vector{UInt8}(4)); position(s)) == 4 - - verbose && println("$name seek...") - for n = 0:length(text)-1 - @test readlines(seek(io(), n)) == readlines(seek(IOBuffer(text), n)) - cleanup() - end - verbose && println("$name skip...") - for n = 0:length(text)-1 - @test readlines(seek(io(), n)) == readlines(seek(IOBuffer(text), n)) - @test readlines(skip(io(), n)) == readlines(skip(IOBuffer(text), n)) - cleanup() - end - verbose && println("$name seekend...") - @test readstring(seekend(io())) == "" - - verbose && println("$name write(::IOStream, ...)") - to = open("$filename.to", "w") - write(to, io()) - close(to) - @test readstring("$filename.to") == text - - verbose && println("$name write(filename, ...)") - write("$filename.to", io()) - @test readstring("$filename.to") == text - - verbose && println("$name write(::IOBuffer, ...)") - @compat to = IOBuffer(UInt8[convert(UInt8, x) for x in text], false, true) - write(to, io()) - @test String(take!(to)) == text - - cleanup() - end - - -# https://github.com/JuliaLang/julia/pull/13232 - -setprecision(BigFloat, 100) -@test precision(BigFloat) == 100 -setprecision(256) -@test precision(BigFloat) == 256 - -setprecision(BigFloat, 100) do - a = big(pi) - @test precision(a) == 100 -end - -setprecision(130) do - a = big(pi) - @test precision(a) == 130 -end - -for T in (BigFloat, Float64) - setrounding(T, RoundDown) - @test rounding(T) == RoundDown - setrounding(T, RoundNearest) - - setrounding(T, RoundUp) do - @test rounding(T) == RoundUp - end -end - -end - -@test typeof(displaysize()) == @compat(Tuple{Int, Int}) - -@test Compat.LinAlg.checksquare(randn(4,4)) == 4 -@test Compat.LinAlg.checksquare(randn(4,4), randn(3,3)) == [4,3] -@test_throws DimensionMismatch Compat.LinAlg.checksquare(randn(4,3)) - -@test issymmetric([1 2 3; 2 2 3; 3 3 2]) -@test !issymmetric([1 3 3; 2 2 3; 3 3 2]) - -let X = randn(10,2), Y = randn(10,2), x = randn(10), y = randn(10) - for b in (true, false) - if VERSION < v"0.5.0-dev+679" - @test cov(x, b) == cov(x, corrected=b) - end - for d in (1, 2) - @test size(cov(X, d), 1) == 8*d - 6 - @test size(cov(X, d, b), 1) == 8*d - 6 - @test size(cov(X, Y, d), 1) == 8*d - 6 - @test size(cov(X, Y, d, b), 1) == 8*d - 6 - - @test size(cor(X, d), 1) == 8*d - 6 - @test size(cor(X, Y, d), 1) == 8*d - 6 - end - end -end - -# foreach -let - a = Any[] - foreach(()->push!(a,0)) - @test a == [0] - a = Any[] - foreach(x->push!(a,x), [1,5,10]) - @test a == [1,5,10] - a = Any[] - foreach((args...)->push!(a,args), [2,4,6], [10,20,30]) - @test a == [(2,10),(4,20),(6,30)] -end - -@test istextmime("text/html") && !istextmime("image/png") - -module CallTest - -using Base.Test, Compat - -eval(Expr(:type, false, :A, quote - a -end)) - -eval(Expr(:type, false, :(B{T}), quote - b::T -end)) - -if VERSION >= v"0.4" - @compat (::Type{A})() = A(1) - @compat (::Type{B})() = B{Int}() - @compat (::Type{B{T}}){T}() = B{T}(zero(T)) - - @compat (a::A)() = a.a - @compat (a::A)(b) = (a.a, b) - @compat (a::A)(b, c; d=2) = (a.a, b, c, d) - @compat (b::B{T}){T}() = b.b, T - @compat (b::B{T}){T}(c::T) = 1 - @compat (b::B{T}){T,T2}(c::T2) = 0 - @compat (b::B{T}){T}(c::T, d; f=1) = (c, d, f) - - @test A() === A(1) - @test B() === B(0) - @test B{Float64}() === B(0.0) - - @test A(1)() === 1 - @test A(1)(2) === (1, 2) - @test A(1)(2, 3; d=10) === (1, 2, 3, 10) - @test B(0)() === (0, Int) - @test B(0)(1) === 1 - @test B(0)(1, 2; f=100) === (1, 2, 100) - @test B(0)(1.0) === 0 -end - -end - -# walkdir - -dirwalk = mktempdir() -cd(dirwalk) do - for i=1:2 - mkdir("sub_dir$i") - open("file$i", "w") do f end - - mkdir(joinpath("sub_dir1", "subsub_dir$i")) - touch(joinpath("sub_dir1", "file$i")) - end - touch(joinpath("sub_dir2", "file_dir2")) - has_symlinks = Compat.Sys.isunix() ? true : (isdefined(Base, :WINDOWS_VISTA_VER) && Base.windows_version() >= Base.WINDOWS_VISTA_VER) - follow_symlink_vec = has_symlinks ? [true, false] : [false] - has_symlinks && symlink(abspath("sub_dir2"), joinpath("sub_dir1", "link")) - for follow_symlinks in follow_symlink_vec - chnl = walkdir(".", follow_symlinks=follow_symlinks) - root, dirs, files = take!(chnl) - @test root == "." - @test dirs == ["sub_dir1", "sub_dir2"] - @test files == ["file1", "file2"] - - root, dirs, files = take!(chnl) - @test root == joinpath(".", "sub_dir1") - @test dirs == (has_symlinks ? ["link", "subsub_dir1", "subsub_dir2"] : ["subsub_dir1", "subsub_dir2"]) - @test files == ["file1", "file2"] - - root, dirs, files = take!(chnl) - if follow_symlinks - @test root == joinpath(".", "sub_dir1", "link") - @test dirs == [] - @test files == ["file_dir2"] - root, dirs, files = take!(chnl) - end - for i=1:2 - @test root == joinpath(".", "sub_dir1", "subsub_dir$i") - @test dirs == [] - @test files == [] - root, dirs, files = take!(chnl) - end - - @test root == joinpath(".", "sub_dir2") - @test dirs == [] - @test files == ["file_dir2"] - end - - for follow_symlinks in follow_symlink_vec - chnl = walkdir(".", follow_symlinks=follow_symlinks, topdown=false) - root, dirs, files = take!(chnl) - if follow_symlinks - @test root == joinpath(".", "sub_dir1", "link") - @test dirs == [] - @test files == ["file_dir2"] - root, dirs, files = take!(chnl) - end - for i=1:2 - @test root == joinpath(".", "sub_dir1", "subsub_dir$i") - @test dirs == [] - @test files == [] - root, dirs, files = take!(chnl) - end - @test root == joinpath(".", "sub_dir1") - @test dirs == (has_symlinks ? ["link", "subsub_dir1", "subsub_dir2"] : ["subsub_dir1", "subsub_dir2"]) - @test files == ["file1", "file2"] - - root, dirs, files = take!(chnl) - @test root == joinpath(".", "sub_dir2") - @test dirs == [] - @test files == ["file_dir2"] - - root, dirs, files = take!(chnl) - @test root == "." - @test dirs == ["sub_dir1", "sub_dir2"] - @test files == ["file1", "file2"] - end - #test of error handling - chnl_error = walkdir(".") - chnl_noerror = walkdir(".", onerror=x->x) - root, dirs, files = take!(chnl_error) - @test root == "." - @test dirs == ["sub_dir1", "sub_dir2"] - @test files == ["file1", "file2"] - - rm(joinpath("sub_dir1"), recursive=true) - @test_throws SystemError take!(chnl_error) # throws an error because sub_dir1 do not exist - - root, dirs, files = take!(chnl_noerror) - @test root == "." - @test dirs == ["sub_dir1", "sub_dir2"] - @test files == ["file1", "file2"] - - root, dirs, files = take!(chnl_noerror) # skips sub_dir1 as it no longer exist - @test root == joinpath(".", "sub_dir2") - @test dirs == [] - @test files == ["file_dir2"] - -end -rm(dirwalk, recursive=true) - -# RemoteChannel/Future -r = remotecall(sin, 1, pi/3) -@compat foo(r::Future) = 7 -@test foo(r) == 7 - -@compat rc = RemoteChannel() -@compat rc = RemoteChannel(myid()) - -@compat rc = Future() -@compat rc = Future(myid()) - -# @functorize -function checkfunc(Fun, func) - if VERSION >= v"0.5.0-dev+3701" - @eval @test @functorize($(func)) === Base.$(func) - else - if isdefined(Base, Fun) - @eval @test isa(@functorize($(func)), Base.$(Fun)) - else - @eval @test isa(@functorize($(func)), Function) - @eval @test @functorize($(func)) === Base.$(func) - end - end -end - -for (Fun, func) in [(:IdFun, :identity), - (:AbsFun, :abs), - (:Abs2Fun, :abs2), - (:ExpFun, :exp), - (:LogFun, :log), - (:ConjFun, :conj)] - begin - if isdefined(Base, func) - checkfunc(Fun, func) - a = rand(1:10, 10) - @eval @test mapreduce($(func), +, $(a)) == mapreduce(@functorize($(func)), +, $(a)) - end - end -end - -dotfunctors = [(:DotAddFun, :.+), - (:DotSubFun, :.-), - (:DotMulFun, :.*), - (:DotRDivFun, :./), - (:DotIDivFun, @compat(Symbol(".÷"))), - (:DotRemFun, :.%), - (:DotLSFun, :.<<), - (:DotRSFun, :.>>)] - -functors = [(:AndFun, :&), - (:OrFun, :|), - (:XorFun, :⊻), - (:AddFun, :+), - (:SubFun, :-), - (:MulFun, :*), - (:RDivFun, :/), - (:LDivFun, :\ ), - (:IDivFun, :div), - (:ModFun, :mod), - (:RemFun, :rem), - (:PowFun, :^), - (:MaxFun, :scalarmax), - (:MinFun, :scalarmin), - (:LessFun, :<), - (:MoreFun, :>), - (:ElementwiseMaxFun, :max), - (:ElementwiseMinFun, :min)] - -# since #17623, dot functions are no longer function objects -if VERSION < v"0.6.0-dev.1614" - append!(functors, dotfunctors) -end - -for (Fun, func) in functors - begin - if isdefined(Base, func) && (func !== :.>> || VERSION >= v"0.4.0-dev+553") && (func !== :.% || VERSION >= v"0.5.0-dev+1472") - checkfunc(Fun, func) - a = rand(1:10, 10) - @eval @test mapreduce(identity, Base.$(func), $(a)) == mapreduce(identity, @functorize($(func)), $(a)) - end - end -end - -if VERSION >= v"0.5.0-dev+3701" - @test @functorize(complex) === complex - @test @functorize(dot) === dot -else - if isdefined(Base, :SparseArrays) && isdefined(Base.SparseArrays, :ComplexFun) - @test isa(@functorize(complex), Base.SparseArrays.ComplexFun) - @test isa(@functorize(dot), Base.SparseArrays.DotFun) - else - @test isa(@functorize(complex), Function) - @test isa(@functorize(dot), Function) - @test @functorize(complex) === complex - @test @functorize(dot) === dot - end -end -let a = rand(1:10, 10) - @test mapreduce(identity, dot, a) == mapreduce(identity, @functorize(dot), a) -end - -if VERSION < v"0.6.0-dev.2521" - @test isa(@functorize(centralizedabs2fun)(1), @functorize(centralizedabs2fun)) - @test isa(@functorize(centralizedabs2fun)(1.0), @functorize(centralizedabs2fun)) - let a = rand(1:10, 10) - @eval @test mapreduce(x -> abs2(x - 1), +, $(a)) == mapreduce(@functorize(centralizedabs2fun)(1), +, $(a)) - end -end - -# Threads.@threads -using Compat.Threads -@threads for i=1:10 - @test true -end - -# Issue #223 -@test 1 == threadid() <= nthreads() - -@test @compat(Symbol("foo")) === :foo -@test @compat(Symbol("foo", "bar")) === :foobar -@test @compat(Symbol("a_", 2)) === :a_2 -@test @compat(Symbol('c')) === :c -@test @compat(Symbol(1)) === @compat(Symbol("1")) - -@test @compat(Base.:+) == + -let x = rand(3), y = rand(3) - @test @compat(sin.(cos.(x))) == map(x -> sin(cos(x)), x) - @test @compat(atan2.(sin.(y),x)) == broadcast(atan2,map(sin,y),x) -end -let x0 = Array{Float64}(), v, v0 - x0[1] = rand() - v0 = @compat sin.(x0) - @test isa(v0, Array{Float64,0}) - v = @compat sin.(x0[1]) - @test isa(v, Float64) - @test v == v0[1] == sin(x0[1]) -end -let x = rand(2, 2), v - v = @compat sin.(x) - @test isa(v, Array{Float64,2}) - @test v == [sin(x[1, 1]) sin(x[1, 2]); - sin(x[2, 1]) sin(x[2, 2])] -end -let x1 = [1, 2, 3], x2 = ([3, 4, 5],), v - v = @compat atan2.(x1, x2...) - @test isa(v, Vector{Float64}) - @test v == [atan2(1, 3), atan2(2, 4), atan2(3, 5)] -end -# Do the following in global scope to make sure inference is able to handle it -@test @compat(sin.([1, 2])) == [sin(1), sin(2)] -@test isa(@compat(sin.([1, 2])), Vector{Float64}) -@test @compat(atan2.(1, [2, 3])) == [atan2(1, 2), atan2(1, 3)] -@test isa(@compat(atan2.(1, [2, 3])), Vector{Float64}) -@test @compat(atan2.([1, 2], [2, 3])) == [atan2(1, 2), atan2(2, 3)] -@test isa(@compat(atan2.([1, 2], [2, 3])), Vector{Float64}) -# And make sure it is actually inferrable -f15032(a) = @compat sin.(a) -@inferred f15032([1, 2, 3]) -@inferred f15032([1.0, 2.0, 3.0]) - -# Issue #291 -if VERSION ≥ v"0.5.0-dev+4002" - @test (1, 2) == @compat abs.((1, -2)) - @test broadcast(+, (1.0, 1.0), (0, -2.0)) == (1.0,-1.0) -end - -if VERSION ≥ v"0.4.0-dev+3732" - @test Symbol("foo") === :foo - @test Symbol("foo", "bar") === :foobar - @test Symbol("a_", 2) === :a_2 - @test Symbol('c') === :c - @test Symbol(1) === Symbol("1") -end - -let async, c = false - run = Condition() - async = Compat.AsyncCondition(x->(c = true; notify(run))) - ccall(:uv_async_send, Void, (Ptr{Void},), async.handle) - wait(run) - @test c -end - -let async, c = false - async = Compat.AsyncCondition() - started = Condition() - task = @schedule begin - notify(started) - wait(async) - true - end - wait(started) - ccall(:uv_async_send, Void, (Ptr{Void},), async.handle) - @test wait(task) -end - -let io = IOBuffer(), s = "hello" - unsafe_write(io, pointer(s), length(s)) - @test String(take!(io)) == s -end - -@static if VERSION ≥ v"0.4" - @test VERSION ≥ v"0.4" -else - @test VERSION < v"0.4" -end - -let io = IOBuffer(), s = "hello" - @test @compat String(Vector{UInt8}(s)) == s - write(io, s) - @test @compat String(io) == s - @test unsafe_string(pointer(s)) == s - @test unsafe_string(pointer(s),sizeof(s)) == s - @test string(s, s, s) == "hellohellohello" - @test @compat(String(s)) == s -end - -@test Compat.repeat(1:2, inner=2) == [1, 1, 2, 2] -@test Compat.repeat(1:2, outer=[2]) == [1, 2, 1, 2] -@test Compat.repeat([1,2], inner=(2,)) == [1, 1, 2, 2] - for os in [:apple, :bsd, :linux, :unix, :windows] from_base = if VERSION >= v"0.7.0-DEV.914" Expr(:., Expr(:., :Base, Base.Meta.quot(:Sys)), Base.Meta.quot(Symbol("is", os))) - else # VERSION >= v"0.5.0-dev+4267" + else Expr(:., :Base, Base.Meta.quot(Symbol("is_", os))) end @eval @test Compat.Sys.$(Symbol("is", os))() == $from_base() end -io = IOBuffer() -@test @compat(get(io, :limit, false)) == false -@test @compat(get(io, :compact, false)) == false -@test @compat(get(io, :multiline, false)) == false -@test @compat(get(Nullable(1))) == 1 - -let - test_str = "test" - ptr = pointer(test_str) - wrapped_str = if VERSION < v"0.6.0-dev.1988" - unsafe_wrap(Compat.String, ptr) - else - unsafe_string(ptr) - end - new_str = unsafe_string(ptr) - cstr = convert(Cstring, ptr) - new_str2 = unsafe_string(cstr) - @test wrapped_str == "test" - @test new_str == "test" - @test new_str2 == "test" - if VERSION < v"0.6.0-dev.1988" - # Test proper pointer aliasing behavior, which is not possible in 0.6 - # with the new String representation - @test ptr == pointer(wrapped_str) - end - @test ptr ≠ pointer(new_str) - @test ptr ≠ pointer(new_str2) - @test unsafe_string(convert(Ptr{Int8}, ptr)) == "test" - if VERSION < v"0.6.0-dev.1988" - @test unsafe_wrap(Compat.String, convert(Ptr{Int8}, ptr)) == "test" - end - x = [1, 2] - @test unsafe_wrap(Array, pointer(x), 2) == [1, 2] -end - -@test allunique([1, 2, 3]) -@test !allunique([1, 2, 1]) -@test allunique(1:3) -if VERSION < v"0.6.0-dev.2390" - @test allunique(FloatRange(0.0, 0.0, 0.0, 1.0)) - @test !allunique(FloatRange(0.0, 0.0, 2.0, 1.0)) -end - -# Add test for Base.view -let a = rand(10,10) - @test view(a, :, 1) == a[:,1] -end - - -# 0.5 style single argument `@boundscheck` -@inline function do_boundscheck() - # A bit ugly since `@boundscheck` returns `nothing`. - checked = false - @compat @boundscheck (checked = true;) - checked -end -@test do_boundscheck() == true - -if VERSION < v"0.6.0-dev.1886" - # `promote_eltype_op` is deprecated - @test Compat.promote_eltype_op(@functorize(+), ones(2,2), 1) === Float64 - @test Compat.promote_eltype_op(@functorize(*), ones(Int, 2), zeros(Int16,2)) === Int -end - -#Add test for Base.normalize and Base.normalize! -let - vr = [3.0, 4.0] - for Tr in (Float32, Float64) - for T in (Tr, Complex{Tr}) - v = convert(Vector{T}, vr) - @test norm(v) == 5.0 - w = normalize(v) - @test norm(w - [0.6, 0.8], Inf) < eps(Tr) - @test isapprox(norm(w), 1.0) - @test norm(normalize!(copy(v)) - w, Inf) < eps(Tr) - @test isempty(normalize!(T[])) - end - end -end - -#Test potential overflow in normalize! -let - δ = inv(prevfloat(typemax(Float64))) - v = [δ, -δ] - if VERSION > v"0.4.0-pre+7164" - @test norm(v) === 7.866824069956793e-309 - end - w = normalize(v) - if VERSION > v"0.4.0-pre+7164" - @test w ≈ [1/√2, -1/√2] - @test isapprox(norm(w), 1.0) - end - @test norm(normalize!(v) - w, Inf) < eps() -end - -# JuliaLang/julia#16603 -@test sprint(join, [1, 2, 3]) == "123" -@test sprint(join, [1, 2, 3], ',') == "1,2,3" -@test sprint(join, [1, 2, 3], ", ", ", and ") == "1, 2, and 3" -@test sprint(escape_string, "xyz\n", "z") == "xy\\z\\n" -@test sprint(unescape_string, "xyz\\n") == "xyz\n" - -# three-argument show from JuliaLang/julia#16563 -@test sprint(show, "text/plain", 1) == stringmime("text/plain", 1) - -let n=5, a=rand(n), incx=1, b=rand(n), incy=1 - ccall((Compat.@blasfunc(dcopy_), Base.LinAlg.BLAS.libblas), Void, - (Ptr{Base.LinAlg.BLAS.BlasInt}, Ptr{Float64}, Ptr{Base.LinAlg.BLAS.BlasInt}, Ptr{Float64}, Ptr{Base.LinAlg.BLAS.BlasInt}), - &n, a, &incx, b, &incy) - @test a == b -end - # do-block redirect_std* +# 0.6 let filename = tempname() ret = open(filename, "w") do f redirect_stdout(f) do @@ -1358,7 +20,7 @@ let filename = tempname() end end @test ret == [1,3] - @test chomp(readstring(filename)) == "hello" + @test chomp(read(filename, String)) == "hello" ret = open(filename, "w") do f redirect_stderr(f) do println(STDERR, "WARNING: hello") @@ -1366,7 +28,7 @@ let filename = tempname() end end @test ret == [2] - @test contains(readstring(filename), "WARNING: hello") + @test contains(read(filename, String), "WARNING: hello") ret = open(filename) do f redirect_stdin(f) do readline() @@ -1376,6 +38,7 @@ let filename = tempname() rm(filename) end +# 0.6 @test @__DIR__() == dirname(@__FILE__) # PR #17302 @@ -1395,31 +58,6 @@ mktemp() do fname, f end end -# 0.5.0-dev+4677 -for A in (Hermitian(randn(5,5) + 10I), - Symmetric(randn(5,5) + 10I), - Symmetric(randn(5,5) + 10I, :L)) - F = cholfact(A) - @test F[:U]'F[:U] ≈ A - @test F[:L]*F[:L]' ≈ A - - Ac = copy(A) - F = cholfact!(Ac) - @test F[:U]'F[:U] ≈ A - @test F[:L]*F[:L]' ≈ A - - @test istriu(chol(A)) - @test chol(A) ≈ F[:U] - - F = cholfact(A, valtrue) - @test F[:U]'F[:U] ≈ A[F[:p], F[:p]] - @test F[:L]*F[:L]' ≈ A[F[:p], F[:p]] - Ac = copy(A) - F = cholfact!(Ac, valtrue) - @test F[:U]'F[:U] ≈ A[F[:p], F[:p]] - @test F[:L]*F[:L]' ≈ A[F[:p], F[:p]] -end - types = [ Bool, Float16, @@ -1558,13 +196,9 @@ A = view(rand(5,5), 1:3, 1:3) @test A*D == copy(A) * Diagonal(copy(x)) # julia#17623 -if VERSION >= v"0.5.0-dev+5509" -# Use include_string to work around unsupported syntax on Julia 0.4 -include_string(@__MODULE__, """ - @test [true, false] .& [true, true] == [true, false] - @test [true, false] .| [true, true] == [true, true] -""") -end +# 0.6 +@test [true, false] .& [true, true] == [true, false] +@test [true, false] .| [true, true] == [true, true] # julia#20022 @test !Compat.isapprox(NaN, NaN) @@ -1833,13 +467,11 @@ using Compat: StringVector @test String(fill!(StringVector(5), 0x61)) == "aaaaa" # collect -if VERSION >= v"0.5.0-rc1+46" - using OffsetArrays - a = OffsetArray(1:3, -1:1) - b = Compat.collect(a) - @test indices(b) === (Base.OneTo(3),) - @test b == [1,2,3] -end +using OffsetArrays +a = OffsetArray(1:3, -1:1) +b = Compat.collect(a) +@test indices(b) === (Base.OneTo(3),) +@test b == [1,2,3] # PR 22064 module Test22064 @@ -1917,6 +549,36 @@ if VERSION < v"0.7.0-DEV.880" end end -include("deprecated.jl") +let x = fill!(StringVector(5), 0x61) + # 0.7 + @test pointer(x) == pointer(String(x)) +end + +# Val(x) +# 0.7 +begin + local firstlast + firstlast(::Val{true}) = "First" + firstlast(::Val{false}) = "Last" + + @test firstlast(Val(true)) == "First" + @test firstlast(Val(false)) == "Last" +end + +# @nospecialize +# 0.7 +no_specialize(@nospecialize(x)) = sin(1) +no_specialize(@nospecialize(x::Integer)) = sin(2) +@test no_specialize(1.0) == sin(1) +@test no_specialize(1) == sin(2) + +# 0.7 +@test read(IOBuffer("aaaa"), String) == "aaaa" +@test contains(read(@__FILE__, String), "read(@__FILE__, String)") +@test read(`$(Base.julia_cmd()) --startup-file=no -e "println(:aaaa)"`, String) == "aaaa\n" + +if VERSION < v"0.6.0" + include("deprecated.jl") +end nothing