Skip to content

Commit

Permalink
More WeakKeyIdDict tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin committed Sep 12, 2023
1 parent 1d88f46 commit 5656ea9
Showing 1 changed file with 89 additions and 1 deletion.
90 changes: 89 additions & 1 deletion test/WeakKeyIdDict-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,101 @@
@test WeakKeyIdDict(dd) == wkd
@test convert(WeakKeyIdDict{Any, Any}, dd) == wkd
@test isa(WeakKeyIdDict(dd), WeakKeyIdDict{Any,Any})

# test many constructors without type parameters specified
@test WeakKeyIdDict(A=>2, B=>3, C=>4) == wkd
@test isa(WeakKeyIdDict(A=>2, B=>3, C=>4), WeakKeyIdDict{Array{Int,1},Int})
@test isa(WeakKeyIdDict(A=>2, B=>3, C=>4), WeakKeyIdDict{Vector{Int},Int})
@test WeakKeyIdDict(a=>i+1 for (i,a) in enumerate([A,B,C]) ) == wkd
@test WeakKeyIdDict([(A,2), (B,3), (C,4)]) == wkd
@test WeakKeyIdDict(Pair(A,2), Pair(B,3), Pair(C,4)) == wkd

# test many constructors with type parameters specified
@test WeakKeyIdDict{Vector{Int},Int}(A=>2, B=>3, C=>4) == wkd
@test isa(WeakKeyIdDict{Vector{Int},Int}(A=>2, B=>3, C=>4), WeakKeyIdDict{Vector{Int},Int})
@test WeakKeyIdDict{Vector{Int},Int}(a=>i+1 for (i,a) in enumerate([A,B,C]) ) == wkd
@test WeakKeyIdDict{Vector{Int},Int}([(A,2), (B,3), (C,4)]) == wkd
@test WeakKeyIdDict{Vector{Int},Int}(Pair(A,2), Pair(B,3), Pair(C,4)) == wkd

# test more constructors with mixed types
@test isa(WeakKeyIdDict(A=>2, B=>3, C=>"4"), WeakKeyIdDict{Vector{Int},Any})
@test isa(WeakKeyIdDict(A=>2, B=>3, "C"=>4), WeakKeyIdDict{Any,Int})
@test isa(WeakKeyIdDict(A=>2, B=>3, "C"=>"4"), WeakKeyIdDict{Any,Any})

@test copy(wkd) == wkd

@test length(wkd) == 3
@test !isempty(wkd)
@test haskey(wkd, C)
@test getkey(wkd, C, 123) === C
res = pop!(wkd, C)
@test res == 4
@test C keys(wkd)
@test 4 values(wkd)
@test !haskey(wkd, C)
@test length(wkd) == 2
@test !isempty(wkd)
@test 47 == pop!(wkd, C, 47)
@test getkey(wkd, C, 123) == 123
wkd = filter!( p -> p.first != B, wkd)
@test B keys(wkd)
@test 3 values(wkd)
@test length(wkd) == 1
@test WeakKeyIdDict(Pair(A, 2)) == wkd
@test !isempty(wkd)

wkd[A] = 42
@test wkd[A] == 42

wkd = WeakKeyIdDict(A=>2, B=>3, C=>4)
map!(x -> x + 1, values(wkd))
@test WeakKeyIdDict(A=>3, B=>4, C=>5) == wkd

wkd = WeakKeyIdDict(A=>2, B=>3, C=>4)
@test delete!(wkd, A) == WeakKeyIdDict(B=>3, C=>4)
@test delete!(wkd, A) == WeakKeyIdDict(B=>3, C=>4) # deleting the same key twice works
@test delete!(wkd, C) == WeakKeyIdDict(B=>3)
@test delete!(wkd, B) == WeakKeyIdDict()
# adding stuff back is OK
wkd[A] = 2
wkd[B] = 3
wkd[C] = 4
@test wkd == WeakKeyIdDict(A=>2, B=>3, C=>4)

wkd = WeakKeyIdDict(A=>2)
@test get(wkd, A, 17) == 2
@test get!(wkd, A, 17) == 2
@test get(wkd, B, 17) == 17
@test length(wkd) == 1
@test get!(wkd, B, 17) == 17
@test length(wkd) == 2

wkd = WeakKeyIdDict(A=>2)
@test get(() -> 23, wkd, A) == 2
@test get!(() -> 23, wkd, A) == 2
@test get(() -> 23, wkd, B) == 23
@test length(wkd) == 1
@test get!(() -> 23, wkd, B) == 23
@test length(wkd) == 2

wkd = empty!(wkd)
@test wkd == empty(wkd)
@test wkd == empty(wkd)
@test typeof(wkd) == typeof(empty(wkd))
@test length(wkd) == 0
@test isempty(wkd)
@test isa(wkd, WeakKeyIdDict)
@test WeakKeyIdDict() == WeakKeyIdDict(())

@test_throws ArgumentError WeakKeyIdDict([1, 2, 3])

# WeakKeyIdDict does not convert keys
@test_throws ArgumentError WeakKeyIdDict{Int,Any}(5.0=>1)

# iterator
wkd = WeakKeyIdDict(A=>2, B=>3, C=>4)
@test Set(collect(wkd)) == Set([A=>2, B=>3, C=>4])
@test 2+3+4 == sum(v for (k,v) in wkd)

# WeakKeyIdDict hashes with object-id
AA = copy(A)
GC.@preserve A AA begin
Expand All @@ -66,4 +127,31 @@
d26939 = WeakKeyIdDict()
d26939[big"1.0" + 1.1] = 1
GC.gc() # make sure this doesn't segfault

end

# The following tests involve the garbage collector and
# don't work if they are inside a @testset
wkd = WeakKeyIdDict([42]=>2, [43]=>3, [44]=>4)
for k in keys(wkd)
delete!(wkd, k)
end
@test isempty(wkd)
GC.gc() # try to get it to evict some weak references
@test isempty(wkd)

# verify that garbage collection takes care of our weak references
A = [1]
wkd = WeakKeyIdDict(A => 1)
let tmp = [ 42 ]
@test length(wkd) == 1
wkd[tmp] = 2
@test length(wkd) == 2
end
# at this point there is no strong reference left to the vector [42]
# previously reachable via tmp
GC.gc(true)

@test length(wkd) == 1
@test length(keys(wkd)) == 1
@test WeakKeyIdDict(A => 1) == wkd

0 comments on commit 5656ea9

Please sign in to comment.