github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/regexp/onepass_test.gno (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package regexp 6 7 import ( 8 "regexp/syntax" 9 "strings" 10 "testing" 11 ) 12 13 var runeMergeTests = []struct { 14 left, right, merged []rune 15 next []uint32 16 leftPC, rightPC uint32 17 }{ 18 { 19 // empty rhs 20 []rune{69, 69}, 21 []rune{}, 22 []rune{69, 69}, 23 []uint32{1}, 24 1, 2, 25 }, 26 { 27 // identical runes, identical targets 28 []rune{69, 69}, 29 []rune{69, 69}, 30 []rune{}, 31 []uint32{mergeFailed}, 32 1, 1, 33 }, 34 { 35 // identical runes, different targets 36 []rune{69, 69}, 37 []rune{69, 69}, 38 []rune{}, 39 []uint32{mergeFailed}, 40 1, 2, 41 }, 42 { 43 // append right-first 44 []rune{69, 69}, 45 []rune{71, 71}, 46 []rune{69, 69, 71, 71}, 47 []uint32{1, 2}, 48 1, 2, 49 }, 50 { 51 // append, left-first 52 []rune{71, 71}, 53 []rune{69, 69}, 54 []rune{69, 69, 71, 71}, 55 []uint32{2, 1}, 56 1, 2, 57 }, 58 { 59 // successful interleave 60 []rune{60, 60, 71, 71, 101, 101}, 61 []rune{69, 69, 88, 88}, 62 []rune{60, 60, 69, 69, 71, 71, 88, 88, 101, 101}, 63 []uint32{1, 2, 1, 2, 1}, 64 1, 2, 65 }, 66 { 67 // left surrounds right 68 []rune{69, 74}, 69 []rune{71, 71}, 70 []rune{}, 71 []uint32{mergeFailed}, 72 1, 2, 73 }, 74 { 75 // right surrounds left 76 []rune{69, 74}, 77 []rune{68, 75}, 78 []rune{}, 79 []uint32{mergeFailed}, 80 1, 2, 81 }, 82 { 83 // overlap at interval begin 84 []rune{69, 74}, 85 []rune{74, 75}, 86 []rune{}, 87 []uint32{mergeFailed}, 88 1, 2, 89 }, 90 { 91 // overlap ar interval end 92 []rune{69, 74}, 93 []rune{65, 69}, 94 []rune{}, 95 []uint32{mergeFailed}, 96 1, 2, 97 }, 98 { 99 // overlap from above 100 []rune{69, 74}, 101 []rune{71, 74}, 102 []rune{}, 103 []uint32{mergeFailed}, 104 1, 2, 105 }, 106 { 107 // overlap from below 108 []rune{69, 74}, 109 []rune{65, 71}, 110 []rune{}, 111 []uint32{mergeFailed}, 112 1, 2, 113 }, 114 { 115 // out of order []rune 116 []rune{69, 74, 60, 65}, 117 []rune{66, 67}, 118 []rune{}, 119 []uint32{mergeFailed}, 120 1, 2, 121 }, 122 } 123 124 func TestMergeRuneSet(t *testing.T) { 125 for ix, test := range runeMergeTests { 126 merged, next := mergeRuneSets(&test.left, &test.right, test.leftPC, test.rightPC) 127 // XXX reflect not supported 128 // if !reflect.DeepEqual(merged, test.merged) { 129 if string(merged) != string(test.merged) { 130 t.Errorf("mergeRuneSet :%d (%v, %v) merged\n have\n%v\nwant\n%v", ix, test.left, test.right, merged, test.merged) 131 } 132 /* XXX reflect not supported 133 if !reflect.DeepEqual(next, test.next) { 134 t.Errorf("mergeRuneSet :%d(%v, %v) next\n have\n%v\nwant\n%v", ix, test.left, test.right, next, test.next) 135 } 136 */ 137 if len(next) != len(test.next) { 138 t.Errorf("mergeRuneSet :%d(%v, %v) next\n have\n%v\nwant\n%v", ix, test.left, test.right, next, test.next) 139 } 140 for i, u32a := range next { 141 u32b := test.next[i] 142 if u32a != u32b { 143 t.Errorf("mergeRuneSet :%d(%v, %v) next\n have\n%v\nwant\n%v", ix, test.left, test.right, next, test.next) 144 } 145 } 146 } 147 } 148 149 var onePassTests = []struct { 150 re string 151 isOnePass bool 152 }{ 153 {`^(?:a|(?:a*))$`, false}, 154 {`^(?:(a)|(?:a*))$`, false}, 155 {`^(?:(?:(?:.(?:$))?))$`, true}, 156 {`^abcd$`, true}, 157 {`^(?:(?:a{0,})*?)$`, false}, 158 {`^(?:(?:a+)*)$`, true}, 159 {`^(?:(?:a|(?:aa)))$`, true}, 160 {`^(?:[^\s\S])$`, true}, 161 {`^(?:(?:a{3,4}){0,})$`, false}, 162 {`^(?:(?:(?:a*)+))$`, true}, 163 {`^[a-c]+$`, true}, 164 {`^[a-c]*$`, true}, 165 {`^(?:a*)$`, true}, 166 {`^(?:(?:aa)|a)$`, true}, 167 {`^[a-c]*`, false}, 168 {`^...$`, true}, 169 {`^(?:a|(?:aa))$`, true}, 170 {`^a((b))c$`, true}, 171 {`^a.[l-nA-Cg-j]?e$`, true}, 172 {`^a((b))$`, true}, 173 {`^a(?:(b)|(c))c$`, true}, 174 {`^a(?:(b*)|(c))c$`, false}, 175 {`^a(?:b|c)$`, true}, 176 {`^a(?:b?|c)$`, true}, 177 {`^a(?:b?|c?)$`, false}, 178 {`^a(?:b?|c+)$`, true}, 179 {`^a(?:b+|(bc))d$`, false}, 180 {`^a(?:bc)+$`, true}, 181 {`^a(?:[bcd])+$`, true}, 182 {`^a((?:[bcd])+)$`, true}, 183 {`^a(:?b|c)*d$`, true}, 184 {`^.bc(d|e)*$`, true}, 185 {`^(?:(?:aa)|.)$`, false}, 186 {`^(?:(?:a{1,2}){1,2})$`, false}, 187 {`^l` + strings.Repeat("o", 2<<8) + `ng$`, true}, 188 } 189 190 func TestCompileOnePass(t *testing.T) { 191 var ( 192 p *syntax.Prog 193 re *syntax.Regexp 194 err error 195 ) 196 for _, test := range onePassTests { 197 if re, err = syntax.Parse(test.re, syntax.Perl); err != nil { 198 t.Errorf("Parse(%q) got err:%s, want success", test.re, err) 199 continue 200 } 201 // needs to be done before compile... 202 re = re.Simplify() 203 if p, err = syntax.Compile(re); err != nil { 204 t.Errorf("Compile(%q) got err:%s, want success", test.re, err) 205 continue 206 } 207 isOnePass := compileOnePass(p) != nil 208 if isOnePass != test.isOnePass { 209 t.Errorf("CompileOnePass(%q) got isOnePass=%v, expected %v", test.re, isOnePass, test.isOnePass) 210 } 211 } 212 } 213 214 // TODO(cespare): Unify with onePassTests and rationalize one-pass test cases. 215 var onePassTests1 = []struct { 216 re string 217 match string 218 }{ 219 {`^a(/b+(#c+)*)*$`, "a/b#c"}, // golang.org/issue/11905 220 } 221 222 func TestRunOnePass(t *testing.T) { 223 for _, test := range onePassTests1 { 224 re, err := Compile(test.re) 225 if err != nil { 226 t.Errorf("Compile(%q): got err: %s", test.re, err) 227 continue 228 } 229 if re.onepass == nil { 230 t.Errorf("Compile(%q): got nil, want one-pass", test.re) 231 continue 232 } 233 if !re.MatchString(test.match) { 234 t.Errorf("onepass %q did not match %q", test.re, test.match) 235 } 236 } 237 }