2382d68cd483a43803ce3272ff99b8e737853f14
[ruby_koans.git] / src / about_hashes.rb
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 class AboutHashes < EdgeCase::Koan
4   def test_creating_hashes
5     empty_hash = Hash.new
6     assert_equal __(Hash), empty_hash.class
7     assert_equal({}, empty_hash) # __
8     assert_equal __(0), empty_hash.size
9   end
10
11   def test_hash_literals
12     hash = { :one => "uno", :two => "dos" }
13     assert_equal __(2), hash.size
14   end
15
16   def test_accessing_hashes
17     hash = { :one => "uno", :two => "dos" }
18     assert_equal __("uno"), hash[:one]
19     assert_equal __("dos"), hash[:two]
20     assert_equal __(nil), hash[:doesnt_exist]
21   end
22
23   def test_accessing_hashes_with_fetch
24     hash = { :one => "uno" }
25     assert_equal __("uno"), hash.fetch(:one)
26     assert_raise(___(IndexError, KeyError)) do
27       hash.fetch(:doesnt_exist)
28     end
29
30     # THINK ABOUT IT:
31     #
32     # Why might you want to use #fetch instead of #[] when accessing hash keys?
33   end
34
35   def test_changing_hashes
36     hash = { :one => "uno", :two => "dos" }
37     hash[:one] = "eins"
38
39     expected = { :one => __("eins"), :two => "dos" }
40     assert_equal __(true), expected == hash
41
42     # Bonus Question: Why was "expected" broken out into a variable
43     # rather than used as a literal?
44   end
45
46   def test_hash_is_unordered
47     hash1 = { :one => "uno", :two => "dos" }
48     hash2 = { :two => "dos", :one => "uno" }
49
50     assert_equal __(true), hash1 == hash2
51   end
52
53   def test_hash_keys
54     hash = { :one => "uno", :two => "dos" }
55     assert_equal __(2), hash.keys.size
56     assert_equal __(true), hash.keys.include?(:one)
57     assert_equal __(true), hash.keys.include?(:two)
58     assert_equal __(Array), hash.keys.class
59   end
60
61   def test_hash_values
62     hash = { :one => "uno", :two => "dos" }
63     assert_equal __(2), hash.values.size
64     assert_equal __(true), hash.values.include?("uno")
65     assert_equal __(true), hash.values.include?("dos")
66     assert_equal __(Array), hash.values.class
67   end
68
69   def test_combining_hashes
70     hash = { "jim" => 53, "amy" => 20, "dan" => 23 }
71     new_hash = hash.merge({ "jim" => 54, "jenny" => 26 })
72
73     assert_equal __(true), hash != new_hash
74
75     expected = { "jim" => __(54), "amy" => 20, "dan" => 23, "jenny" => __(26) }
76     assert_equal __(true), expected == new_hash
77   end
78
79   def test_default_value
80     hash1 = Hash.new
81     hash1[:one] = 1
82
83     assert_equal __(1), hash1[:one]
84     assert_equal __(nil), hash1[:two]
85
86     hash2 = Hash.new("dos")
87     hash2[:one] = 1
88
89     assert_equal __(1), hash2[:one]
90     assert_equal __("dos"), hash2[:two]
91   end
92
93   def test_default_value_is_the_same_object
94     hash = Hash.new([])
95
96     hash[:one] << "uno"
97     hash[:two] << "dos"
98
99     assert_equal __(["uno", "dos"]), hash[:one]
100     assert_equal __(["uno", "dos"]), hash[:two]
101     assert_equal __(["uno", "dos"]), hash[:three]
102
103     assert_equal __(true), hash[:one].object_id == hash[:two].object_id
104   end
105
106   def test_default_value_with_block
107     hash = Hash.new {|hash, key| hash[key] = [] }
108
109     hash[:one] << "uno"
110     hash[:two] << "dos"
111
112     assert_equal __(["uno"]), hash[:one]
113     assert_equal __(["dos"]), hash[:two]
114     assert_equal __([]), hash[:three]
115   end
116 end