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

merge develop #4

Merged
merged 2 commits into from
Sep 8, 2022
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
1 change: 0 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ authors = ["김용희 <yongheekim@devsisters.com>"]
version = "0.4.0"

[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"

[compat]
Expand Down
1 change: 0 additions & 1 deletion src/JSONPointer.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module JSONPointer

using Compat
using OrderedCollections

include("pointer.jl")
Expand Down
4 changes: 1 addition & 3 deletions src/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ end
function Base.show(io::IO, ::Pointer{Nothing})
print(io, "JSONPointer{Nothing}(\"\")")
end
function Base.getindex(A::T, p::Pointer) where T<:AbstractDict
error("test")
end

Base.getindex(A::AbstractArray, p::Pointer) = _getindex(A, p)
Base.haskey(A::AbstractArray, p::Pointer) = _haskey(A, p)

Expand Down
29 changes: 10 additions & 19 deletions src/pointerdict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ struct PointerDict{K<:Union{String,Symbol}, V} <: AbstractDict{K, V}
PointerDict(d::AbstractDict{Symbol,V}) where {V} = new{Symbol,V}(d)

function PointerDict(d::T) where T <: AbstractDict
dict = T{String,valtype(d)}()
dict = dicttype(T){String,valtype(d)}()
for (k,v) in d
dict[string(k)] = v
end
Expand All @@ -34,9 +34,12 @@ struct PointerDict{K<:Union{String,Symbol}, V} <: AbstractDict{K, V}
end
PointerDict(d)
end
PointerDict(; kwargs...) = PointerDict(values(kwargs))
# PointerDict(; kwargs...) = PointerDict(values(kwargs))
end

dicttype(::Type{T}) where T <: AbstractDict = eval(T.name.wrapper)
dicttype(x::T) where T <: AbstractDict = eval(T.name.wrapper)

Base.IteratorSize(@nospecialize T::Type{<:PointerDict}) = Base.IteratorSize(fieldtype(T, :d))
Base.IteratorEltype(@nospecialize T::Type{<:PointerDict}) = Base.IteratorEltype(eltype(T))

Expand Down Expand Up @@ -105,8 +108,6 @@ function Base.setindex!(pd::PointerDict, v, jp::Pointer)
_setindex!(getfield(pd, :d), v, jp)
end

Base.reverse(pd::PointerDict) = PointerDict(reverse(getfield(pd, :d)))

Base.iterate(pd::PointerDict) = iterate(getfield(pd, :d))
Base.iterate(pd::PointerDict, i) = iterate(getfield(pd, :d), i)

Expand All @@ -130,23 +131,13 @@ function Base.merge(pd::PointerDict, pds::PointerDict...)
for (k,v) in pd
out[k] = v
end
merge!(out, pds...)
end

@static if VERSION >= v"1.5"
Base.mergewith(combine, pd::PointerDict) = copy(pd)
function Base.mergewith(combine, pd::PointerDict, pds::PointerDict...)
K = _promote_keytypes((pd, pds...))
V0 = _promote_valtypes(valtype(pd), pds...)
V = promote_type(Core.Compiler.return_type(combine, Tuple{V0,V0}), V0)
out = PointerDict(Dict{K,V}())
for (k,v) in pd
out[k] = v
end
mergewith!(combine, out, pds...)
end
merge!(recursive_merge, out, pds...)
end

recursive_merge(x::AbstractDict...) = merge(recursive_merge, x...)
recursive_merge(x::AbstractVector...) = cat(x...; dims=1)
recursive_merge(x...) = x[end]

# fall back to String if we don't clearly have Symbol
_promote_keytypes(@nospecialize(pds::Tuple{Vararg{PointerDict{Symbol, T}}})) where T = Symbol
_promote_keytypes(@nospecialize(pds::Tuple{Vararg{PointerDict}})) = String
Expand Down
70 changes: 69 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ end
@test data[p2] == "Is my Data"
end

@testset "access deep nested object" begin
@testset "test for 'getindex', 'get', 'get!'" begin
data = [PointerDict("a" => 10)]
@test data[j"/1/a"] == 10

Expand Down Expand Up @@ -156,6 +156,24 @@ end

# get isn't defined for array
@test_broken get(data, j"/1", missing) |> ismissing

data = PointerDict()
@test "this" == get!(data, j"/a", "this")
@test data[j"/a"] == data["a"] == "this"

@test [1,2,3] == get!(data, j"/b", Any[1,2,3])
@test data[j"/b"] == data["b"] == [1,2,3]
@test data[j"/b/1"] == data["b"][1] == 1
@test data[j"/b/2"] == data["b"][2] == 2

@test get!(data, j"/b/5", missing) |> ismissing
@test data[j"/b/5"] === data["b"][5]

@test "that" == get(data, "c", "that")
@test haskey(data, "c") == false
@test "that" == get!(data, "c", "that")
@test haskey(data, "c")
data["e"] = [1]
end

@testset "literal string for a Number" begin
Expand Down Expand Up @@ -233,6 +251,56 @@ end

end

@testset "PointerDicts" begin
d = Dict("foo"=>1, "bar"=>2)
_keys = collect(keys(d))
pd = PointerDict(d)

@test length(pd) == length(d)

@test empty!(PointerDict(Dict("foo"=>1, :bar=>2))) isa PointerDict
@test empty(pd) == PointerDict(empty(d))

@test haskey(pd, "foo")
@test getkey(pd, "buz", nothing) === nothing

@testset "convert" begin
expected = OrderedDict
result = convert(expected, pd)

@test result isa expected
end

@testset "iterate" begin
@test iterate(pd) == iterate(d)
@test iterate(pd, 1) == iterate(d, 1)
@test iterate(pd, 2) == iterate(d, 2)
end

@testset "iteratorsize" begin
@test Base.IteratorSize(pd) == Base.IteratorSize(d)
end

@testset "iteratoreltype" begin
@test Base.IteratorEltype(pd) == Base.IteratorEltype(d)
end

push!(pd, "buz" => 10)
@test pop!(pd, "buz") == 10
@test pop!(pd, "buz", 20) == 20
@test sizehint!(pd, 5) === pd
@test get(pd, delete!(pd, "foo"), 10) == 10

@testset "merge & mergewith" begin
a = PointerDict(j"/dict/a"=>1, j"/array/1"=>2, "c"=>3)
b = PointerDict(j"/dict/b"=>4, j"/array/1"=>5)
c = PointerDict(j"/dict/dict"=>Dict("aa"=>100), "d"=>nothing)

@test @inferred(merge(a, b)) == PointerDict(j"/dict/a" => 1, "c"=>3, j"/dict/b" => 4, j"/array"=>Any[2, 5])
@test @inferred(merge(a, b, c)) == PointerDict(j"/dict/a" => 1, "c"=>3, j"/dict/b" => 4, j"/array"=>Any[2, 5], j"/dict/dict" => Dict("aa" => 100), "d" => nothing)
end
end

@testset "Miscellaneous" begin
p1 = j"/a/b/1/c"

Expand Down