-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathabout_hashes.rb
128 lines (101 loc) · 3.48 KB
/
about_hashes.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
require File.expand_path(File.dirname(__FILE__) + '/neo')
class AboutHashes < Neo::Koan
def test_creating_hashes
empty_hash = Hash.new
assert_equal Hash, empty_hash.class
assert_equal(Hash.new, empty_hash)
assert_equal 0, empty_hash.size
end
def test_hash_literals
hash = { :one => "uno", :two => "dos" }
assert_equal 2, hash.size
end
def test_accessing_hashes
hash = { :one => "uno", :two => "dos" }
assert_equal "uno", hash[:one]
assert_equal "dos", hash[:two]
assert_equal nil, hash[:doesnt_exist]
end
def test_accessing_hashes_with_fetch
hash = { :one => "uno" }
assert_equal "uno", hash.fetch(:one)
assert_raise(KeyError) do
hash.fetch(:doesnt_exist)
end
# THINK ABOUT IT:
#
# Why might you want to use #fetch instead of #[] when accessing hash keys?
#
# Accessing a hash key that doesn't exist using brackets will return nil,
# while accessing a hash key that doesn't exist using .fetch will return a
# KeyError: key not found: :key if the key is passed without a second argument
# If second argument is passed, the non-existent key will be created, and the
# second argument will be the value of newly created key.
end
def test_changing_hashes
hash = { :one => "uno", :two => "dos" }
hash[:one] = "eins"
expected = { :one => "eins", :two => "dos" }
assert_equal expected, hash
# Bonus Question: Why was "expected" broken out into a variable
# rather than used as a literal?
end
def test_hash_is_unordered
hash1 = { :one => "uno", :two => "dos" }
hash2 = { :two => "dos", :one => "uno" }
assert_equal true, hash1 == hash2
end
def test_hash_keys
hash = { :one => "uno", :two => "dos" }
assert_equal 2, hash.keys.size
assert_equal true, hash.keys.include?(:one)
assert_equal true, hash.keys.include?(:two)
assert_equal Array, hash.keys.class
# Why does hash.keys.class return Array?
#
# Because Hash#keys returns the hash's keys as a new array.
# The hash and the array returned by Hash#keys are completely
# independent of each other
end
def test_hash_values
hash = { :one => "uno", :two => "dos" }
assert_equal 2, hash.values.size
assert_equal true, hash.values.include?("uno")
assert_equal true, hash.values.include?("dos")
assert_equal Array, hash.values.class
end
def test_combining_hashes
hash = { "jim" => 53, "amy" => 20, "dan" => 23 }
new_hash = hash.merge({ "jim" => 54, "jenny" => 26 })
assert_equal true, hash != new_hash
expected = { "jim" => 54, "amy" => 20, "dan" => 23, "jenny" => 26 }
assert_equal true, expected == new_hash
end
def test_default_value
hash1 = Hash.new
hash1[:one] = 1
assert_equal 1, hash1[:one]
assert_equal nil, hash1[:two]
hash2 = Hash.new("dos")
hash2[:one] = 1
assert_equal 1, hash2[:one]
assert_equal "dos", hash2[:two]
end
def test_default_value_is_the_same_object
hash = Hash.new([])
hash[:one] << "uno"
hash[:two] << "dos"
assert_equal ["uno", "dos"], hash[:one]
assert_equal ["uno", "dos"], hash[:two]
assert_equal ["uno", "dos"], hash[:three]
assert_equal true, hash[:one].object_id == hash[:two].object_id
end
def test_default_value_with_block
hash = Hash.new {|hash, key| hash[key] = [] }
hash[:one] << "uno"
hash[:two] << "dos"
assert_equal ["uno"], hash[:one]
assert_equal ["dos"], hash[:two]
assert_equal [], hash[:three]
end
end