|
13 | 13 | @test WeakKeyIdDict(dd) == wkd
|
14 | 14 | @test convert(WeakKeyIdDict{Any, Any}, dd) == wkd
|
15 | 15 | @test isa(WeakKeyIdDict(dd), WeakKeyIdDict{Any,Any})
|
| 16 | + |
| 17 | + # test many constructors without type parameters specified |
16 | 18 | @test WeakKeyIdDict(A=>2, B=>3, C=>4) == wkd
|
17 |
| - @test isa(WeakKeyIdDict(A=>2, B=>3, C=>4), WeakKeyIdDict{Array{Int,1},Int}) |
| 19 | + @test isa(WeakKeyIdDict(A=>2, B=>3, C=>4), WeakKeyIdDict{Vector{Int},Int}) |
18 | 20 | @test WeakKeyIdDict(a=>i+1 for (i,a) in enumerate([A,B,C]) ) == wkd
|
19 | 21 | @test WeakKeyIdDict([(A,2), (B,3), (C,4)]) == wkd
|
20 | 22 | @test WeakKeyIdDict(Pair(A,2), Pair(B,3), Pair(C,4)) == wkd
|
| 23 | + |
| 24 | + # test many constructors with type parameters specified |
| 25 | + @test WeakKeyIdDict{Vector{Int},Int}(A=>2, B=>3, C=>4) == wkd |
| 26 | + @test isa(WeakKeyIdDict{Vector{Int},Int}(A=>2, B=>3, C=>4), WeakKeyIdDict{Vector{Int},Int}) |
| 27 | + @test WeakKeyIdDict{Vector{Int},Int}(a=>i+1 for (i,a) in enumerate([A,B,C]) ) == wkd |
| 28 | + @test WeakKeyIdDict{Vector{Int},Int}([(A,2), (B,3), (C,4)]) == wkd |
| 29 | + @test WeakKeyIdDict{Vector{Int},Int}(Pair(A,2), Pair(B,3), Pair(C,4)) == wkd |
| 30 | + |
| 31 | + # test more constructors with mixed types |
| 32 | + @test isa(WeakKeyIdDict(A=>2, B=>3, C=>"4"), WeakKeyIdDict{Vector{Int},Any}) |
| 33 | + @test isa(WeakKeyIdDict(A=>2, B=>3, "C"=>4), WeakKeyIdDict{Any,Int}) |
| 34 | + @test isa(WeakKeyIdDict(A=>2, B=>3, "C"=>"4"), WeakKeyIdDict{Any,Any}) |
| 35 | + |
21 | 36 | @test copy(wkd) == wkd
|
22 | 37 |
|
23 | 38 | @test length(wkd) == 3
|
24 | 39 | @test !isempty(wkd)
|
| 40 | + @test haskey(wkd, C) |
| 41 | + @test getkey(wkd, C, 123) === C |
25 | 42 | res = pop!(wkd, C)
|
26 | 43 | @test res == 4
|
27 | 44 | @test C ∉ keys(wkd)
|
28 | 45 | @test 4 ∉ values(wkd)
|
| 46 | + @test !haskey(wkd, C) |
29 | 47 | @test length(wkd) == 2
|
30 | 48 | @test !isempty(wkd)
|
| 49 | + @test 47 == pop!(wkd, C, 47) |
| 50 | + @test getkey(wkd, C, 123) == 123 |
31 | 51 | wkd = filter!( p -> p.first != B, wkd)
|
32 | 52 | @test B ∉ keys(wkd)
|
33 | 53 | @test 3 ∉ values(wkd)
|
34 | 54 | @test length(wkd) == 1
|
35 | 55 | @test WeakKeyIdDict(Pair(A, 2)) == wkd
|
36 | 56 | @test !isempty(wkd)
|
37 | 57 |
|
| 58 | + wkd[A] = 42 |
| 59 | + @test wkd[A] == 42 |
| 60 | + |
| 61 | + wkd = WeakKeyIdDict(A=>2, B=>3, C=>4) |
| 62 | + map!(x -> x + 1, values(wkd)) |
| 63 | + @test WeakKeyIdDict(A=>3, B=>4, C=>5) == wkd |
| 64 | + |
| 65 | + wkd = WeakKeyIdDict(A=>2, B=>3, C=>4) |
| 66 | + @test delete!(wkd, A) == WeakKeyIdDict(B=>3, C=>4) |
| 67 | + @test delete!(wkd, A) == WeakKeyIdDict(B=>3, C=>4) # deleting the same key twice works |
| 68 | + @test delete!(wkd, C) == WeakKeyIdDict(B=>3) |
| 69 | + @test delete!(wkd, B) == WeakKeyIdDict() |
| 70 | + # adding stuff back is OK |
| 71 | + wkd[A] = 2 |
| 72 | + wkd[B] = 3 |
| 73 | + wkd[C] = 4 |
| 74 | + @test wkd == WeakKeyIdDict(A=>2, B=>3, C=>4) |
| 75 | + |
| 76 | + wkd = WeakKeyIdDict([42]=>2, [43]=>3, [44]=>4) |
| 77 | + for k in keys(wkd) |
| 78 | + delete!(wkd, k) |
| 79 | + end |
| 80 | + @test isempty(wkd) |
| 81 | + GC.gc() # try to get it to evict some weak references |
| 82 | + @test isempty(wkd) |
| 83 | + |
| 84 | + wkd = WeakKeyIdDict(A=>2) |
| 85 | + @test get(wkd, A, 17) == 2 |
| 86 | + @test get!(wkd, A, 17) == 2 |
| 87 | + @test get(wkd, B, 17) == 17 |
| 88 | + @test length(wkd) == 1 |
| 89 | + @test get!(wkd, B, 17) == 17 |
| 90 | + @test length(wkd) == 2 |
| 91 | + |
| 92 | + wkd = WeakKeyIdDict(A=>2) |
| 93 | + @test get(() -> 23, wkd, A) == 2 |
| 94 | + @test get!(() -> 23, wkd, A) == 2 |
| 95 | + @test get(() -> 23, wkd, B) == 23 |
| 96 | + @test length(wkd) == 1 |
| 97 | + @test get!(() -> 23, wkd, B) == 23 |
| 98 | + @test length(wkd) == 2 |
| 99 | + |
38 | 100 | wkd = empty!(wkd)
|
39 | 101 | @test wkd == empty(wkd)
|
| 102 | + @test wkd == empty(wkd) |
40 | 103 | @test typeof(wkd) == typeof(empty(wkd))
|
41 | 104 | @test length(wkd) == 0
|
42 | 105 | @test isempty(wkd)
|
43 | 106 | @test isa(wkd, WeakKeyIdDict)
|
| 107 | + @test WeakKeyIdDict() == WeakKeyIdDict(()) |
44 | 108 |
|
45 | 109 | @test_throws ArgumentError WeakKeyIdDict([1, 2, 3])
|
46 | 110 |
|
47 | 111 | # WeakKeyIdDict does not convert keys
|
48 | 112 | @test_throws ArgumentError WeakKeyIdDict{Int,Any}(5.0=>1)
|
49 | 113 |
|
| 114 | + # iterator |
| 115 | + wkd = WeakKeyIdDict(A=>2, B=>3, C=>4) |
| 116 | + @test Set(collect(wkd)) == Set([A=>2, B=>3, C=>4]) |
| 117 | + @test 2+3+4 == sum(v for (k,v) in wkd) |
| 118 | + |
50 | 119 | # WeakKeyIdDict hashes with object-id
|
51 | 120 | AA = copy(A)
|
52 | 121 | GC.@preserve A AA begin
|
|
66 | 135 | d26939 = WeakKeyIdDict()
|
67 | 136 | d26939[big"1.0" + 1.1] = 1
|
68 | 137 | GC.gc() # make sure this doesn't segfault
|
| 138 | + |
| 139 | +end |
| 140 | + |
| 141 | +@testset "WeakKeyIdDict.gc" begin |
| 142 | + # verify that garbage collection takes care of our weak references |
| 143 | + A = [1] |
| 144 | + wkd = WeakKeyIdDict(A => 1) |
| 145 | + let tmp = [ 42 ] |
| 146 | + @test length(wkd) == 1 |
| 147 | + wkd[tmp] = 2 |
| 148 | + @test length(wkd) == 2 |
| 149 | + end |
| 150 | + # at this point there is no strong reference left to the vector [42] |
| 151 | + # previously reachable via tmp |
| 152 | + GC.gc(true) |
| 153 | + |
| 154 | + # FIXME: somehow the following test does not work if it |
| 155 | + # is inside a @testset; it works if I copy&paste the content |
| 156 | + # into the REPL. Huh? |
| 157 | + #= |
| 158 | + @test length(wkd) == 1 |
| 159 | + @test length(keys(wkd)) == 1 |
| 160 | + @test WeakKeyIdDict(A => 1) == wkd |
| 161 | + =# |
69 | 162 | end
|
0 commit comments