github.com/mailru/activerecord@v1.12.2/internal/pkg/parser/parser_w_test.go (about) 1 package parser 2 3 import ( 4 "go/ast" 5 "go/token" 6 "reflect" 7 "testing" 8 9 "github.com/mailru/activerecord/internal/pkg/ds" 10 "github.com/mailru/activerecord/pkg/octopus" 11 ) 12 13 func Test_parseDoc(t *testing.T) { 14 type args struct { 15 dst *ds.RecordPackage 16 docs *ast.CommentGroup 17 } 18 19 tests := []struct { 20 name string 21 args args 22 want *ds.RecordPackage 23 wantErr bool 24 }{ 25 { 26 name: "doc", 27 args: args{ 28 dst: ds.NewRecordPackage(), 29 docs: &ast.CommentGroup{ 30 List: []*ast.Comment{ 31 {Text: `//ar:serverHost:127.0.0.1;serverPort:11011;serverTimeout:500`}, 32 {Text: `//ar:namespace:5`}, 33 {Text: `//ar:backend:octopus`}, 34 }, 35 }, 36 }, 37 wantErr: false, 38 want: &ds.RecordPackage{ 39 Server: ds.ServerDeclaration{ 40 Host: "127.0.0.1", 41 Port: "11011", 42 Timeout: 500, 43 }, 44 Namespace: ds.NamespaceDeclaration{ 45 ObjectName: "5", 46 PublicName: "", 47 PackageName: "", 48 }, 49 Backends: []string{"octopus"}, 50 Fields: []ds.FieldDeclaration{}, 51 FieldsMap: map[string]int{}, 52 ProcFieldsMap: map[string]int{}, 53 ProcOutFields: map[int]ds.ProcFieldDeclaration{}, 54 FieldsObjectMap: map[string]ds.FieldObject{}, 55 Indexes: []ds.IndexDeclaration{}, 56 IndexMap: map[string]int{}, 57 SelectorMap: map[string]int{}, 58 ImportPackage: ds.NewImportPackage(), 59 SerializerMap: map[string]ds.SerializerDeclaration{}, 60 TriggerMap: map[string]ds.TriggerDeclaration{}, 61 FlagMap: map[string]ds.FlagDeclaration{}, 62 MutatorMap: map[string]ds.MutatorDeclaration{}, 63 ImportStructFieldsMap: map[string][]ds.PartialFieldDeclaration{}, 64 LinkedStructsMap: map[string]ds.LinkedPackageDeclaration{}, 65 }, 66 }, 67 { 68 name: "docComment", 69 args: args{ 70 dst: ds.NewRecordPackage(), 71 docs: &ast.CommentGroup{ 72 List: []*ast.Comment{ 73 {Text: `//blablabla`}, 74 }, 75 }, 76 }, 77 wantErr: false, 78 want: ds.NewRecordPackage(), 79 }, 80 { 81 name: "docError", 82 args: args{ 83 dst: ds.NewRecordPackage(), 84 docs: &ast.CommentGroup{ 85 List: []*ast.Comment{ 86 {Text: `//ar:fdgsdsfgdf`}, 87 }, 88 }, 89 }, 90 wantErr: true, 91 want: ds.NewRecordPackage(), 92 }, 93 } 94 for _, tt := range tests { 95 t.Run(tt.name, func(t *testing.T) { 96 if err := parseDoc(tt.args.dst, string(Fields), tt.args.docs); (err != nil) != tt.wantErr { 97 t.Errorf("parseDoc() error = %v, wantErr %v", err, tt.wantErr) 98 return 99 } 100 101 if !reflect.DeepEqual(tt.args.dst, tt.want) { 102 t.Errorf("parseDoc() dst = %+v, want %+v", tt.args.dst, tt.want) 103 return 104 } 105 }) 106 } 107 } 108 109 func Test_parseGen(t *testing.T) { 110 type args struct { 111 dst *ds.RecordPackage 112 genD *ast.GenDecl 113 } 114 w := ds.NewRecordPackage() 115 w.Backends = []string{"octopus"} 116 w.Namespace = ds.NamespaceDeclaration{ 117 ObjectName: "5", 118 PublicName: "Baz", 119 PackageName: "baz", 120 } 121 w.Server = ds.ServerDeclaration{ 122 Timeout: 500, 123 Host: "127.0.0.1", 124 Port: "11011", 125 } 126 wLinked := ds.NewRecordPackage() 127 wLinked.Backends = []string{"octopus"} 128 wLinked.Namespace = ds.NamespaceDeclaration{ 129 ObjectName: "5", 130 PublicName: "Foo", 131 PackageName: "foo", 132 } 133 wLinked.Server = ds.ServerDeclaration{ 134 Timeout: 500, 135 Host: "127.0.0.1", 136 Port: "11011", 137 } 138 wLinked.FieldsMap["ID"] = len(wLinked.Fields) 139 wLinked.Fields = append(wLinked.Fields, ds.FieldDeclaration{ 140 Name: "ID", 141 Format: octopus.Int, 142 PrimaryKey: true, 143 Mutators: []string{}, 144 Size: 0, 145 Serializer: []string{}, 146 ObjectLink: "", 147 }) 148 wLinked.FieldsMap["BarID"] = len(wLinked.Fields) 149 wLinked.Fields = append(wLinked.Fields, ds.FieldDeclaration{ 150 Name: "BarID", 151 Format: octopus.Int, 152 PrimaryKey: false, 153 Mutators: []string{}, 154 Size: 0, 155 Serializer: []string{}, 156 ObjectLink: "Bar", 157 }) 158 wLinked.FieldsObjectMap["Bar"] = ds.FieldObject{ 159 Name: "Bar", 160 Key: "ID", 161 ObjectName: "bar", 162 Field: "BarID", 163 Unique: true, 164 } 165 wantIndex := ds.IndexDeclaration{ 166 Name: "ID", 167 Primary: true, 168 Fields: []int{0}, 169 FieldsMap: map[string]ds.IndexField{"ID": {IndField: 0, Order: 0}}, 170 Selector: "SelectByID", 171 Unique: true, 172 Num: 0, 173 } 174 wLinked.IndexMap[wantIndex.Name] = len(wLinked.Indexes) 175 wLinked.SelectorMap[wantIndex.Selector] = len(wLinked.Indexes) 176 wLinked.Indexes = append(wLinked.Indexes, wantIndex) 177 178 tests := []struct { 179 name string 180 args args 181 wantErr bool 182 want *ds.RecordPackage 183 }{ 184 { 185 name: "private and public names", 186 args: args{ 187 dst: ds.NewRecordPackage(), 188 genD: &ast.GenDecl{ 189 Tok: token.TYPE, 190 Doc: &ast.CommentGroup{ 191 List: []*ast.Comment{ 192 {Text: `//ar:serverHost:127.0.0.1;serverPort:11011;serverTimeout:500`}, 193 {Text: `//ar:namespace:5`}, 194 {Text: `//ar:backend:octopus`}, 195 }, 196 }, 197 Specs: []ast.Spec{ 198 &ast.TypeSpec{ 199 Type: &ast.StructType{ 200 Fields: &ast.FieldList{ 201 List: []*ast.Field{}, 202 }, 203 }, 204 Name: &ast.Ident{ 205 Name: "FieldsBaz", 206 }, 207 }, 208 }, 209 }, 210 }, 211 wantErr: false, 212 want: w, 213 }, 214 { 215 name: "Invalid names in struct", 216 args: args{ 217 dst: ds.NewRecordPackage(), 218 genD: &ast.GenDecl{ 219 Tok: token.TYPE, 220 Doc: &ast.CommentGroup{ 221 List: []*ast.Comment{ 222 {Text: `//ar:serverHost:127.0.0.1;serverPort:11011;serverTimeout:500`}, 223 {Text: `//ar:namespace:5`}, 224 {Text: `//ar:backend:octopus`}, 225 }, 226 }, 227 Specs: []ast.Spec{ 228 &ast.TypeSpec{ 229 Type: &ast.StructType{ 230 Fields: &ast.FieldList{ 231 List: []*ast.Field{}, 232 }, 233 }, 234 Name: &ast.Ident{ 235 Name: "FieldsBaz", 236 }, 237 }, 238 &ast.TypeSpec{ 239 Type: &ast.StructType{ 240 Fields: &ast.FieldList{ 241 List: []*ast.Field{}, 242 }, 243 }, 244 Name: &ast.Ident{ 245 Name: "IndexesInvalid", 246 }, 247 }, 248 }, 249 }, 250 }, 251 wantErr: true, 252 want: w, 253 }, 254 { 255 name: "linked objects", 256 args: args{ 257 dst: ds.NewRecordPackage(), 258 genD: &ast.GenDecl{ 259 Tok: token.TYPE, 260 Doc: &ast.CommentGroup{ 261 List: []*ast.Comment{ 262 {Text: `//ar:serverHost:127.0.0.1;serverPort:11011;serverTimeout:500`}, 263 {Text: `//ar:namespace:5`}, 264 {Text: `//ar:backend:octopus`}, 265 }, 266 }, 267 Specs: []ast.Spec{ 268 &ast.TypeSpec{ 269 Type: &ast.StructType{ 270 Fields: &ast.FieldList{ 271 List: []*ast.Field{ 272 { 273 Names: []*ast.Ident{{Name: "ID"}}, 274 Type: &ast.Ident{Name: "int"}, 275 Tag: &ast.BasicLit{Value: "`" + `ar:"primary_key"` + "`"}, 276 }, 277 { 278 Names: []*ast.Ident{{Name: "BarID"}}, 279 Type: &ast.Ident{Name: "int"}, 280 Tag: &ast.BasicLit{Value: "`" + `ar:""` + "`"}, 281 }, 282 }, 283 }, 284 }, 285 Name: &ast.Ident{ 286 Name: "FieldsFoo", 287 }, 288 }, 289 &ast.TypeSpec{ 290 Type: &ast.StructType{ 291 Fields: &ast.FieldList{ 292 List: []*ast.Field{ 293 { 294 Names: []*ast.Ident{{Name: "Bar"}}, 295 Type: &ast.Ident{Name: "bool"}, 296 Tag: &ast.BasicLit{Value: "`" + `ar:"key:ID;object:bar;field:BarID"` + "`"}, 297 }, 298 }, 299 }, 300 }, 301 Name: &ast.Ident{ 302 Name: "FieldsObjectFoo", 303 }, 304 }, 305 }, 306 }, 307 }, 308 wantErr: false, 309 want: wLinked, 310 }, 311 } 312 for _, tt := range tests { 313 t.Run(tt.name, func(t *testing.T) { 314 if err := parseGen(tt.args.dst, tt.args.genD); (err != nil) != tt.wantErr { 315 t.Errorf("parseGen() error = %v, wantErr %v", err, tt.wantErr) 316 return 317 } 318 319 if !reflect.DeepEqual(tt.args.dst, tt.want) { 320 t.Errorf("parseGen() %+v, want %+v", tt.args.dst, tt.want) 321 } 322 }) 323 } 324 } 325 326 func Test_parseAst(t *testing.T) { 327 type args struct { 328 pkgName string 329 decls []ast.Decl 330 rc *ds.RecordPackage 331 } 332 tests := []struct { 333 name string 334 args args 335 wantErr bool 336 want *ds.RecordPackage 337 }{ 338 { 339 name: "private and public names", 340 args: args{ 341 rc: ds.NewRecordPackage(), 342 decls: []ast.Decl{ 343 &ast.GenDecl{ 344 Tok: token.TYPE, 345 Doc: &ast.CommentGroup{ 346 List: []*ast.Comment{ 347 {Text: `//ar:serverHost:127.0.0.1;serverPort:11011;serverTimeout:500`}, 348 {Text: `//ar:namespace:5`}, 349 {Text: `//ar:backend:octopus`}, 350 }, 351 }, 352 Specs: []ast.Spec{ 353 &ast.TypeSpec{ 354 Type: &ast.StructType{ 355 Fields: &ast.FieldList{ 356 List: []*ast.Field{}, 357 }, 358 }, 359 Name: &ast.Ident{ 360 Name: "FieldsBaz", 361 }, 362 }, 363 }, 364 }, 365 }, 366 }, 367 wantErr: false, 368 want: &ds.RecordPackage{ 369 Server: ds.ServerDeclaration{Timeout: 500, Host: "127.0.0.1", Port: "11011"}, 370 Namespace: ds.NamespaceDeclaration{ObjectName: "5", PublicName: "Baz", PackageName: "baz"}, 371 ProcFieldsMap: map[string]int{}, 372 ProcOutFields: map[int]ds.ProcFieldDeclaration{}, 373 Fields: []ds.FieldDeclaration{}, 374 FieldsMap: map[string]int{}, 375 FieldsObjectMap: map[string]ds.FieldObject{}, 376 Indexes: []ds.IndexDeclaration{}, 377 IndexMap: map[string]int{}, 378 SelectorMap: map[string]int{}, 379 Backends: []string{"octopus"}, 380 SerializerMap: map[string]ds.SerializerDeclaration{}, 381 ImportPackage: ds.NewImportPackage(), 382 TriggerMap: map[string]ds.TriggerDeclaration{}, 383 FlagMap: map[string]ds.FlagDeclaration{}, 384 MutatorMap: map[string]ds.MutatorDeclaration{}, 385 ImportStructFieldsMap: map[string][]ds.PartialFieldDeclaration{}, 386 LinkedStructsMap: map[string]ds.LinkedPackageDeclaration{}, 387 }, 388 }, 389 } 390 for _, tt := range tests { 391 t.Run(tt.name, func(t *testing.T) { 392 if err := parseAst(tt.args.pkgName, tt.args.decls, tt.args.rc); (err != nil) != tt.wantErr { 393 t.Errorf("parseAst() error = %v, wantErr %v", err, tt.wantErr) 394 } 395 396 if !reflect.DeepEqual(tt.args.rc, tt.want) { 397 t.Errorf("parseAst() %+v, want %+v", tt.args.rc, tt.want) 398 } 399 }) 400 } 401 }