Skip to content

Commit

Permalink
Luhn with generator (#559)
Browse files Browse the repository at this point in the history
Test generator for Luhn, with example solution
  • Loading branch information
hilary authored and Insti committed Apr 21, 2017
1 parent 4c702ea commit 348672a
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 50 deletions.
1 change: 1 addition & 0 deletions exercises/luhn/.meta/.version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
41 changes: 18 additions & 23 deletions exercises/luhn/example.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
class Luhn
def self.create(number)
test_number = number * 10
luhn = Luhn.new(test_number)
return test_number if luhn.valid?
test_number + 10 - (luhn.checksum % 10)
end
DOUBLE = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
DOUBLE.freeze

attr_reader :number
def initialize(number)
@number = number
def self.valid?(string)
Luhn.new(string).valid?
end

def addends
numbers = []
number.to_s.reverse.split('').map(&:to_i).each_with_index do |n, i|
if i % 2 == 0
numbers << n
else
value = n * 2
value -= 9 if value > 9
numbers << value
end
end
numbers.reverse
def initialize(string)
@string = string.tr(' ', '')
end

def checksum
addends.inject(0, :+)
@string.
reverse.each_char.with_index.
reduce(0) {|sum, (c, i)| sum + (i.odd? ? DOUBLE[c.to_i] : c.to_i) }
end

def valid?
checksum % 10 == 0
clean? && (checksum % 10).zero?
end

def clean?
@string.match(/^\d{2,}$/)
end
end

module BookKeeping
VERSION = 1
end
18 changes: 18 additions & 0 deletions exercises/luhn/example.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env ruby
gem 'minitest', '>= 5.0.0'
require 'minitest/autorun'
require_relative 'luhn'

# Common test data version: <%= abbreviated_commit_hash %>
class LuhnTest < Minitest::Test<% test_cases.each do |test_case| %>
def <%= test_case.name %>
<%= test_case.skipped %>
<%= test_case.workload %>
end
<% end %>
<%= IO.read(XRUBY_LIB + '/bookkeeping.md') %>
def test_bookkeeping
skip
assert_equal <%= version %>, BookKeeping::VERSION
end
end
87 changes: 60 additions & 27 deletions exercises/luhn/luhn_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,90 @@
require 'minitest/autorun'
require_relative 'luhn'

# Common test data version: c826372
class LuhnTest < Minitest::Test
def test_addends
luhn = Luhn.new(12_121)
assert_equal [1, 4, 1, 4, 1], luhn.addends
def test_single_digit_strings_can_not_be_valid
# skip
refute Luhn.valid?("1")
end

def test_too_large_addend
def test_A_single_zero_is_invalid
skip
luhn = Luhn.new(8631)
assert_equal [7, 6, 6, 1], luhn.addends
refute Luhn.valid?("0")
end

def test_checksum
def test_a_simple_valid_SIN_that_remains_valid_if_reversed
skip
luhn = Luhn.new(4913)
assert_equal 22, luhn.checksum
assert Luhn.valid?("059")
end

def test_checksum_again
def test_a_simple_valid_SIN_that_becomes_invalid_if_reversed
skip
luhn = Luhn.new(201_773)
assert_equal 21, luhn.checksum
assert Luhn.valid?("59")
end

def test_invalid_number
def test_a_valid_Canadian_SIN
skip
luhn = Luhn.new(738)
refute luhn.valid?
assert Luhn.valid?("055 444 285")
end

def test_valid_number
def test_invalid_Canadian_SIN
skip
luhn = Luhn.new(8_739_567)
assert luhn.valid?
refute Luhn.valid?("055 444 286")
end

def test_create_valid_number
def test_invalid_credit_card
skip
number = Luhn.create(123)
assert_equal 1230, number
refute Luhn.valid?("8273 1232 7352 0569")
end

def test_create_other_valid_number
def test_valid_strings_with_a_non_digit_included_become_invalid
skip
number = Luhn.create(873_956)
assert_equal 8_739_567, number
refute Luhn.valid?("055a 444 285")
end

def test_create_yet_another_valid_number
def test_valid_strings_with_punctuation_included_become_invalid
skip
number = Luhn.create(837_263_756)
assert_equal 8_372_637_564, number
refute Luhn.valid?("055-444-285")
end

def test_valid_strings_with_symbols_included_become_invalid
skip
refute Luhn.valid?("055£ 444$ 285")
end

def test_single_zero_with_space_is_invalid
skip
refute Luhn.valid?(" 0")
end

def test_more_than_a_single_zero_is_valid
skip
assert Luhn.valid?("0000 0")
end

def test_input_digit_9_is_correctly_converted_to_output_digit_9
skip
assert Luhn.valid?("091")
end
# Problems in exercism evolve over time, as we find better ways to ask
# questions.
# The version number refers to the version of the problem you solved,
# not your solution.
#
# Define a constant named VERSION inside of the top level BookKeeping
# module, which may be placed near the end of your file.
#
# In your file, it will look like this:
#
# module BookKeeping
# VERSION = 1 # Where the version number matches the one in the test.
# end
#
# If you are curious, read more about constants on RubyDoc:
# http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
def test_bookkeeping
skip
assert_equal 1, BookKeeping::VERSION
end
end
27 changes: 27 additions & 0 deletions lib/luhn_cases.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'exercise_cases'

class LuhnCase < OpenStruct
def name
'test_%s' % description.tr('- ', '__')
end

def workload
%Q(#{assertion} Luhn.valid?(#{input.inspect}))
end

def skipped
index.zero? ? '# skip' : 'skip'
end

private

def assertion
expected ? 'assert' : 'refute'
end
end

LuhnCases = proc do |data|
JSON.parse(data)['cases'].map.with_index do |row, i|
LuhnCase.new(row.merge('index' => i))
end
end

0 comments on commit 348672a

Please sign in to comment.