github.com/lyeb/hugo@v0.47.1/helpers/emoji_test.go (about)

     1  // Copyright 2016 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  package helpers
    14  
    15  import (
    16  	"math"
    17  	"reflect"
    18  	"strings"
    19  	"testing"
    20  
    21  	"github.com/gohugoio/hugo/bufferpool"
    22  	"github.com/kyokomi/emoji"
    23  )
    24  
    25  func TestEmojiCustom(t *testing.T) {
    26  	for i, this := range []struct {
    27  		input  string
    28  		expect []byte
    29  	}{
    30  		{"A :smile: a day", []byte("A šŸ˜„ a day")},
    31  		{"A few :smile:s a day", []byte("A few šŸ˜„s a day")},
    32  		{"A :smile: and a :beer: makes the day for sure.", []byte("A šŸ˜„ and a šŸŗ makes the day for sure.")},
    33  		{"A :smile: and: a :beer:", []byte("A šŸ˜„ and: a šŸŗ")},
    34  		{"A :diamond_shape_with_a_dot_inside: and then some.", []byte("A šŸ’  and then some.")},
    35  		{":smile:", []byte("šŸ˜„")},
    36  		{":smi", []byte(":smi")},
    37  		{"A :smile:", []byte("A šŸ˜„")},
    38  		{":beer:!", []byte("šŸŗ!")},
    39  		{"::smile:", []byte(":šŸ˜„")},
    40  		{":beer::", []byte("šŸŗ:")},
    41  		{" :beer: :", []byte(" šŸŗ :")},
    42  		{":beer: and :smile: and another :beer:!", []byte("šŸŗ and šŸ˜„ and another šŸŗ!")},
    43  		{" :beer: : ", []byte(" šŸŗ : ")},
    44  		{"No smilies for you!", []byte("No smilies for you!")},
    45  		{" The motto: no smiles! ", []byte(" The motto: no smiles! ")},
    46  		{":hugo_is_the_best_static_gen:", []byte(":hugo_is_the_best_static_gen:")},
    47  		{"ģ€ķ–‰ :smile: ģ€ķ–‰", []byte("ģ€ķ–‰ šŸ˜„ ģ€ķ–‰")},
    48  		// #2198
    49  		{"See: A :beer:!", []byte("See: A šŸŗ!")},
    50  		{`Aaaaaaaaaa: aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa.
    51  
    52  :beer:`, []byte(`Aaaaaaaaaa: aaaaaaaaaa aaaaaaaaaa aaaaaaaaaa.
    53  
    54  šŸŗ`)},
    55  		{"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: šŸ•")},
    56  		{
    57  			// 2391
    58  			"[a](http://gohugo.io) :smile: [r](http://gohugo.io/introduction/overview/) :beer:",
    59  			[]byte(`[a](http://gohugo.io) šŸ˜„ [r](http://gohugo.io/introduction/overview/) šŸŗ`),
    60  		},
    61  	} {
    62  
    63  		result := Emojify([]byte(this.input))
    64  
    65  		if !reflect.DeepEqual(result, this.expect) {
    66  			t.Errorf("[%d] got %q but expected %q", i, result, this.expect)
    67  		}
    68  
    69  	}
    70  }
    71  
    72  // The Emoji benchmarks below are heavily skewed in Hugo's direction:
    73  //
    74  // Hugo have a byte slice, wants a byte slice and doesn't mind if the original is modified.
    75  
    76  func BenchmarkEmojiKyokomiFprint(b *testing.B) {
    77  
    78  	f := func(in []byte) []byte {
    79  		buff := bufferpool.GetBuffer()
    80  		defer bufferpool.PutBuffer(buff)
    81  		emoji.Fprint(buff, string(in))
    82  
    83  		bc := make([]byte, buff.Len(), buff.Len())
    84  		copy(bc, buff.Bytes())
    85  		return bc
    86  	}
    87  
    88  	doBenchmarkEmoji(b, f)
    89  }
    90  
    91  func BenchmarkEmojiKyokomiSprint(b *testing.B) {
    92  
    93  	f := func(in []byte) []byte {
    94  		return []byte(emoji.Sprint(string(in)))
    95  	}
    96  
    97  	doBenchmarkEmoji(b, f)
    98  }
    99  
   100  func BenchmarkHugoEmoji(b *testing.B) {
   101  	doBenchmarkEmoji(b, Emojify)
   102  }
   103  
   104  func doBenchmarkEmoji(b *testing.B, f func(in []byte) []byte) {
   105  
   106  	type input struct {
   107  		in     []byte
   108  		expect []byte
   109  	}
   110  
   111  	data := []struct {
   112  		input  string
   113  		expect string
   114  	}{
   115  		{"A :smile: a day", emoji.Sprint("A :smile: a day")},
   116  		{"A :smile: and a :beer: day keeps the doctor away", emoji.Sprint("A :smile: and a :beer: day keeps the doctor away")},
   117  		{"A :smile: a day and 10 " + strings.Repeat(":beer: ", 10), emoji.Sprint("A :smile: a day and 10 " + strings.Repeat(":beer: ", 10))},
   118  		{"No smiles today.", "No smiles today."},
   119  		{"No smiles for you or " + strings.Repeat("you ", 1000), "No smiles for you or " + strings.Repeat("you ", 1000)},
   120  	}
   121  
   122  	var in = make([]input, b.N*len(data))
   123  	var cnt = 0
   124  	for i := 0; i < b.N; i++ {
   125  		for _, this := range data {
   126  			in[cnt] = input{[]byte(this.input), []byte(this.expect)}
   127  			cnt++
   128  		}
   129  	}
   130  
   131  	b.ResetTimer()
   132  	cnt = 0
   133  	for i := 0; i < b.N; i++ {
   134  		for j := range data {
   135  			currIn := in[cnt]
   136  			cnt++
   137  			result := f(currIn.in)
   138  			// The Emoji implementations gives slightly different output.
   139  			diffLen := len(result) - len(currIn.expect)
   140  			diffLen = int(math.Abs(float64(diffLen)))
   141  			if diffLen > 30 {
   142  				b.Fatalf("[%d] emoji std, got \n%q but expected \n%q", j, result, currIn.expect)
   143  			}
   144  		}
   145  
   146  	}
   147  }