-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlinked_list_test.rb
211 lines (165 loc) Β· 5.69 KB
/
linked_list_test.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
require_relative "../../test_helper"
require_relative "linked_list"
require_relative "node"
describe LinkedList do
describe "#get" do
subject { LinkedList.generate(1, 2, 3, 4) }
it "should return the node" do
expect(subject.get(1).value).must_equal 1
expect(subject.get(2).value).must_equal 2
expect(subject.get(3).value).must_equal 3
expect(subject.get(4).value).must_equal 4
end
describe "when querying an empty list" do
it "should print an error message" do
_ { LinkedList.new.get(1) }.must_output(/No node at index 1/)
end
end
end
describe "#append" do
subject { LinkedList.new }
it "should work for empty lists" do
expect(subject.head).must_be_nil
expect(subject.tail).must_be_nil
subject.append Node.new(1)
expect(subject.head.value).must_equal 1
expect(subject.head).wont_be_nil
expect(subject.tail).wont_be_nil
end
it "should work for populated lists" do
subject = LinkedList.generate(1, 2, 3, 4)
subject.append Node.new(5)
expect(subject.tail.value).must_equal 5
end
end
describe "#delete" do
subject { LinkedList.generate(1, 2, 3, 4, 5) }
it "should return nil if input node is nil" do
subject.delete(nil, nil)
expect(subject.head.value).must_equal 1
expect(subject.tail.value).must_equal 5
end
it "should remove a head node" do
node = subject.head
prev_node = nil
subject.delete(node, prev_node)
expect(subject.head).wont_equal node
expect(subject.head).must_equal node.next
end
it "should remove a tail node" do
node = subject.tail
prev_node = subject.get(4)
# Make sure that prev_node is indeed 1 before the tail
expect(prev_node.next).must_equal node
subject.delete(node, prev_node)
expect(subject.tail).must_equal prev_node
expect(subject.tail.value).must_equal 4
expect(subject.tail.next).must_be_nil
expect(subject.get(3).next).must_equal subject.tail
end
it "should remove a node in the middle" do
node = subject.get(3)
prev_node = subject.get(2)
subject.delete(node, prev_node)
expect(prev_node.next.value).must_equal 4
expect(subject.tail.value).must_equal 5
end
end
describe "#create_cycle_at" do
subject { LinkedList.generate(1, 2, 3, 4, 5) }
it "should continue from the tail back to 3rd node" do
target_node = subject.get(3)
subject.create_cycle_at(target_node)
expect(subject.tail.next).wont_be_nil
expect(subject.tail.next).must_equal subject.get(3)
end
end
describe "#cycle?" do
subject { LinkedList.generate(1, 2, 3, 4, 5) }
it "should return true when cycle exists" do
target_node = subject.get(3)
subject.create_cycle_at(target_node)
expect(subject.cycle?).must_equal true
expect(subject.tail.next).wont_be_nil
end
it "should return false when cycle does not exist" do
expect(subject.cycle?).wont_equal true
expect(subject.tail.next).must_be_nil
end
end
describe "#cycle_length" do
subject { LinkedList.generate(1, 2, 3, 4, 5, 6, 7, 8) }
describe "edge cases" do
it "should return -1 when no cycle present" do
expect(subject.cycle_length).must_equal(-1)
end
end
describe "base cases" do
it "should calculate cycle length of 1" do
subject.create_cycle_at(subject.get(8))
expect(subject.cycle_length).must_equal 1
end
it "should calculate cycle length of 2" do
subject.create_cycle_at(subject.get(7))
expect(subject.cycle_length).must_equal 2
end
it "should calculate cycle length of 3" do
subject.create_cycle_at(subject.get(6))
expect(subject.cycle_length).must_equal 3
end
end
describe "regular cases" do
it "should calculate an odd cycle" do
subject.create_cycle_at(subject.get(4))
expect(subject.cycle_length).must_equal 5
end
it "should calculate an even cycle" do
subject.create_cycle_at(subject.get(3))
expect(subject.cycle_length).must_equal 6
end
it "should work when whole list is a cycle" do
subject.create_cycle_at(subject.get(1))
expect(subject.cycle_length).must_equal 8
end
end
end
describe "#median" do
subject { LinkedList.new }
describe "edge cases" do
it "should return nil for an empty list" do
expect(subject.median).must_be_nil
end
end
describe "base cases" do
it "should return first node in single node list" do
[1].each { |i| subject.append(Node.new(i)) }
expect(subject.median.value).must_equal 1
end
end
describe "regular case" do
it "should work for list of 2 nodes" do
[1, 2].each { |i| subject.append(Node.new(i)) }
expect(subject.median.value).must_equal 1
end
it "should work for list of 3 nodes" do
[1, 2, 3].each { |i| subject.append(Node.new(i)) }
expect(subject.median.value).must_equal 2
end
it "should work for list with an even amount of nodes" do
[1, 2, 3, 4].each { |i| subject.append(Node.new(i)) }
expect(subject.median.value).must_equal 2
end
it "should work for a list with an odd amount of nodes" do
[1, 2, 3, 4, 5].each { |i| subject.append(Node.new(i)) }
expect(subject.median.value).must_equal 3
end
end
end
describe "#cycle_head" do
subject { LinkedList.generate(1, 2, 3, 4, 5, 6, 7, 8, 9) }
it "should find the beginning of the cycle" do
subject.create_cycle_at(subject.get(7))
expect(subject.cycle_head).must_equal subject.get(7)
end
end
end