#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

Interactions

No Webmentions yet. Be the first to interact with this post!
← An IndieWeb Webring πŸ•ΈπŸ’ β†’