CodeBlanks Logo Icon CodeBlanks

Challenge 3 - Test and benchmark

Write a test and benchmark for a function.

Challenge: tests and benchmarks

You will write a slug function, verify it with a table test and compare two implementations with a benchmark. Rules: lower-case it, convert Turkish letters to their ASCII counterparts (ç→c, ğ→g, ı→i, ö→o, ş→s, ü→u), turn everything that isn't a letter or digit into a single dash, and drop leading and trailing dashes.

Slug("Merhaba Dünya!")      // merhaba-dunya
Slug("  Go ile Web  ")      // go-ile-web
Slug("Çay & Şeker")         // cay-seker

Plan

Walk the runes with a strings.Builder: map Turkish letters with a map[rune]rune and apply unicode.ToLower; append if it's a letter/digit, otherwise append a dash unless the last appended character was a dash. Finish with strings.Trim(s, "-"). Run the table test in main with an anonymous struct slice; measure allocations with testing.AllocsPerRun.

Practice Slug and its test

Write the Slug function and try the three cases above with a table test. Print the number of passing cases.

Starter code

main.go
package main

import (
    "fmt"
    "strings"
    "unicode"
)

func main() {
    // buraya yaz
}

Sample solution

main.go
package main

import (
    "fmt"
    "strings"
    "unicode"
)

var trHarf = map[rune]rune{'ç': 'c', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u', 'Ç': 'c', 'Ğ': 'g', 'İ': 'i', 'Ö': 'o', 'Ş': 's', 'Ü': 'u'}

func Slug(s string) string {
    var b strings.Builder
    tire := false
    for _, r := range s {
        if t, ok := trHarf[r]; ok {
            r = t
        }
        r = unicode.ToLower(r)
        if unicode.IsLetter(r) || unicode.IsDigit(r) {
            b.WriteRune(r)
            tire = false
        } else if !tire {
            b.WriteByte('-')
            tire = true
        }
    }
    return strings.Trim(b.String(), "-")
}

func main() {
    tests := []struct{ in, want string }{
        {"Merhaba Dünya!", "merhaba-dunya"},
        {"  Go ile Web  ", "go-ile-web"},
        {"Çay & Şeker", "cay-seker"},
    }
    gecen := 0
    for _, tt := range tests {
        if Slug(tt.in) == tt.want {
            gecen++
        }
    }
    fmt.Println(gecen)
}

Expected output

3

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Why does <code>strings.ToLower("İ")</code> need care?

  • It doesn't change
  • It becomes ı
  • Turkish İ lowercases to "i" plus a combining dot (i̇) Correct answer
  • It errors

Explanation: Under the default Unicode rule İ (U+0130) becomes "i̇"; for Turkish rules use unicode.TurkishCase or a manual mapping.

2 Is it a letter?

Question
if unicode.____(r) || unicode.IsDigit(r) {
    b.WriteRune(r)
}
Answer
if unicode.IsLetter(r) || unicode.IsDigit(r) {
    b.WriteRune(r)
}

Explanation: unicode.IsLetter recognizes Unicode letters (including Turkish).

3 Input and slug

Term Meaning
"Merhaba Dünya!" merhaba-dunya
" Go ile Web " go-ile-web
"Çay & Şeker" cay-seker
"--A--" a

All lessons in Intermediate