Write tests
create word/word.go. The code has a problem: it use byte sequance and not rune sequance.
package word
// IsPalindrome reports whether s reads the same forward and backward.
// (Our first attempt.)
func IsPalindrome(s string) bool {
for i := range s {
if s[i] != s[len(s) - 1 - i] {
return false
}
}
return true
}
create word/word_test.go
package word
import "testing"
func TestPalindrome(t *testing.T) {
if !IsPalindrome("detartrated") {
t.Error("IsPalindrome('detartrated') = false")
}
if !IsPalindrome("kayak") {
t.Error("IsPalindrome('kayak') = false")
}
}
func TestNonPalindrome(t *testing.T) {
if IsPalindrome("palindrome") {
t.Error("IsPalindrome('palindrome') = true")
}
}
add more tests to word_test.go to investigate bugs
package word
import "testing"
func TestPalindrome(t *testing.T) {
if !IsPalindrome("detartrated") {
t.Error("IsPalindrome('detartrated') = false")
}
if !IsPalindrome("kayak") {
t.Error("IsPalindrome('kayak') = false")
}
}
func TestNonPalindrome(t *testing.T) {
if IsPalindrome("palindrome") {
t.Error("IsPalindrome('palindrome') = true")
}
}
func TestFrenchPalindrome(t *testing.T) {
if !IsPalindrome("été") {
t.Error("IsPalindrome('été') = false")
}
}
func TestCanalPalindrome(t *testing.T) {
input := "A man, a plan, a canal: Panama"
if !IsPalindrome(input) {
t.Errorf("IsPalindrome(%q) = false", input)
}
}
go test -v // verbose
go test -v -run="French|Canal" // run only the regular expressions that match French and Canal
Fix tests
change word/word.go. Change the code to use a rune sequance.
// Package word provides utilities for word games.
package word
import "unicode"
// IsPalindrome reports whether s reads the same forward and backward.
// (Our first attempt.)
func IsPalindrome(s string) bool {
var letters []rune
for _, r := range s {
if unicode.IsLetter(r) {
letters = append(letters, unicode.ToLower(r))
}
}
for i := range letters {
if letters[i] != letters[len(letters) - 1 - i] {
return false
}
}
return true
}
change word/word_test.go
package word
import "testing"
func TestIsPalindrome(t *testing.T) {
var tests = []struct {
input string
want bool
}{
{"", true},
{"a", true},
{"aa", true},
{"ab", false},
{"kayak", true},
{"detartrated", true},
{"A man, a plan, a canal: Panama", true},
{"Evil I did dwell; lewd did I live.", true},
{"Able was I ere I saw Elba", true},
{"été", true},
{"Et se resservir, ivresse reste.", true},
{"palindrome", false}, // non-palindrome
{"desserts", false},
// semi-palindrome
}
for _, test := range tests {
if got := IsPalindrome(test.input); got != test.want {
t.Errorf("IsPalindrome(%q) = %v", test.input, got)
}
}
}