github.com/everdrone/grab@v0.1.7-0.20230416223925-40674b995521/internal/utils/regex_test.go (about) 1 package utils 2 3 import ( 4 "reflect" 5 "regexp" 6 "testing" 7 ) 8 9 func TestHasNamedCaptures(t *testing.T) { 10 tests := []struct { 11 Name string 12 Regex string 13 Want bool 14 WantNames []string 15 }{ 16 { 17 Name: "no named captures", 18 Regex: "^foo\\s+(bar)?(?:baz)$", 19 Want: false, 20 WantNames: []string{"", ""}, 21 }, 22 { 23 Name: "named captures", 24 Regex: "^(?P<foo>foo)$", 25 Want: true, 26 WantNames: []string{"", "foo"}, 27 }, 28 } 29 30 for _, test := range tests { 31 t.Run(test.Name, func(t *testing.T) { 32 re, err := regexp.Compile(test.Regex) 33 if err != nil { 34 t.Fatal(err) 35 } 36 got, gotNames := HasNamedCaptures(re) 37 38 if got != test.Want { 39 t.Errorf("got: %v, want: %v", got, test.Want) 40 } 41 if !reflect.DeepEqual(gotNames, test.WantNames) { 42 t.Errorf("got: %v, want: %v", gotNames, test.WantNames) 43 } 44 }) 45 } 46 } 47 48 /* 49 // MARK: - With named captures: 50 with find ALL: 51 52 re := "(?P<first>foo)\s*(?P<second>bar)" 53 s := "foo bar foo bar" 54 capture := "first" 55 matches := [ 56 ["foo bar", "foo", "bar"], 57 ["foo bar", "foo", "bar"], 58 ] 59 names := ["", "first", "second"] 60 output := ["foo", "foo"] 61 62 // MARK: - With named captures: 63 with find ONE: 64 65 re := "(?P<first>foo)\s*(?P<second>bar)" 66 s := "foo bar foo bar" 67 capture := "first" 68 matches := ["foo bar", "foo", "bar"] 69 names := ["", "first", "second"] 70 output := ["foo"] 71 72 // MARK: - With capture groups: 73 with find ALL: 74 75 re := "(foo)\s*(bar)" 76 s := "foo bar foo bar" 77 capture := 1 78 matches := [ 79 ["foo bar", "foo", "bar"], 80 ["foo bar", "foo", "bar"], 81 ] 82 names := ["", "", ""] 83 output := ["foo", "foo"] 84 85 // MARK: - With capture groups: 86 with find ONE: 87 88 re := "(foo)\s*(bar)" 89 s := "foo bar foo bar" 90 capture := 1 91 matches := ["foo bar", "foo", "bar"] 92 names := ["", "", ""] 93 output := ["foo"] 94 */ 95 96 func TestGetCaptures(t *testing.T) { 97 tests := []struct { 98 Name string 99 Regex string 100 FindAll bool 101 String string 102 Capture string 103 Want []string 104 WantErr string 105 }{ 106 { 107 Name: "all with no named captures", 108 Regex: "(foo\\d)\\s*(bar)", 109 FindAll: true, 110 Capture: "1", 111 String: "foo1 bar foo2 bar", 112 Want: []string{"foo1", "foo2"}, 113 WantErr: "", 114 }, 115 { 116 Name: "one no named captures", 117 Regex: "(foo\\d)\\s*(bar)", 118 FindAll: false, 119 Capture: "1", 120 String: "foo1 bar foo2 bar", 121 Want: []string{"foo1"}, 122 WantErr: "", 123 }, 124 { 125 Name: "all with named captures", 126 Regex: "(?P<first>foo\\d)\\s*(?P<second>bar)", 127 FindAll: true, 128 Capture: "first", 129 String: "foo1 bar foo2 bar", 130 Want: []string{"foo1", "foo2"}, 131 WantErr: "", 132 }, 133 { 134 Name: "one no named captures", 135 Regex: "(?P<first>foo\\d)\\s*(?P<second>bar)", 136 FindAll: false, 137 Capture: "first", 138 String: "foo1 bar foo2 bar", 139 Want: []string{"foo1"}, 140 WantErr: "", 141 }, 142 143 // MARK: - Failing tests 144 145 { 146 Name: "named with number capture input", 147 Regex: "(?P<first>foo\\d)\\s*(?P<second>bar)", 148 FindAll: false, 149 Capture: "0", 150 String: "foo1 bar foo2 bar", 151 Want: nil, 152 WantErr: "capture `0` not found in expression `(?P<first>foo\\d)\\s*(?P<second>bar)`", 153 }, 154 { 155 Name: "named with existing number capture input", 156 Regex: "(?P<first>foo\\d)\\s*(?P<second>bar)", 157 FindAll: false, 158 Capture: "1", 159 String: "foo1 bar foo2 bar", 160 Want: nil, 161 WantErr: "capture `1` not found in expression `(?P<first>foo\\d)\\s*(?P<second>bar)`", 162 }, 163 { 164 Name: "named when using non-named captures", 165 Regex: "(foo\\d)\\s*(bar)", 166 FindAll: false, 167 Capture: "first", 168 String: "foo1 bar foo2 bar", 169 Want: nil, 170 WantErr: "capture group `first` is not a number", 171 }, 172 { 173 Name: "no captures", 174 Regex: "(foo\\d)\\s*(bar)", 175 FindAll: false, 176 Capture: "1", 177 String: "baz qux", 178 Want: nil, 179 WantErr: "no captures found for pattern `(foo\\d)\\s*(bar)`, capture `1`", 180 }, 181 { 182 Name: "no captures with find all", 183 Regex: "(foo\\d)\\s*(bar)", 184 FindAll: true, 185 Capture: "1", 186 String: "baz qux bez qux", 187 Want: nil, 188 WantErr: "no captures found for pattern `(foo\\d)\\s*(bar)`, capture `1`", 189 }, 190 } 191 192 for _, tt := range tests { 193 t.Run(tt.Name, func(t *testing.T) { 194 re, err := regexp.Compile(tt.Regex) 195 if err != nil { 196 t.Fatal(err) 197 } 198 199 got, err := GetCaptures(re, tt.FindAll, tt.Capture, tt.String) 200 if err != nil && tt.WantErr == "" { 201 t.Errorf("got: %v, want no error", err) 202 } 203 204 if err == nil && tt.WantErr != "" { 205 t.Errorf("got no error, want: %v", tt.WantErr) 206 } 207 208 if err != nil && tt.WantErr != "" { 209 if err.Error() != tt.WantErr { 210 t.Errorf("got: %v, want: %v", err, tt.WantErr) 211 } 212 } 213 214 if !reflect.DeepEqual(got, tt.Want) { 215 t.Errorf("got: %#v, want: %#v", got, tt.Want) 216 } 217 }) 218 } 219 }