diff options
Diffstat (limited to 'helpers/emoji_test.go')
-rw-r--r-- | helpers/emoji_test.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/helpers/emoji_test.go b/helpers/emoji_test.go new file mode 100644 index 000000000..6485bb5fe --- /dev/null +++ b/helpers/emoji_test.go @@ -0,0 +1,143 @@ +// Copyright 2016 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package helpers + +import ( + "math" + "reflect" + "strings" + "testing" + + "github.com/gohugoio/hugo/bufferpool" + "github.com/kyokomi/emoji/v2" +) + +func TestEmojiCustom(t *testing.T) { + for i, this := range []struct { + input string + expect []byte + }{ + {"A :smile: a day", []byte("A š a day")}, + {"A few :smile:s a day", []byte("A few šs a day")}, + {"A :smile: and a :beer: makes the day for sure.", []byte("A š and a šŗ makes the day for sure.")}, + {"A :smile: and: a :beer:", []byte("A š and: a šŗ")}, + {"A :diamond_shape_with_a_dot_inside: and then some.", []byte("A š and then some.")}, + {":smile:", []byte("š")}, + {":smi", []byte(":smi")}, + {"A :smile:", []byte("A š")}, + {":beer:!", []byte("šŗ!")}, + {"::smile:", []byte(":š")}, + {":beer::", []byte("šŗ:")}, + {" :beer: :", []byte(" šŗ :")}, + {":beer: and :smile: and another :beer:!", []byte("šŗ and š and another šŗ!")}, + {" :beer: : ", []byte(" šŗ : ")}, + {"No smilies for you!", []byte("No smilies for you!")}, + {" The motto: no smiles! ", []byte(" The motto: no smiles! ")}, + {":hugo_is_the_best_static_gen:", []byte(":hugo_is_the_best_static_gen:")}, + {"ģķ :smile: ģķ", []byte("ģķ š ģķ")}, + // #2198 + {"See: A :beer:!", []byte("See: A šŗ!")}, + {`Aaaaaaaaaa: aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa. + +:beer:`, []byte(`Aaaaaaaaaa: aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa. + +šŗ`)}, + {"test :\n```bash\nthis is a test\n```\n\ntest\n\n:cool::blush:::pizza:\\:blush : : blush: :pizza:", []byte("test :\n```bash\nthis is a test\n```\n\ntest\n\nšš:š\\:blush : : blush: š")}, + { + // 2391 + "[a](http://gohugo.io) :smile: [r](http://gohugo.io/introduction/overview/) :beer:", + []byte(`[a](http://gohugo.io) š [r](http://gohugo.io/introduction/overview/) šŗ`), + }, + } { + + result := Emojify([]byte(this.input)) + + if !reflect.DeepEqual(result, this.expect) { + t.Errorf("[%d] got %q but expected %q", i, result, this.expect) + } + + } +} + +// The Emoji benchmarks below are heavily skewed in Hugo's direction: +// +// Hugo have a byte slice, wants a byte slice and doesn't mind if the original is modified. + +func BenchmarkEmojiKyokomiFprint(b *testing.B) { + f := func(in []byte) []byte { + buff := bufferpool.GetBuffer() + defer bufferpool.PutBuffer(buff) + emoji.Fprint(buff, string(in)) + + bc := make([]byte, buff.Len()) + copy(bc, buff.Bytes()) + return bc + } + + doBenchmarkEmoji(b, f) +} + +func BenchmarkEmojiKyokomiSprint(b *testing.B) { + f := func(in []byte) []byte { + return []byte(emoji.Sprint(string(in))) + } + + doBenchmarkEmoji(b, f) +} + +func BenchmarkHugoEmoji(b *testing.B) { + doBenchmarkEmoji(b, Emojify) +} + +func doBenchmarkEmoji(b *testing.B, f func(in []byte) []byte) { + type input struct { + in []byte + expect []byte + } + + data := []struct { + input string + expect string + }{ + {"A :smile: a day", emoji.Sprint("A :smile: a day")}, + {"A :smile: and a :beer: day keeps the doctor away", emoji.Sprint("A :smile: and a :beer: day keeps the doctor away")}, + {"A :smile: a day and 10 " + strings.Repeat(":beer: ", 10), emoji.Sprint("A :smile: a day and 10 " + strings.Repeat(":beer: ", 10))}, + {"No smiles today.", "No smiles today."}, + {"No smiles for you or " + strings.Repeat("you ", 1000), "No smiles for you or " + strings.Repeat("you ", 1000)}, + } + + in := make([]input, b.N*len(data)) + cnt := 0 + for i := 0; i < b.N; i++ { + for _, this := range data { + in[cnt] = input{[]byte(this.input), []byte(this.expect)} + cnt++ + } + } + + b.ResetTimer() + cnt = 0 + for i := 0; i < b.N; i++ { + for j := range data { + currIn := in[cnt] + cnt++ + result := f(currIn.in) + // The Emoji implementations gives slightly different output. + diffLen := len(result) - len(currIn.expect) + diffLen = int(math.Abs(float64(diffLen))) + if diffLen > 30 { + b.Fatalf("[%d] emoji std, got \n%q but expected \n%q", j, result, currIn.expect) + } + } + } +} |