github.com/lingyao2333/mo-zero@v1.4.1/core/stringx/node_fuzz_test.go (about)

     1  //go:build go1.18
     2  // +build go1.18
     3  
     4  package stringx
     5  
     6  import (
     7  	"fmt"
     8  	"math/rand"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func FuzzNodeFind(f *testing.F) {
    17  	rand.Seed(time.Now().UnixNano())
    18  
    19  	f.Add(10)
    20  	f.Fuzz(func(t *testing.T, keys int) {
    21  		str := Randn(rand.Intn(100) + 50)
    22  		keywords := make(map[string]struct{})
    23  		for i := 0; i < keys; i++ {
    24  			keyword := Randn(rand.Intn(10) + 5)
    25  			if !strings.Contains(str, keyword) {
    26  				keywords[keyword] = struct{}{}
    27  			}
    28  		}
    29  
    30  		size := len(str)
    31  		var scopes []scope
    32  		var n node
    33  		for i := 0; i < size%20; i++ {
    34  			start := rand.Intn(size)
    35  			stop := start + rand.Intn(20) + 1
    36  			if stop > size {
    37  				stop = size
    38  			}
    39  			if start == stop {
    40  				continue
    41  			}
    42  
    43  			keyword := str[start:stop]
    44  			if _, ok := keywords[keyword]; ok {
    45  				continue
    46  			}
    47  
    48  			keywords[keyword] = struct{}{}
    49  			var pos int
    50  			for pos <= len(str)-len(keyword) {
    51  				val := str[pos:]
    52  				p := strings.Index(val, keyword)
    53  				if p < 0 {
    54  					break
    55  				}
    56  
    57  				scopes = append(scopes, scope{
    58  					start: pos + p,
    59  					stop:  pos + p + len(keyword),
    60  				})
    61  				pos += p + 1
    62  			}
    63  		}
    64  
    65  		for keyword := range keywords {
    66  			n.add(keyword)
    67  		}
    68  		n.build()
    69  
    70  		var buf strings.Builder
    71  		buf.WriteString("keywords:\n")
    72  		for key := range keywords {
    73  			fmt.Fprintf(&buf, "\t%q,\n", key)
    74  		}
    75  		buf.WriteString("scopes:\n")
    76  		for _, scp := range scopes {
    77  			fmt.Fprintf(&buf, "\t{%d, %d},\n", scp.start, scp.stop)
    78  		}
    79  		fmt.Fprintf(&buf, "text:\n\t%s\n", str)
    80  		defer func() {
    81  			if r := recover(); r != nil {
    82  				t.Errorf(buf.String())
    83  			}
    84  		}()
    85  		assert.ElementsMatchf(t, scopes, n.find([]rune(str)), buf.String())
    86  	})
    87  }