github.com/xmplusdev/xmcore@v1.8.11-0.20240412132628-5518b55526af/common/strmatcher/strmatcher_test.go (about)

     1  package strmatcher_test
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/xmplusdev/xmcore/common"
     8  	. "github.com/xmplusdev/xmcore/common/strmatcher"
     9  )
    10  
    11  func TestMatcherGroup(t *testing.T) {
    12  	rules := []struct {
    13  		Type   Type
    14  		Domain string
    15  	}{
    16  		{
    17  			Type:   Regex,
    18  			Domain: "apis\\.us$",
    19  		},
    20  		{
    21  			Type:   Substr,
    22  			Domain: "apis",
    23  		},
    24  		{
    25  			Type:   Domain,
    26  			Domain: "googleapis.com",
    27  		},
    28  		{
    29  			Type:   Domain,
    30  			Domain: "com",
    31  		},
    32  		{
    33  			Type:   Full,
    34  			Domain: "www.baidu.com",
    35  		},
    36  		{
    37  			Type:   Substr,
    38  			Domain: "apis",
    39  		},
    40  		{
    41  			Type:   Domain,
    42  			Domain: "googleapis.com",
    43  		},
    44  		{
    45  			Type:   Full,
    46  			Domain: "fonts.googleapis.com",
    47  		},
    48  		{
    49  			Type:   Full,
    50  			Domain: "www.baidu.com",
    51  		},
    52  		{
    53  			Type:   Domain,
    54  			Domain: "example.com",
    55  		},
    56  	}
    57  	cases := []struct {
    58  		Input  string
    59  		Output []uint32
    60  	}{
    61  		{
    62  			Input:  "www.baidu.com",
    63  			Output: []uint32{5, 9, 4},
    64  		},
    65  		{
    66  			Input:  "fonts.googleapis.com",
    67  			Output: []uint32{8, 3, 7, 4, 2, 6},
    68  		},
    69  		{
    70  			Input:  "example.googleapis.com",
    71  			Output: []uint32{3, 7, 4, 2, 6},
    72  		},
    73  		{
    74  			Input:  "testapis.us",
    75  			Output: []uint32{1, 2, 6},
    76  		},
    77  		{
    78  			Input:  "example.com",
    79  			Output: []uint32{10, 4},
    80  		},
    81  	}
    82  	matcherGroup := &MatcherGroup{}
    83  	for _, rule := range rules {
    84  		matcher, err := rule.Type.New(rule.Domain)
    85  		common.Must(err)
    86  		matcherGroup.Add(matcher)
    87  	}
    88  	for _, test := range cases {
    89  		if m := matcherGroup.Match(test.Input); !reflect.DeepEqual(m, test.Output) {
    90  			t.Error("unexpected output: ", m, " for test case ", test)
    91  		}
    92  	}
    93  }
    94  
    95  func TestACAutomaton(t *testing.T) {
    96  	cases1 := []struct {
    97  		pattern string
    98  		mType   Type
    99  		input   string
   100  		output  bool
   101  	}{
   102  		{
   103  			pattern: "xtls.github.io",
   104  			mType:   Domain,
   105  			input:   "www.xtls.github.io",
   106  			output:  true,
   107  		},
   108  		{
   109  			pattern: "xtls.github.io",
   110  			mType:   Domain,
   111  			input:   "xtls.github.io",
   112  			output:  true,
   113  		},
   114  		{
   115  			pattern: "xtls.github.io",
   116  			mType:   Domain,
   117  			input:   "www.xtis.github.io",
   118  			output:  false,
   119  		},
   120  		{
   121  			pattern: "xtls.github.io",
   122  			mType:   Domain,
   123  			input:   "tls.github.io",
   124  			output:  false,
   125  		},
   126  		{
   127  			pattern: "xtls.github.io",
   128  			mType:   Domain,
   129  			input:   "xxtls.github.io",
   130  			output:  false,
   131  		},
   132  		{
   133  			pattern: "xtls.github.io",
   134  			mType:   Full,
   135  			input:   "xtls.github.io",
   136  			output:  true,
   137  		},
   138  		{
   139  			pattern: "xtls.github.io",
   140  			mType:   Full,
   141  			input:   "xxtls.github.io",
   142  			output:  false,
   143  		},
   144  	}
   145  	for _, test := range cases1 {
   146  		ac := NewACAutomaton()
   147  		ac.Add(test.pattern, test.mType)
   148  		ac.Build()
   149  		if m := ac.Match(test.input); m != test.output {
   150  			t.Error("unexpected output: ", m, " for test case ", test)
   151  		}
   152  	}
   153  	{
   154  		cases2Input := []struct {
   155  			pattern string
   156  			mType   Type
   157  		}{
   158  			{
   159  				pattern: "163.com",
   160  				mType:   Domain,
   161  			},
   162  			{
   163  				pattern: "m.126.com",
   164  				mType:   Full,
   165  			},
   166  			{
   167  				pattern: "3.com",
   168  				mType:   Full,
   169  			},
   170  			{
   171  				pattern: "google.com",
   172  				mType:   Substr,
   173  			},
   174  			{
   175  				pattern: "vgoogle.com",
   176  				mType:   Substr,
   177  			},
   178  		}
   179  		ac := NewACAutomaton()
   180  		for _, test := range cases2Input {
   181  			ac.Add(test.pattern, test.mType)
   182  		}
   183  		ac.Build()
   184  		cases2Output := []struct {
   185  			pattern string
   186  			res     bool
   187  		}{
   188  			{
   189  				pattern: "126.com",
   190  				res:     false,
   191  			},
   192  			{
   193  				pattern: "m.163.com",
   194  				res:     true,
   195  			},
   196  			{
   197  				pattern: "mm163.com",
   198  				res:     false,
   199  			},
   200  			{
   201  				pattern: "m.126.com",
   202  				res:     true,
   203  			},
   204  			{
   205  				pattern: "163.com",
   206  				res:     true,
   207  			},
   208  			{
   209  				pattern: "63.com",
   210  				res:     false,
   211  			},
   212  			{
   213  				pattern: "oogle.com",
   214  				res:     false,
   215  			},
   216  			{
   217  				pattern: "vvgoogle.com",
   218  				res:     true,
   219  			},
   220  			{
   221  				pattern: "½",
   222  				res:     false,
   223  			},
   224  		}
   225  		for _, test := range cases2Output {
   226  			if m := ac.Match(test.pattern); m != test.res {
   227  				t.Error("unexpected output: ", m, " for test case ", test)
   228  			}
   229  		}
   230  	}
   231  	{
   232  		cases3Input := []struct {
   233  			pattern string
   234  			mType   Type
   235  		}{
   236  			{
   237  				pattern: "video.google.com",
   238  				mType:   Domain,
   239  			},
   240  			{
   241  				pattern: "gle.com",
   242  				mType:   Domain,
   243  			},
   244  		}
   245  		ac := NewACAutomaton()
   246  		for _, test := range cases3Input {
   247  			ac.Add(test.pattern, test.mType)
   248  		}
   249  		ac.Build()
   250  		cases3Output := []struct {
   251  			pattern string
   252  			res     bool
   253  		}{
   254  			{
   255  				pattern: "google.com",
   256  				res:     false,
   257  			},
   258  		}
   259  		for _, test := range cases3Output {
   260  			if m := ac.Match(test.pattern); m != test.res {
   261  				t.Error("unexpected output: ", m, " for test case ", test)
   262  			}
   263  		}
   264  	}
   265  }