| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- // Copyright 2013 by Dobrosław Żybort. All rights reserved.
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this
- // file, You can obtain one at http://mozilla.org/MPL/2.0/.
- package slug
- import (
- "testing"
- )
- //=============================================================================
- func TestSlugMake(t *testing.T) {
- var testCases = []struct {
- in string
- want string
- }{
- {"DOBROSLAWZYBORT", "dobroslawzybort"},
- {"Dobroslaw Zybort", "dobroslaw-zybort"},
- {" Dobroslaw Zybort ?", "dobroslaw-zybort"},
- {"Dobrosław Żybort", "dobroslaw-zybort"},
- {"Ala ma 6 kotów.", "ala-ma-6-kotow"},
- {"áÁàÀãÃâÂäÄąĄą̊Ą̊", "aaaaaaaaaaaaaa"},
- {"ćĆĉĈçÇ", "cccccc"},
- {"éÉèÈẽẼêÊëËęĘ", "eeeeeeeeeeee"},
- {"íÍìÌĩĨîÎïÏįĮ", "iiiiiiiiiiii"},
- {"łŁ", "ll"},
- {"ńŃ", "nn"},
- {"óÓòÒõÕôÔöÖǫǪǭǬø", "ooooooooooooooo"},
- {"śŚ", "ss"},
- {"úÚùÙũŨûÛüÜųŲ", "uuuuuuuuuuuu"},
- {"y̨Y̨", "yy"},
- {"źŹżŹ", "zzzz"},
- {"·/,:;`˜'\"", ""},
- {"2000–2013", "2000-2013"},
- {"style—not", "style-not"},
- {"test_slug", "test_slug"},
- {"Æ", "ae"},
- {"Ich heiße", "ich-heisse"},
- {"This & that", "this-and-that"},
- {"fácil €", "facil-eu"},
- {"smile ☺", "smile"},
- {"Hellö Wörld хелло ворлд", "hello-world-khello-vorld"},
- {"\"C'est déjà l’été.\"", "cest-deja-lete"},
- {"jaja---lol-méméméoo--a", "jaja-lol-mememeoo-a"},
- {"影師", "ying-shi"},
- }
- for index, st := range testCases {
- got := Make(st.in)
- if got != st.want {
- t.Errorf(
- "%d. Make(%#v) = %#v; want %#v",
- index, st.in, got, st.want)
- }
- }
- }
- func TestSlugMakeLang(t *testing.T) {
- var testCases = []struct {
- lang string
- in string
- want string
- }{
- {"en", "This & that", "this-and-that"},
- {"de", "This & that", "this-und-that"},
- {"pl", "This & that", "this-i-that"},
- {"es", "This & that", "this-y-that"},
- {"gr", "This & that", "this-kai-that"},
- {"test", "This & that", "this-and-that"}, // unknown lang, fallback to "en"
- }
- for index, smlt := range testCases {
- got := MakeLang(smlt.in, smlt.lang)
- if got != smlt.want {
- t.Errorf(
- "%d. MakeLang(%#v, %#v) = %#v; want %#v",
- index, smlt.in, smlt.lang, got, smlt.want)
- }
- }
- }
- func TestSlugMakeUserSubstituteLang(t *testing.T) {
- var testCases = []struct {
- cSub map[string]string
- lang string
- in string
- want string
- }{
- {map[string]string{"'": " "}, "en", "That's great", "that-s-great"},
- {map[string]string{"&": "or"}, "en", "This & that", "this-or-that"}, // by default "&" => "and"
- {map[string]string{"&": "or"}, "de", "This & that", "this-or-that"}, // by default "&" => "und"
- {map[string]string{"&": "or", "@": "the"}, "de", "@ This & that", "the-this-or-that"}, // by default "&" => "und", "@" => "an"
- }
- for index, smust := range testCases {
- CustomSub = smust.cSub
- got := MakeLang(smust.in, smust.lang)
- if got != smust.want {
- t.Errorf(
- "%d. %#v; MakeLang(%#v, %#v) = %#v; want %#v",
- index, smust.cSub, smust.in, smust.lang,
- got, smust.want)
- }
- }
- }
- func TestSlugMakeSubstituteOrderLang(t *testing.T) {
- // Always substitute runes first
- var testCases = []struct {
- rSub map[rune]string
- sSub map[string]string
- in string
- want string
- }{
- {map[rune]string{'o': "left"}, map[string]string{"o": "right"}, "o o", "left-left"},
- {map[rune]string{'o': "left", 'a': "r"}, map[string]string{"o": "right"}, "o a o", "left-r-left"},
- {map[rune]string{'o': "left"}, map[string]string{"o": "right", "a": "r"}, "a o a o", "r-left-r-left"},
- {map[rune]string{'&': "down"}, map[string]string{"&": "up"}, "&", "down"},
- }
- for index, smsot := range testCases {
- CustomRuneSub = smsot.rSub
- CustomSub = smsot.sSub
- got := Make(smsot.in)
- if got != smsot.want {
- t.Errorf(
- "%d. %#v; %#v; Make(%#v) = %#v; want %#v",
- index, smsot.rSub, smsot.sSub, smsot.in,
- got, smsot.want)
- }
- }
- }
- func TestSubstituteLang(t *testing.T) {
- var testCases = []struct {
- cSub map[string]string
- in string
- want string
- }{
- {map[string]string{"o": "no"}, "o o o", "no no no"},
- {map[string]string{"o": "no", "a": "or"}, "o a o", "no nor no"},
- {map[string]string{"a": "or", "o": "no"}, "o a o", "no nor no"},
- {map[string]string{"'": " "}, "That's great", "That s great"},
- }
- for index, sst := range testCases {
- got := Substitute(sst.in, sst.cSub)
- if got != sst.want {
- t.Errorf(
- "%d. Substitute(%#v, %#v) = %#v; want %#v",
- index, sst.in, sst.cSub, got, sst.want)
- }
- }
- }
- func TestSubstituteRuneLang(t *testing.T) {
- var testCases = []struct {
- cSub map[rune]string
- in string
- want string
- }{
- {map[rune]string{'o': "no"}, "o o o", "no no no"},
- {map[rune]string{'o': "no", 'a': "or"}, "o a o", "no or no"},
- {map[rune]string{'a': "or", 'o': "no"}, "o a o", "no or no"},
- {map[rune]string{'\'': " "}, "That's great", "That s great"},
- }
- for index, ssrt := range testCases {
- got := SubstituteRune(ssrt.in, ssrt.cSub)
- if got != ssrt.want {
- t.Errorf(
- "%d. SubstituteRune(%#v, %#v) = %#v; want %#v",
- index, ssrt.in, ssrt.cSub, got, ssrt.want)
- }
- }
- }
- func TestSlugMakeSmartTruncate(t *testing.T) {
- var testCases = []struct {
- in string
- maxLength int
- want string
- }{
- {"DOBROSLAWZYBORT", 100, "dobroslawzybort"},
- {"Dobroslaw Zybort", 100, "dobroslaw-zybort"},
- {"Dobroslaw Zybort", 12, "dobroslaw"},
- {" Dobroslaw Zybort ?", 12, "dobroslaw"},
- {"Ala ma 6 kotów.", 10, "ala-ma-6"},
- {"Dobrosław Żybort", 5, "dobro"},
- }
- for index, smstt := range testCases {
- MaxLength = smstt.maxLength
- got := Make(smstt.in)
- if got != smstt.want {
- t.Errorf(
- "%d. MaxLength = %v; Make(%#v) = %#v; want %#v",
- index, smstt.maxLength, smstt.in, got, smstt.want)
- }
- }
- }
- func TestIsSlug(t *testing.T) {
- MaxLength = 0
- type args struct {
- text string
- }
- tests := []struct {
- name string
- args args
- want bool
- }{
- {"some", args{"some"}, true},
- {"with -", args{"some-more"}, true},
- {"with _", args{"some_more"}, true},
- {"with numbers", args{"number-2"}, true},
- {"empty string", args{""}, false},
- {"upper case", args{"Some-more"}, false},
- {"space", args{"some more"}, false},
- {"starts with '-'", args{"-some"}, false},
- {"ends with '-'", args{"some-"}, false},
- {"starts with '_'", args{"_some"}, false},
- {"ends with '_'", args{"some_"}, false},
- {"outside ASCII", args{"Dobrosław Żybort"}, false},
- {"outside ASCII –", args{"2000–2013"}, false},
- {"smile ☺", args{"smile ☺"}, false},
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- if got := IsSlug(tt.args.text); got != tt.want {
- t.Errorf("IsSlug() = %v, want %v", got, tt.want)
- }
- })
- }
- t.Run("MaxLength", func(t *testing.T) {
- MaxLength = 4
- if got := IsSlug("012345"); got != false {
- t.Errorf("IsSlug() = %v, want %v", got, false)
- }
- MaxLength = 0
- })
- }
- func BenchmarkMakeShortAscii(b *testing.B) {
- b.ReportAllocs()
- for n := 0; n < b.N; n++ {
- Make("Hello world")
- }
- }
- func BenchmarkMakeShort(b *testing.B) {
- b.ReportAllocs()
- for n := 0; n < b.N; n++ {
- Make("хелло ворлд")
- }
- }
- func BenchmarkMakeShortSymbols(b *testing.B) {
- b.ReportAllocs()
- for n := 0; n < b.N; n++ {
- Make("·/,:;`˜'\" &€£¥")
- }
- }
- func BenchmarkMakeMediumAscii(b *testing.B) {
- b.ReportAllocs()
- for n := 0; n < b.N; n++ {
- Make("ABCDE FGHIJ KLMNO PQRST UWXYZ ABCDE FGHIJ KLMNO PQRST UWXYZ ABCDE")
- }
- }
- func BenchmarkMakeMedium(b *testing.B) {
- b.ReportAllocs()
- for n := 0; n < b.N; n++ {
- Make("ヲァィゥェ ォャュョッ ーアイウエ オカキクケ コサシスセ ソタチツテ トナニヌネ ノハヒフヘ ホマミムメ モヤユヨラ リルレロワ")
- }
- }
- func BenchmarkMakeLongAscii(b *testing.B) {
- longStr := "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi " +
- "pulvinar sodales ultrices. Nulla facilisi. Sed at vestibulum erat. Ut " +
- "sit amet urna posuere, sagittis eros ac, varius nisi. Morbi ullamcorper " +
- "odio at nunc pulvinar mattis. Vestibulum rutrum, ante eu dictum mattis, " +
- "elit risus finibus nunc, consectetur facilisis eros leo ut sapien. Sed " +
- "pulvinar volutpat mi. Cras semper mi ac eros accumsan, at feugiat massa " +
- "elementum. Morbi eget dolor sit amet purus condimentum egestas non ut " +
- "sapien. Duis feugiat magna vitae nisi lobortis, quis finibus sem " +
- "sollicitudin. Pellentesque eleifend blandit ipsum, ut porta arcu " +
- "ultricies et. Fusce vel ipsum porta, placerat diam ac, consectetur " +
- "magna. Nulla in porta sem. Suspendisse commodo, felis in molestie " +
- "ultricies, arcu ipsum aliquet turpis, elementum dapibus ipsum lorem a " +
- "nisl. Etiam varius imperdiet placerat. Aliquam euismod lacus arcu, " +
- "ultrices hendrerit est pellentesque vel. Aliquam sit amet laoreet leo. " +
- "Integer eros libero, mollis sed posuere."
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- Make(longStr)
- }
- }
- func BenchmarkSubstituteRuneShort(b *testing.B) {
- shortStr := "Hello/Hi world"
- subs := map[rune]string{'o': "no", '/': "slash"}
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- SubstituteRune(shortStr, subs)
- }
- }
- func BenchmarkSubstituteRuneLong(b *testing.B) {
- longStr := "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi " +
- "pulvinar sodales ultrices. Nulla facilisi. Sed at vestibulum erat. Ut " +
- "sit amet urna posuere, sagittis eros ac, varius nisi. Morbi ullamcorper " +
- "odio at nunc pulvinar mattis. Vestibulum rutrum, ante eu dictum mattis, " +
- "elit risus finibus nunc, consectetur facilisis eros leo ut sapien. Sed " +
- "pulvinar volutpat mi. Cras semper mi ac eros accumsan, at feugiat massa " +
- "elementum. Morbi eget dolor sit amet purus condimentum egestas non ut " +
- "sapien. Duis feugiat magna vitae nisi lobortis, quis finibus sem " +
- "sollicitudin. Pellentesque eleifend blandit ipsum, ut porta arcu " +
- "ultricies et. Fusce vel ipsum porta, placerat diam ac, consectetur " +
- "magna. Nulla in porta sem. Suspendisse commodo, felis in molestie " +
- "ultricies, arcu ipsum aliquet turpis, elementum dapibus ipsum lorem a " +
- "nisl. Etiam varius imperdiet placerat. Aliquam euismod lacus arcu, " +
- "ultrices hendrerit est pellentesque vel. Aliquam sit amet laoreet leo. " +
- "Integer eros libero, mollis sed posuere."
- subs := map[rune]string{
- 'o': "no",
- '/': "slash",
- 'i': "done",
- 'E': "es",
- 'a': "ASD",
- '1': "one",
- 'l': "onetwo",
- }
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- SubstituteRune(longStr, subs)
- }
- }
- func BenchmarkSmartTruncateShort(b *testing.B) {
- shortStr := "Hello-world"
- MaxLength = 8
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- smartTruncate(shortStr)
- }
- }
- func BenchmarkSmartTruncateLong(b *testing.B) {
- longStr := "Lorem-ipsum-dolor-sit-amet,-consectetur-adipiscing-elit.-Morbi-" +
- "pulvinar-sodales-ultrices.-Nulla-facilisi.-Sed-at-vestibulum-erat.-Ut-" +
- "sit-amet-urna-posuere,-sagittis-eros-ac,-varius-nisi.-Morbi-ullamcorper-" +
- "odio-at-nunc-pulvinar-mattis.-Vestibulum-rutrum,-ante-eu-dictum-mattis,-" +
- "elit-risus-finibus-nunc,-consectetur-facilisis-eros-leo-ut-sapien.-Sed-" +
- "pulvinar-volutpat-mi.-Cras-semper-mi-ac-eros-accumsan,-at-feugiat-massa-" +
- "elementum.-Morbi-eget-dolor-sit-amet-purus-condimentum-egestas-non-ut-" +
- "sapien.-Duis-feugiat-magna-vitae-nisi-lobortis,-quis-finibus-sem-" +
- "sollicitudin.-Pellentesque-eleifend-blandit-ipsum,-ut-porta-arcu-" +
- "ultricies-et.-Fusce-vel-ipsum-porta,-placerat-diam-ac,-consectetur-" +
- "magna.-Nulla-in-porta-sem.-Suspendisse-commodo,-felis-in-molestie-" +
- "ultricies,-arcu-ipsum-aliquet-turpis,-elementum-dapibus-ipsum-lorem-a-" +
- "nisl.-Etiam-varius-imperdiet-placerat.-Aliquam-euismod-lacus-arcu,-" +
- "ultrices-hendrerit-est-pellentesque-vel.-Aliquam-sit-amet-laoreet-leo.-" +
- "Integer-eros-libero,-mollis-sed-posuere."
- MaxLength = 256
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- smartTruncate(longStr)
- }
- }
- func BenchmarkIsSlugShort(b *testing.B) {
- shortStr := "hello-world"
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- IsSlug(shortStr)
- }
- }
- func BenchmarkIsSlugLong(b *testing.B) {
- longStr := "lorem-ipsum-dolor-sit-amet-consectetur-adipiscing-elit-morbi-" +
- "pulvinar-sodales-ultrices-nulla-facilisi-sed-at-vestibulum-erat-ut-" +
- "sit-amet-urna-posuere-sagittis-eros-ac-varius-nisi-morbi-ullamcorper-" +
- "odio-at-nunc-pulvinar-mattis-vestibulum-rutrum-ante-eu-dictum-mattis,-" +
- "elit-risus-finibus-nunc-consectetur-facilisis-eros-leo-ut-sapien-sed-" +
- "pulvinar-volutpat-mi-cras-semper-mi-ac-eros-accumsan-at-feugiat-massa-" +
- "elementum-morbi-eget-dolor-sit-amet-purus-condimentum-egestas-non-ut-" +
- "sapien-duis-feugiat-magna-vitae-nisi-lobortis-quis-finibus-sem-" +
- "sollicitudin-pellentesque-eleifend-blandit-ipsum-ut-porta-arcu-" +
- "ultricies-et-fusce-vel-ipsum-porta-placerat-diam-ac-consectetur-" +
- "magna-nulla-in-porta-sem-suspendisse-commodo-felis-in-molestie-" +
- "ultricies-arcu-ipsum-aliquet-turpis-elementum-dapibus-ipsum-lorem-a-" +
- "nisl-etiam-varius-imperdiet-placerat-aliquam-euismod-lacus-arcu-" +
- "ultrices-hendrerit-est-pellentesque-vel-aliquam-sit-amet-laoreet-leo-" +
- "integer-eros-libero-mollis-sed-posuere"
- b.ReportAllocs()
- b.ResetTimer()
- for n := 0; n < b.N; n++ {
- IsSlug(longStr)
- }
- }
|