Skip to content

Commit

Permalink
Updated OrderedDict tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kmsquire committed Mar 5, 2015
1 parent 2d4edfe commit 4c6e6d0
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 8 deletions.
22 changes: 17 additions & 5 deletions src/ordereddict.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ordered dict

import Base: haskey, get, get!, getkey, delete!, push!, pop!, empty!,
setindex!, getindex, sizehint, length, isempty, start,
setindex!, getindex, length, isempty, start,
next, done, keys, values, setdiff, setdiff!,
union, union!, intersect, isequal, filter, filter!,
hash, eltype
Expand Down Expand Up @@ -51,10 +51,22 @@ copy(d::OrderedDict) = OrderedDict(d)

## Most functions are simply delegated to the wrapped HashDict

@compat @delegate OrderedDict.d [ haskey, get, get!, getkey, delete!, pop!,
empty!, setindex!, getindex, sizehint,
length, isempty, start, next, done, keys,
values ]
@delegate OrderedDict.d [ haskey, get, get!, getkey, delete!, pop!,
empty!, setindex!, getindex,
length, isempty, start, next, done, keys,
values ]

sizehint(d::OrderedDict, sz::Integer) = (sizehint(d.d, sz); d)

if VERSION >= v"0.4.0-dev+980"
push!(d::OrderedDict, kv::Pair) = (push!(d.d, kv); d)
push!(d::OrderedDict, kv::Pair, kv2::Pair) = (push!(d.d, kv, kv2); d)
push!(d::OrderedDict, kv::Pair, kv2::Pair, kv3::Pair...) = (push!(d.d, kv, kv2, kv3...); d)
end

push!(d::OrderedDict, kv) = (push!(d.d, kv); d)
push!(d::OrderedDict, kv, kv2...) = (push!(d.d, kv, kv2...); d)


similar{K,V}(d::OrderedDict{K,V}) = OrderedDict{K,V}()
in{T<:OrderedDict}(key, v::Base.KeyIterator{T}) = key in keys(v.dict.d.d)
242 changes: 242 additions & 0 deletions test/test_ordereddict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,245 @@ end
od60[14]=15

@test od60[14] == 15


##############################
# Copied and modified from Base/test/dict.jl

# OrderedDict
h = OrderedDict()
for i=1:10000
h[i] = i+1
end
@test collect(h) == collect(zip(1:10000, 2:10001))

for i=1:2:10000
delete!(h, i)
end
for i=1:2:10000
h[i] = i+1
end

for i=1:10000
@test h[i]==i+1
end

for i=1:10000
delete!(h, i)
end
@test isempty(h)

h[77] = 100
@test h[77]==100

for i=1:10000
h[i] = i+1
end

for i=1:2:10000
delete!(h, i)
end

for i=10001:20000
h[i] = i+1
end

for i=2:2:10000
@test h[i]==i+1
end

for i=10000:20000
@test h[i]==i+1
end

h = OrderedDict{Any,Any}("a" => 3)
@test h["a"] == 3
h["a","b"] = 4
@test h["a","b"] == h[("a","b")] == 4
h["a","b","c"] = 4
@test h["a","b","c"] == h[("a","b","c")] == 4

let
z = OrderedDict()
get_KeyError = false
try
z["a"]
catch _e123_
get_KeyError = isa(_e123_,KeyError)
end
@test get_KeyError
end

_d = OrderedDict("a"=>0)
@test isa([k for k in filter(x->length(x)==1, collect(keys(_d)))], Vector{Any})

let
## TODO: this should work, but inference seems to be working incorrectly
#d = OrderedDict(((1, 2), (3, 4)))
d = OrderedDict([(1, 2), (3, 4)])
@test d[1] === 2
@test d[3] === 4
## TODO: @compat only rewrites Dict, not OrderedDict
# d2 = OrderedDict(1 => 2, 3 => 4)
# d3 = OrderedDict((1 => 2, 3 => 4))
# @test d == d2 == d3
# @test typeof(d) == typeof(d2) == typeof(d3) == OrderedDict{Int,Int}
@test typeof(d) == OrderedDict{Int,Int}

#d = OrderedDict(((1, 2), (3, "b")))
d = OrderedDict([(1, 2), (3, "b")])
@test d[1] === 2
@test d[3] == "b"
# d2 = OrderedDict(1 => 2, 3 => "b")
# d3 = OrderedDict((1 => 2, 3 => "b"))
# @test d == d2 == d3
# @test typeof(d) == typeof(d2) == typeof(d3) == OrderedDict{Int,Any}
@test typeof(d) == OrderedDict{Int,Any}

#d = OrderedDict(((1, 2), ("a", 4)))
d = OrderedDict([(1, 2), ("a", 4)])
@test d[1] === 2
@test d["a"] === 4
# d2 = OrderedDict(1 => 2, "a" => 4)
# d3 = OrderedDict((1 => 2, "a" => 4))
# @test d == d2 == d3
# @test typeof(d) == typeof(d2) == typeof(d3) == OrderedDict{Any,Int}
@test typeof(d) == OrderedDict{Any,Int}

#d = OrderedDict(((1, 2), ("a", "b")))
d = OrderedDict([(1, 2), ("a", "b")])
@test d[1] === 2
@test d["a"] == "b"
# d2 = OrderedDict(1 => 2, "a" => "b")
# d3 = OrderedDict((1 => 2, "a" => "b"))
# @test d == d2 == d3
# @test typeof(d) == typeof(d2) == typeof(d3) == OrderedDict{Any,Any}
@test typeof(d) == OrderedDict{Any,Any}
end

@test_throws ArgumentError first(OrderedDict())
@test first(OrderedDict(:f=>2)) == (:f,2)

# issue #1821
let
d = OrderedDict{UTF8String, Vector{Int}}()
d["a"] = [1, 2]
@test_throws MethodError d["b"] = 1
@test isa(repr(d), AbstractString) # check that printable without error
end

# issue #2344
let
local bar
bestkey(d, key) = key
bestkey{K<:AbstractString,V}(d::Associative{K,V}, key) = string(key)
bar(x) = bestkey(x, :y)
@test bar(OrderedDict(:x => [1,2,5])) == :y
@test bar(OrderedDict("x" => [1,2,5])) == "y"
end


@test isequal(OrderedDict(), OrderedDict())
@test isequal(OrderedDict(1 => 1), OrderedDict(1 => 1))
@test !isequal(OrderedDict(1 => 1), OrderedDict())
@test !isequal(OrderedDict(1 => 1), OrderedDict(1 => 2))
@test !isequal(OrderedDict(1 => 1), OrderedDict(2 => 1))

# Generate some data to populate dicts to be compared
data_in = [ (rand(1:1000), randstring(2)) for _ in 1:1001 ]

# Populate the first dict
d1 = OrderedDict{Int, AbstractString}()
for (k,v) in data_in
d1[k] = v
end
data_in = collect(d1)
# shuffle the data
for i in 1:length(data_in)
j = rand(1:length(data_in))
data_in[i], data_in[j] = data_in[j], data_in[i]
end
# Inserting data in different (shuffled) order should result in
# equivalent dict.
d2 = OrderedDict{Int, AbstractString}()
for (k,v) in data_in
d2[k] = v
end

@test isequal(d1, d2)
d3 = copy(d2)
d4 = copy(d2)
# Removing an item gives different dict
delete!(d1, data_in[rand(1:length(data_in))][1])
@test !isequal(d1, d2)
# Changing a value gives different dict
d3[data_in[rand(1:length(data_in))][1]] = randstring(3)
!isequal(d1, d3)
# Adding a pair gives different dict
d4[1001] = randstring(3)
@test !isequal(d1, d4)

@test isequal(OrderedDict(), sizehint(OrderedDict(),96))

# Here is what currently happens when dictionaries of different types
# are compared. This is not necessarily desirable. These tests are
# descriptive rather than proscriptive.
@test !isequal(OrderedDict(1 => 2), OrderedDict("dog" => "bone"))
@test isequal(OrderedDict{Int,Int}(), OrderedDict{AbstractString,AbstractString}())

# get! (get with default values assigned to the given location)

## TODO: get! not implemented for OrderedDict
# let f(x) = x^2, d = OrderedDict(8=>19)

# @test get!(d, 8, 5) == 19
# @test get!(d, 19, 2) == 2

# @test get!(d, 42) do # d is updated with f(2)
# f(2)
# end == 4

# @test get!(d, 42) do # d is not updated
# f(200)
# end == 4

# @test get(d, 13) do # d is not updated
# f(4)
# end == 16

# @test d == OrderedDict(8=>19, 19=>2, 42=>4)
# end


# issue #5886
d5886 = OrderedDict()
for k5886 in 1:11
d5886[k5886] = 1
end
for k5886 in keys(d5886)
# undefined ref if not fixed
d5886[k5886] += 1
end

# issue #8877
## TODO: merge not implemented for OrderedDict
# let
# a = OrderedDict("foo" => 0.0, "bar" => 42.0)
# b = OrderedDict("フー" => 17, "バー" => 4711)
# @test is(typeof(merge(a, b)), OrderedDict{UTF8String,Float64})
# end

# issue 9295
let
d = OrderedDict()
@test is(push!(d, 'a' => 1), d)
@test d['a'] == 1
@test is(push!(d, 'b' => 2, 'c' => 3), d)
@test d['b'] == 2
@test d['c'] == 3
@test is(push!(d, 'd' => 4, 'e' => 5, 'f' => 6), d)
@test d['d'] == 4
@test d['e'] == 5
@test d['f'] == 6
@test length(d) == 6
end
6 changes: 3 additions & 3 deletions test/test_orderedset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ s3 = OrderedSet{ASCIIString}(["baz"])
@test !isequal(OrderedSet(), OrderedSet([1]))
@test isequal(OrderedSet{Any}(Any[1,2]), OrderedSet{Int}([1,2]))
@test !isequal(OrderedSet{Any}(Any[1,2]), OrderedSet{Int}([1,2,3]))
# Comparison of unrelated types seems rather inconsistent

@test isequal(OrderedSet{Int}(), OrderedSet{AbstractString}())
@test !isequal(OrderedSet{Int}(), OrderedSet{AbstractString}([""]))
@test !isequal(OrderedSet{AbstractString}(), OrderedSet{Int}([0]))
Expand All @@ -48,8 +48,8 @@ s2 = similar(OrderedSet{Float32}([2.0f0,3.0f0,4.0f0]))
@test is(eltype(s2), Float32)

# show
@test sprint(show, OrderedSet()) == "DataStructures.OrderedSet{Any}()"
@test sprint(show, OrderedSet(['a'])) == "DataStructures.OrderedSet{Char}(['a'])"
@test endswith(sprint(show, OrderedSet()), "OrderedSet{Any}()")
@test endswith(sprint(show, OrderedSet(['a'])), "OrderedSet{Char}(['a'])")

s = OrderedSet(); push!(s,1); push!(s,2); push!(s,3)
@test !isempty(s)
Expand Down

0 comments on commit 4c6e6d0

Please sign in to comment.