github.com/d-tsuji/suffixarray@v0.0.0-20200625031310-5b0c40604e73/suffixarray_test.go (about)

     1  package suffixarray
     2  
     3  import (
     4  	"index/suffixarray"
     5  	"io/ioutil"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/google/go-cmp/cmp"
    10  	"github.com/google/go-cmp/cmp/cmpopts"
    11  )
    12  
    13  func TestBuild(t *testing.T) {
    14  	tests := []struct {
    15  		name string
    16  		text string
    17  		want *Manber
    18  	}{
    19  		{
    20  			name: "normal",
    21  			text: "abracadabra",
    22  			want: &Manber{
    23  				N:     11,
    24  				Text:  "abracadabra",
    25  				Index: []int{10, 7, 0, 3, 5, 8, 1, 4, 6, 9, 2, 11 /*sentinels*/},
    26  				Rank:  []int{2, 6, 10, 3, 7, 4, 8, 1, 5, 9, 0, -1 /*sentinels*/},
    27  			},
    28  		},
    29  	}
    30  	for _, tt := range tests {
    31  		t.Run(tt.name, func(t *testing.T) {
    32  			m := New(tt.text)
    33  			m.Build()
    34  			opt := cmpopts.IgnoreUnexported(Manber{})
    35  			if diff := cmp.Diff(m, tt.want, opt); diff != "" {
    36  				t.Errorf("m.Build() differs: (-got +want)\n%s", diff)
    37  			}
    38  		})
    39  	}
    40  }
    41  
    42  func TestLookupAll(t *testing.T) {
    43  	tests := []struct {
    44  		name   string
    45  		text   string
    46  		target string
    47  		want   []int
    48  	}{
    49  		{
    50  			name:   "normal",
    51  			text:   "banana",
    52  			target: "ana",
    53  			want:   []int{1, 3},
    54  		},
    55  	}
    56  	for _, tt := range tests {
    57  		t.Run(tt.name, func(t *testing.T) {
    58  			m := New(tt.text)
    59  			m.Build()
    60  
    61  			// This Transformer sorts a []int.
    62  			trans := cmp.Transformer("Sort", func(in []int) []int {
    63  				out := append([]int(nil), in...) // Copy input to avoid mutating it
    64  				sort.Ints(out)
    65  				return out
    66  			})
    67  
    68  			got := m.LookupAll(tt.target)
    69  			if diff := cmp.Diff(got, tt.want, trans); diff != "" {
    70  				t.Errorf("m.LookupAll() differs: (-got +want)\n%s", diff)
    71  			}
    72  		})
    73  	}
    74  }
    75  
    76  func BenchmarkLookupAll1(b *testing.B) {
    77  	data, err := ioutil.ReadFile("testdata/05_maximum_01.in.data")
    78  	if err != nil {
    79  		b.Fatalf("read test data: %v", err)
    80  	}
    81  	target, err := ioutil.ReadFile("testdata/05_maximum_01.in.target")
    82  	if err != nil {
    83  		b.Fatalf("read test data: %v", err)
    84  	}
    85  	b.ResetTimer()
    86  
    87  	sa := New(string(data))
    88  	sa.Build()
    89  	sa.LookupAll(string(target))
    90  }
    91  
    92  func BenchmarkLookupAll2(b *testing.B) {
    93  	data, err := ioutil.ReadFile("testdata/05_maximum_01.in.data")
    94  	if err != nil {
    95  		b.Fatalf("read test data: %v", err)
    96  	}
    97  	target, err := ioutil.ReadFile("testdata/05_maximum_01.in.target")
    98  	if err != nil {
    99  		b.Fatalf("read test data: %v", err)
   100  	}
   101  	b.ResetTimer()
   102  
   103  	index := suffixarray.New(data)
   104  	index.Lookup(target, -1)
   105  }
   106  
   107  func TestManber_msd(t *testing.T) {
   108  	tests := []struct {
   109  		name string
   110  		text string
   111  		want *Manber
   112  	}{
   113  		{
   114  			name: "normal",
   115  			text: "abracadabra",
   116  			want: &Manber{
   117  				N:     11,
   118  				Text:  "abracadabra",
   119  				Index: []int{0, 3, 5, 7, 10, 1, 8, 4, 6, 2, 9, 11 /*sentinels*/},
   120  				Rank:  []int{0, 5, 9, 0, 7, 0, 8, 0, 5, 9, 0, -1 /*sentinels*/},
   121  			},
   122  		},
   123  	}
   124  	for _, tt := range tests {
   125  		t.Run(tt.name, func(t *testing.T) {
   126  			m := New(tt.text)
   127  			m.msd()
   128  			opt := cmpopts.IgnoreUnexported(Manber{})
   129  			if diff := cmp.Diff(m, tt.want, opt); diff != "" {
   130  				t.Errorf("m.msd() differs: (-got +want)\n%s", diff)
   131  			}
   132  		})
   133  	}
   134  }