From 93271c78e1ddd3779d2e405ddad07149cd4cf80a Mon Sep 17 00:00:00 2001 From: Matthaus Owens Date: Sat, 18 Feb 2017 18:53:21 -0800 Subject: [PATCH 1/2] Issue #159: Update luhn test and implementation Changes to x-common updated the tests and description for luhn to only test the validity check and not test addends or check digit generation. This commit adds a test generator for the luhn exercise and updates the example solution to pass the updated tests. In moving to use the canonical test data, the inputs to luhn are now strings, so the example solution was also updated to take that into account. --- exercises/luhn/luhn.mustache | 9 +++++ exercises/luhn/src/example.clj | 13 +++++-- exercises/luhn/test/luhn_test.clj | 58 +++++++++++++++---------------- 3 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 exercises/luhn/luhn.mustache diff --git a/exercises/luhn/luhn.mustache b/exercises/luhn/luhn.mustache new file mode 100644 index 000000000..7a91a5dcd --- /dev/null +++ b/exercises/luhn/luhn.mustache @@ -0,0 +1,9 @@ +(ns luhn-test + (:require [clojure.test :refer [deftest is testing]] + luhn)) + +(deftest validity-tests +{{#valid}} + (testing "{{{description}}}" + (is ({{{expected}}}? (luhn/valid? "{{{input}}}")))) +{{/valid}}) diff --git a/exercises/luhn/src/example.clj b/exercises/luhn/src/example.clj index 7f41eec95..649fca657 100644 --- a/exercises/luhn/src/example.clj +++ b/exercises/luhn/src/example.clj @@ -1,4 +1,5 @@ -(ns luhn) +(ns luhn + (:require [clojure.string :as string])) (defn to-reversed-digits "returns a lazy sequence of least to most significant digits of n" @@ -19,10 +20,18 @@ (apply +)) (mod 10))) +(defn string->long + "Strips any non-digit characters and converts the string into a Long" + [n] + (-> n (string/replace #"[^0-9]+" "") Long/parseLong)) + (defn valid? "whether n has a valid luhn check-digit" [n] - (zero? (checksum n))) + ; Numbers with non digit/whitespace or only 1 digit are invalid + (if (or (re-find #"[^0-9\s]+" n) (>= 1 (count (string/trim n)))) + false + (zero? (-> n string->long checksum)))) (defn add-check-digit "given a number, adds a luhn check digit at the end" diff --git a/exercises/luhn/test/luhn_test.clj b/exercises/luhn/test/luhn_test.clj index d13d7b1a6..174039cfd 100644 --- a/exercises/luhn/test/luhn_test.clj +++ b/exercises/luhn/test/luhn_test.clj @@ -1,32 +1,32 @@ (ns luhn-test - (:require [clojure.test :refer [deftest is]] + (:require [clojure.test :refer [deftest is testing]] luhn)) -(deftest checksum-works - (is (= 2 (luhn/checksum 10))) - (is (= 9 (luhn/checksum 90))) - (is (= 1 (luhn/checksum 100))) - (is (= 2 (luhn/checksum 1000))) - (is (= 1 (luhn/checksum 10000000000000000))) - (is (= 6 (luhn/checksum 1111))) - (is (= 0 (luhn/checksum 8763))) - (is (= 0 (luhn/checksum 2323200577663554)))) - -(deftest valid?-works - (is (= true (luhn/valid? 18))) - (is (= true (luhn/valid? 59))) - (is (= false (luhn/valid? 63))) - (is (= true (luhn/valid? 8763))) - (is (= false (luhn/valid? 1111))) - (is (= true (luhn/valid? 4242424242424242))) - (is (= true (luhn/valid? 2323200577663554))) - (is (= false (luhn/valid? 2323200577663555))) - (is (= false (luhn/valid? 2223200577663554))) - (is (= false (luhn/valid? 3323200577663554)))) - -(deftest add-check-digit-works - (is (= 18 (luhn/add-check-digit 1))) - (is (= 59 (luhn/add-check-digit 5))) - (is (= 8763 (luhn/add-check-digit 876))) - (is (= 4242424242424242 (luhn/add-check-digit 424242424242424))) - (is (= 2323200577663554 (luhn/add-check-digit 232320057766355)))) +(deftest validity-tests + (testing "single digit strings can not be valid" + (is (false? (luhn/valid? "1")))) + (testing "A single zero is invalid" + (is (false? (luhn/valid? "0")))) + (testing "simple valid sin" + (is (true? (luhn/valid? " 5 9 ")))) + (testing "valid Canadian SIN" + (is (true? (luhn/valid? "046 454 286")))) + (testing "invalid Canadian SIN" + (is (false? (luhn/valid? "046 454 287")))) + (testing "invalid credit card" + (is (false? (luhn/valid? "8273 1232 7352 0569")))) + (testing "valid strings with a non-digit added become invalid" + (is (false? (luhn/valid? "046a 454 286")))) + (testing "punctuation is not allowed" + (is (false? (luhn/valid? "055-444-285")))) + (testing "symbols are not allowed" + (is (false? (luhn/valid? "055£ 444$ 285")))) + (testing "single zero with space is invalid" + (is (false? (luhn/valid? " 0")))) + (testing "lots of zeros are valid" + (is (true? (luhn/valid? " 00000")))) + (testing "another valid sin" + (is (true? (luhn/valid? "055 444 285")))) + (testing "nine doubled is nine" + (is (true? (luhn/valid? "091")))) +) From 6d8f797a8006bd63c8d96a67b9da3b9f5fcda837 Mon Sep 17 00:00:00 2001 From: Matthaus Owens Date: Sat, 18 Feb 2017 21:10:07 -0800 Subject: [PATCH 2/2] Remove unused function from luhn exercise --- exercises/luhn/src/example.clj | 7 ------- 1 file changed, 7 deletions(-) diff --git a/exercises/luhn/src/example.clj b/exercises/luhn/src/example.clj index 649fca657..c6b452111 100644 --- a/exercises/luhn/src/example.clj +++ b/exercises/luhn/src/example.clj @@ -32,10 +32,3 @@ (if (or (re-find #"[^0-9\s]+" n) (>= 1 (count (string/trim n)))) false (zero? (-> n string->long checksum)))) - -(defn add-check-digit - "given a number, adds a luhn check digit at the end" - [n] - (let [n-shifted (* 10 n) - check-digit (- 10 (checksum n-shifted))] - (+ n-shifted check-digit)))