∞
#web-development
Table-driven tests
I am enjoying this approach to testing code while reading and studying. No need for minitest or any testing framework. Just write code and test it in the same file. Allows me move quickly and focus on the code.
If I were to use this code in a real project I would extract the tests into a separate file and use a testing framework. But for now, while tinkering and learning, this is a great way to test code.
I believe this qualifies as table-driven testing. Running the same set of tests with different inputs and expected outputs, organized in a table-like structure.
eg:
$ ruby recursive-algorithms.rb
"#quicksort! | [0, 1, 2, 3, 5, 6] = [0, 1, 2, 3, 5, 6] | true"
"#quickselect! | 10 = 10 | true"
"#greatest_product_of_three_numbers | 90000 = 90000 | true"
"#find_missing_number | 3 = 3 | true"
"#find_missing_number | 8 = 8 | true"
My ruby file recursive-algorithms.rb
:
# Quicksort.
class SortableArray
attr_reader :array
def initialize(array)
@array = array
end
def partition!(left_pointer, right_pointer)
pivot_index = right_pointer
pivot = @array[pivot_index]
right_pointer -= 1
while true
while @array[left_pointer] < pivot do
left_pointer += 1
end
while @array[right_pointer] > pivot do
right_pointer -= 1
end
if left_pointer >= right_pointer
break
else
@array[left_pointer], @array[right_pointer] = @array[right_pointer], @array[left_pointer]
left_pointer += 1
end
end
@array[left_pointer], @array[pivot_index] = @array[pivot_index], @array[left_pointer]
return left_pointer
end
def quicksort!(left_index, right_index)
if right_index - left_index <= 0
return
end
pivot_index = partition!(left_index, right_index)
quicksort!(left_index, pivot_index - 1)
quicksort!(pivot_index + 1, right_index)
end
def quickselect!(kth_lowest_value, left_index, right_index)
if right_index - left_index <= 0
return @array[left_index]
end
pivot_index = partition!(left_index, right_index)
if kth_lowest_value < pivot_index
quickselect!(kth_lowest_value, left_index, pivot_index - 1)
elsif kth_lowest_value > pivot_index
quickselect!(kth_lowest_value, pivot_index + 1, right_index)
else
return @array[pivot_index]
end
end
end
def greatest_product_of_three_numbers(array)
sa = SortableArray.new(array)
sa.quicksort! 0, array.length - 1
return sa.array[-3] * sa.array[-2] * sa.array[-1]
end
def find_missing_number(array)
sa = SortableArray.new(array)
sa.quicksort! 0, array.length - 1
sa.array.each_with_index do |value, i|
if i != value
return i
end
end
end
# TESTS
[
[[0, 5, 2, 1, 6, 3], [0, 1, 2, 3, 5, 6]]
].each do |test, expected|
sa = SortableArray.new(test)
sa.quicksort! 0, test.length - 1
pp "#quicksort! | #{sa.array} = #{expected} | #{sa.array == expected}"
end
[
[[0, 50, 20, 10, 60, 30], 10]
].each do |test, expected|
sa = SortableArray.new(test)
ret = sa.quickselect! 1, 0, test.length - 1
pp "#quickselect! | #{ret} = #{expected} | #{ret == expected}"
end
[
[[0, 50, 20, 10, 60, 30], 90000]
].each do |test, expected|
ret = greatest_product_of_three_numbers(test)
pp "#greatest_product_of_three_numbers | #{ret} = #{expected} | #{ret == expected}"
end
[
[[5, 2, 4, 1, 0], 3],
[[9, 3, 2, 5, 6, 7, 1, 0, 4], 8]
].each do |test, expected|
ret = find_missing_number(test)
pp "#find_missing_number | #{ret} = #{expected} | #{ret == expected}"
end