Skip to content

Instantly share code, notes, and snippets.

@mFingers
Last active August 29, 2015 14:18
Show Gist options
  • Save mFingers/74b4b7c370a2c832ce6c to your computer and use it in GitHub Desktop.
Save mFingers/74b4b7c370a2c832ce6c to your computer and use it in GitHub Desktop.
Unit tests and production code for the credit card validator kata.
using System;
using System.Collections.Generic;
using System.Linq;
namespace CreditCardValidator {
public class CreditCard {
private string ccNumber;
private const int minThreshold = 13;
private const int maxThreshold = 16;
private readonly int[] substitutionDigits = new int[]{
0, 2, 4, 6, 8, 1, 3, 5, 7, 9
};
public CreditCard(string creditCardNumber) {
ccNumber = creditCardNumber;
}
public bool IsValid() {
return
!String.IsNullOrEmpty(ccNumber) &&
ccNumber.All(Char.IsDigit) &&
ccNumber.Length <= maxThreshold &&
ccNumber.Length >= minThreshold &&
GetChecksum() % 10 == 0;
}
public int GetChecksum() {
return ConvertToNumbers(ccNumber)
.Select((c, i) => {
if (i % 2 == 0) {
return substitutionDigits[c];
}
else {
return c;
}
}).Sum();
}
private IEnumerable<int> ConvertToNumbers(string ccNumber) {
var asNumbers = ccNumber.PadLeft(maxThreshold, '0')
.Select(c => Int32.Parse(c.ToString()));
return asNumbers;
}
}
}
using NUnit.Framework;
namespace CreditCardValidator.Tests {
/*
* Test card numbers from http://testcreditcardnumbers.com/
*/
[TestFixture]
public class ValidateFixture {
[TestCase("")]
[TestCase(" ")]
[TestCase(null)]
public void EmptyCardNumber(string ccNumber) {
var cc = new CreditCard(ccNumber);
Assert.False(cc.IsValid());
}
[TestCase("1234g6345")]
[TestCase("908234*&775")]
public void NonDigitCharactersAreInvalid(string ccNumber) {
var cc = new CreditCard(ccNumber);
Assert.False(cc.IsValid());
}
[TestCase("111111111111", false)]
[TestCase("4222222222222", true)]
[TestCase("30569309025904", true)]
[TestCase("371449635398431", true)]
[TestCase("4111111111111111", true)]
[TestCase("11111111111111111", false)]
public void CreditCardLength(string ccNumber, bool isValid) {
var cc = new CreditCard(ccNumber);
Assert.AreEqual(isValid, cc.IsValid());
}
[Test]
public void SixteenDigitChecksumSumsOddIndexes() {
var cc = new CreditCard("0101010101010101");
Assert.AreEqual(8, cc.GetChecksum());
}
[Test]
public void LessThanSixteenPadsToSixteenBeforeChecksumCalc() {
var cc = new CreditCard("0101010101010");
Assert.AreEqual(12, cc.GetChecksum());
}
[TestCase("0", 0)]
[TestCase("1", 2)]
[TestCase("2", 4)]
[TestCase("3", 6)]
[TestCase("4", 8)]
[TestCase("5", 1)]
[TestCase("6", 3)]
[TestCase("7", 5)]
[TestCase("8", 7)]
[TestCase("9", 9)]
public void SubstitutionLookups(string digit, int substitutionDigit) {
var cc = new CreditCard(digit + "000000000000000");
Assert.AreEqual(substitutionDigit, cc.GetChecksum());
}
[Test]
public void ChecksumNotEndingInZeroIsInvalid() {
var cc = new CreditCard("0101010101010101");
Assert.False(cc.IsValid());
}
[Test]
public void ValidCardNumberIsValid() {
var cc = new CreditCard("5111111111111118");
Assert.True(cc.IsValid());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment