github.com/mailru/activerecord@v1.12.2/internal/pkg/generator/tmpl/octopus/fixturestore.tmpl (about) 1 package {{ .FixturePkg }} 2 3 import ( 4 _ "embed" 5 "context" 6 "fmt" 7 "log" 8 "sync" 9 10 "gopkg.in/yaml.v3" 11 12 "github.com/mailru/activerecord/pkg/activerecord" 13 "github.com/mailru/activerecord/pkg/octopus" 14 15 {{- range $ind, $imp := .Imports }} 16 {{ if ne $imp.ImportName "" }}{{- $imp.ImportName }} {{ end }}"{{ $imp.Path }}" 17 {{- end }} 18 {{- range $i, $imp := addImport .FieldList }} 19 "{{ $imp }}" 20 {{- end }} 21 ) 22 {{ $serializers := .Serializers -}} 23 {{ $PackageName := .ARPkg -}} 24 {{ $PublicStructName := .ARPkgTitle -}} 25 {{ $fields := .FieldList }} 26 {{ $procfields := .ProcOutFieldList }} 27 {{ $procInLen := len .ProcInFieldList }} 28 {{ $typePK := "" -}} 29 {{ $fieldNamePK := "" -}} 30 {{ $mutators := .Mutators -}} 31 {{ $mutatorLen := len .Mutators }} 32 33 {{ if $procfields }} 34 {{ $typePK := "string" -}} 35 var {{$PackageName}}Once sync.Once 36 var {{$PackageName}}Store map[{{$typePK}}]int 37 var {{$PackageName}}Fixtures []*{{$PackageName}}.{{$PublicStructName}} 38 39 //go:embed data/{{$PackageName}}.yaml 40 var {{$PackageName}}Source []byte 41 42 func init{{$PublicStructName}}() { 43 {{$PackageName}}Once.Do(func() { 44 {{$PackageName}}Fixtures = {{$PackageName}}.UnmarshalFromYaml({{$PackageName}}Source) 45 46 {{$PackageName}}Store = map[{{$typePK}}]int{} 47 for i, f := range {{$PackageName}}Fixtures { 48 if _, ok := {{$PackageName}}Store[f.GetParams().PK()]; ok { 49 log.Fatalf("{{$PackageName}} fixture with params %v are duplicated", f.GetParams()) 50 } 51 {{$PackageName}}Store[f.GetParams().PK()] = i 52 } 53 }) 54 } 55 56 func Get{{$PublicStructName}}ByParams(params {{$PackageName}}.{{$PublicStructName}}Params) *{{$PackageName}}.{{$PublicStructName}} { 57 init{{$PublicStructName}}() 58 59 idx, ex := {{$PackageName}}Store[params.PK()] 60 if !ex { 61 log.Fatalf("{{$PublicStructName}} fixture with params %v not found", params) 62 } 63 64 res := {{$PackageName}}Fixtures[idx] 65 66 ctx := activerecord.Logger().SetLoggerValueToContext(context.Background(), map[string]interface{}{"Get{{$PublicStructName}}ByParams": params, "FixtureStore": "{{$PackageName}}Store"}) 67 68 activerecord.Logger().Debug(ctx, {{$PackageName}}.{{$PublicStructName}}List([]*{{$PackageName}}.{{$PublicStructName}}{res})) 69 70 return res 71 } 72 73 type {{ $PublicStructName }}ProcedureMocker struct {} 74 75 func Get{{ $PublicStructName }}ProcedureMocker() {{ $PublicStructName }}ProcedureMocker { 76 return {{ $PublicStructName }}ProcedureMocker{} 77 } 78 79 func (m {{ $PublicStructName }}ProcedureMocker) ByFixture{{ if ne $procInLen 0 }}Params{{ end }}(ctx context.Context{{ if ne $procInLen 0 }}, params {{$PackageName}}.{{ $PublicStructName }}Params{{ end }}) octopus.FixtureType { 80 {{ if ne $procInLen 0 }} 81 return m.ByParamsMocks(ctx, params, 82 []octopus.MockEntities{ 83 Get{{$PublicStructName}}ByParams(params), 84 }) 85 {{ else }} 86 return m.ByMocks(ctx, 87 []octopus.MockEntities{ 88 Get{{$PublicStructName}}ByParams({{$PackageName}}.{{$PublicStructName}}Params{}), 89 }) 90 {{- end }} 91 } 92 93 func (m {{ $PublicStructName }}ProcedureMocker) By{{ if ne $procInLen 0 }}Params{{ end }}Mocks(ctx context.Context{{ if ne $procInLen 0 }}, params {{$PackageName}}.{{ $PublicStructName }}Params{{ end }}, mocks []octopus.MockEntities) octopus.FixtureType { 94 oft, err := octopus.CreateCallFixture( 95 func(wsubME []octopus.MockEntities) []byte { 96 return {{$PackageName}}.MockCallRequest(ctx{{ if ne $procInLen 0 }}, params{{ end }}) 97 }, 98 mocks, 99 ) 100 if err != nil { 101 activerecord.Logger().Fatal(ctx, fmt.Sprintf("Error create mock by params: %s", err)) 102 } 103 104 return oft 105 } 106 {{ end }} 107 108 {{ if $fields }} 109 {{ range $num, $ind := .Indexes -}} 110 {{ $lenfld := len $ind.Fields -}} 111 {{ if $ind.Primary }} 112 {{ if ne $lenfld 1 }} 113 {{ $typePK = print $PackageName "." $ind.Type }} 114 {{ else }} 115 {{- $typePK = $ind.Type -}} 116 {{ end }} 117 {{- $fieldNamePK = $ind.Name -}} 118 {{ end }} 119 {{ end }} 120 121 {{ range $_, $mockOperation := split ",Update,InsertReplace" "," }} 122 var {{$PackageName}}{{ $mockOperation }}Once sync.Once 123 var {{$PackageName}}{{ $mockOperation }}Store map[{{$typePK}}]int 124 var {{$PackageName}}{{ $mockOperation }}Fixtures []*{{$PackageName}}.{{$PublicStructName}} 125 126 //go:embed data/{{$PackageName}}{{ if ne $mockOperation "" -}} _{{ $mockOperation | snakeCase }}{{ end }}.yaml 127 var {{$PackageName}}{{ $mockOperation }}Source []byte 128 129 func init{{$mockOperation}}{{$PublicStructName}}() { 130 {{$PackageName}}{{ $mockOperation }}Once.Do(func() { 131 {{$PackageName}}{{$mockOperation}}Fixtures = {{$PackageName}}.Unmarshal{{$mockOperation}}FromYaml({{$PackageName}}{{ $mockOperation }}Source) 132 133 {{$PackageName}}{{$mockOperation}}Store = map[{{$typePK}}]int{} 134 for i, f := range {{$PackageName}}{{$mockOperation}}Fixtures { 135 if _, ok := {{$PackageName}}{{$mockOperation}}Store[f.Primary()]; ok { 136 log.Fatalf("{{$PackageName}} {{ $mockOperation }} fixture with {{$fieldNamePK}} %v is duplicated", f.Primary()) 137 } 138 {{$PackageName}}{{ $mockOperation }}Store[f.Primary()] = i 139 } 140 }) 141 } 142 143 func Get{{$mockOperation}}{{$PublicStructName}}By{{$fieldNamePK}}({{$fieldNamePK}} {{$typePK}}) *{{$PackageName}}.{{$PublicStructName}} { 144 init{{$mockOperation}}{{$PublicStructName}}() 145 146 idx, ex := {{$PackageName}}{{$mockOperation}}Store[{{$fieldNamePK}}] 147 if !ex { 148 log.Fatalf("{{$PublicStructName}} {{$mockOperation}} fixture with {{$fieldNamePK}} %v not found", {{$fieldNamePK}}) 149 } 150 151 res := {{$PackageName}}{{$mockOperation}}Fixtures[idx] 152 153 ctx := activerecord.Logger().SetLoggerValueToContext(context.Background(), map[string]interface{}{"Get{{$mockOperation}}{{$PublicStructName}}By{{$fieldNamePK}}": {{$fieldNamePK}}, "FixtureStore": "{{$PackageName}}{{$mockOperation}}Store"}) 154 155 activerecord.Logger().Debug(ctx, {{$PackageName}}.{{$PublicStructName}}List([]*{{$PackageName}}.{{$PublicStructName}}{res})) 156 157 return res 158 } 159 {{ end }} 160 161 func GetDelete{{$PublicStructName}}FixtureByPrimaryKey(ctx context.Context, pk {{ $typePK }}, trigger func(types []octopus.FixtureType) []octopus.FixtureType) (fx octopus.FixtureType, promiseIsUsed func () bool) { 162 obj := {{$PackageName}}.New(ctx) 163 {{ range $num, $ind := .Indexes -}} 164 {{ $lenfld := len $ind.Fields }} 165 {{ if $ind.Primary }} 166 {{ if ne $lenfld 1 }} 167 {{ range $_, $fieldNum := $ind.Fields }} 168 {{- $ifield := index $fields $fieldNum }} 169 if err := obj.Set{{ $ifield.Name }}(pk.{{ $ifield.Name }}); err != nil { 170 log.Fatalf("Set{{ $ifield.Name }} error: %v", err) 171 } 172 {{ end }} 173 {{ else }} 174 if err := obj.Set{{ $fieldNamePK }}(pk); err != nil { 175 log.Fatalf("Set{{ $fieldNamePK }} error: %v", err) 176 } 177 {{ end }} 178 {{ end }} 179 {{ end }} 180 181 wrappedTrigger, promiseIsUsed := octopus.WrapTriggerWithOnUsePromise(trigger) 182 183 return octopus.CreateDeleteFixture(obj.MockDelete(ctx), wrappedTrigger), promiseIsUsed 184 } 185 186 func GetUpdate{{$PublicStructName}}FixtureBy{{ $fieldNamePK }}(ctx context.Context, {{ $fieldNamePK }} {{$typePK}}, trigger func(types []octopus.FixtureType) []octopus.FixtureType) (fx octopus.FixtureType, promiseIsUsed func () bool) { 187 obj := GetUpdate{{$PublicStructName}}By{{$fieldNamePK}}({{ $fieldNamePK }}) 188 189 wrappedTrigger, promiseIsUsed := octopus.WrapTriggerWithOnUsePromise(trigger) 190 191 return octopus.CreateUpdateFixture(obj.MockUpdate(ctx), wrappedTrigger), promiseIsUsed 192 } 193 194 func {{$PublicStructName}}StoreIterator() func(it func(any) error) error { 195 return func(it func(e any) error) error { 196 init{{$PublicStructName}}() 197 198 for _, e := range {{$PackageName}}Fixtures { 199 if err := it(e); err != nil { 200 return err 201 } 202 } 203 204 return nil 205 } 206 } 207 208 {{ range $ind, $fstruct := $fields -}} 209 {{- range $i, $mut := $fstruct.Mutators -}} 210 {{ $customMutator := index $mutators $mut -}} 211 {{ if and (ne $customMutator.Update "") $customMutator.Name }} 212 // Нужно доработать, т.к. пока из файла репозитория фикстур update.yaml нельзя выборочно устанавливать значения частично обновляемого поля 213 // Все неустановленные поля будут проинициализированы дефолтными значениями 214 func GetUpdateMutator{{$customMutator.Name}}FixtureBy{{ $fieldNamePK }}(ctx context.Context, {{ $fieldNamePK }} {{$typePK}}) (fxt octopus.FixtureType) { 215 obj := GetUpdate{{$PublicStructName}}By{{$fieldNamePK}}({{ $fieldNamePK }}) 216 217 for _, req := range obj.MockMutator{{$customMutator.Name}}Update(ctx) { 218 ft, _ := octopus.CreateCallFixture( 219 func(wsubME []octopus.MockEntities) []byte { 220 return req 221 }, nil) 222 // available only one 223 return ft 224 } 225 226 return 227 } 228 {{end}} 229 {{end}} 230 {{end}} 231 232 {{ range $_, $mockOperation := split "Insert,Replace,InsertOrReplace" "," }} 233 func Get{{ $mockOperation }}{{$PublicStructName}}FixtureBy{{ $fieldNamePK }}(ctx context.Context, {{ $fieldNamePK }} {{ $typePK }}, trigger func([]octopus.FixtureType) []octopus.FixtureType) (fx octopus.FixtureType, promiseIsUsed func () bool) { 234 obj := GetInsertReplace{{$PublicStructName}}By{{$fieldNamePK}}({{ $fieldNamePK }}) 235 236 return Get{{ $mockOperation }}{{$PublicStructName}}FixtureByModel(ctx, obj, trigger) 237 } 238 239 func Get{{ $mockOperation }}{{$PublicStructName}}FixtureByModel(ctx context.Context, obj *{{ $PackageName }}.{{ $PublicStructName }}, trigger func([]octopus.FixtureType) []octopus.FixtureType) (fx octopus.FixtureType, promiseIsUsed func () bool){ 240 reqData := obj.Mock{{ $mockOperation }}(ctx) 241 242 wrappedTrigger, promiseIsUsed := octopus.WrapTriggerWithOnUsePromise(trigger) 243 244 return octopus.CreateInsertOrReplaceFixture(obj, reqData, wrappedTrigger), promiseIsUsed 245 } 246 {{ end }} 247 248 type {{ $PublicStructName }}BuildableFixture struct { 249 PrimaryKey {{ $typePK }} // {{ $fieldNamePK }} 250 updateOps []{{$PackageName}}.{{ $PublicStructName }}UpdateFixtureOptions 251 252 trigger func([]octopus.FixtureType) []octopus.FixtureType 253 } 254 255 func Update{{ $PublicStructName }}Fixture({{ $fieldNamePK }} {{ $typePK }}) {{ $PublicStructName }}BuildableFixture { 256 return {{ $PublicStructName }}BuildableFixture{PrimaryKey: {{ $fieldNamePK }} } 257 } 258 259 {{- range $_, $fstruct := .FieldList}} 260 {{/* Determine real filed type */}} 261 {{ $rtype := $fstruct.Format -}} 262 {{ $sname := $fstruct.Serializer.Name -}} 263 {{ if ne $sname "" -}} 264 {{ $serializer := index $serializers $sname -}} 265 {{ $rtype = $serializer.Type -}} 266 {{ end -}} 267 268 {{/* без учета первичного ключа */}} 269 {{ if ne $fstruct.Name $fieldNamePK }} 270 func (bf {{ $PublicStructName }}BuildableFixture) WithUpdated{{$fstruct.Name}}(val {{$rtype}}) {{ $PublicStructName }}BuildableFixture { 271 bf.updateOps = append( 272 bf.updateOps, 273 {{$PackageName}}.{{ $PublicStructName }}UpdateFixtureOptions{ {{$fstruct.Name}}: &{{$PackageName}}.{{ $PublicStructName }}{{$fstruct.Name}}UpdateFixtureOption{ Value: val } }, 274 ) 275 276 return bf 277 } 278 {{ end }} 279 {{- end }} 280 281 func (bf {{ $PublicStructName }}BuildableFixture) OnUpdate(trigger func([]octopus.FixtureType) []octopus.FixtureType) {{ $PublicStructName }}BuildableFixture { 282 bf.trigger = trigger 283 284 return bf 285 } 286 287 func (bf {{ $PublicStructName }}BuildableFixture) Build(ctx context.Context) (fx octopus.FixtureType, promiseIsUsed func() bool) { 288 wrappedTrigger, promiseIsUsed := octopus.WrapTriggerWithOnUsePromise(bf.trigger) 289 290 obj := {{$PackageName}}.New(ctx) 291 292 {{ range $num, $ind := .Indexes -}} 293 {{ $lenfld := len $ind.Fields }} 294 {{ if $ind.Primary }} 295 {{ if ne $lenfld 1 }} 296 {{ range $_, $fieldNum := $ind.Fields }} 297 {{- $ifield := index $fields $fieldNum }} 298 if err := obj.Set{{ $ifield.Name }}(bf.PrimaryKey.{{ $ifield.Name }}); err != nil { 299 log.Fatalf("Set{{ $ifield.Name }} error: %v", err) 300 } 301 {{ end }} 302 {{ else }} 303 if err := obj.Set{{ $fieldNamePK }}(bf.PrimaryKey); err != nil { 304 log.Fatalf("Set{{ $fieldNamePK }} error: %v", err) 305 } 306 {{ end }} 307 {{ end }} 308 {{ end }} 309 310 obj.BaseField.UpdateOps = []octopus.Ops{} 311 312 {{$PackageName}}.SetFixtureUpdateOptions(obj, bf.updateOps) 313 314 return octopus.CreateUpdateFixture(obj.MockUpdate(ctx), wrappedTrigger), promiseIsUsed 315 } 316 {{- end }} 317 318 {{ range $num, $ind := .Indexes -}} 319 {{ $lenfld := len $ind.Fields }} 320 321 type {{ $PublicStructName }}By{{ $ind.Selector }}Mocker struct { 322 {{ if not $ind.Unique }}limiter activerecord.SelectorLimiter{{ end }} 323 } 324 325 func Get{{ $PublicStructName }}By{{ $ind.Name }}Mocker({{ if not $ind.Unique }}limiter activerecord.SelectorLimiter{{ end }}) {{ $PublicStructName }}By{{ $ind.Selector }}Mocker { 326 return {{ $PublicStructName }}By{{ $ind.Selector }}Mocker{ {{ if not $ind.Unique }}limiter: limiter{{ end }} } 327 } 328 329 func (m {{ $PublicStructName }}By{{ $ind.Selector }}Mocker) ByFixture{{ $fieldNamePK }}(ctx context.Context, {{ $fieldNamePK }}s ...{{ $typePK }}) octopus.FixtureType { 330 mocks := []octopus.MockEntities{} 331 logger := activerecord.Logger() 332 333 var key *{{ if eq $lenfld 1 }}{{ $ind.Type }}{{ else }}{{ $PackageName }}.{{ $ind.Type }}{{ end }} 334 335 for _, {{ $fieldNamePK }} := range {{ $fieldNamePK }}s { 336 fix := Get{{ $PublicStructName }}By{{$fieldNamePK}}({{ $fieldNamePK }}) 337 mocks = append(mocks, fix) 338 339 {{ if eq $lenfld 1 }} 340 if key == nil { 341 {{ $ifld := index $ind.Fields 0 }} 342 {{ $ifield := index $fields $ifld }} 343 ikey := fix.Get{{ $ifield.Name }}() 344 key = &ikey 345 } else if *key != fix.Get{{ $ifield.Name }}() { 346 logger.Fatal(ctx, "Non unique keys in fixture list") 347 } 348 {{ else }} 349 if key == nil { 350 key = &{{ $PackageName }}.{{ $ind.Type }}{ 351 {{ range $_, $fieldNum := $ind.Fields }} 352 {{- $ifield := index $fields $fieldNum }} 353 {{ $ifield.Name }}: fix.Get{{ $ifield.Name }}(), 354 {{ end }} 355 } 356 } else { 357 {{ range $_, $fieldNum := $ind.Fields }} 358 {{- $ifield := index $fields $fieldNum }} 359 if fix.Get{{ $ifield.Name }}() != key.{{ $ifield.Name }} { 360 logger.Fatal(ctx, "Non unique keys in fixture list") 361 } 362 {{ end }} 363 } 364 365 {{ end }} 366 } 367 368 return m.ByKeysMocks(ctx, []{{ if eq $lenfld 1 }}{{ $ind.Type }}{{ else }}{{ $PackageName }}.{{ $ind.Type }}{{ end }}{*key}, mocks) 369 } 370 371 func (m {{ $PublicStructName }}By{{ $ind.Selector }}Mocker) EmptyByKeys(ctx context.Context, keys ...{{ if eq $lenfld 1 }}{{ $ind.Type }}{{ else }}{{ $PackageName }}.{{ $ind.Type }}{{ end }}) octopus.FixtureType { 372 return m.ByKeysMocks(ctx, keys, []octopus.MockEntities{}) 373 } 374 375 func (m {{ $PublicStructName }}By{{ $ind.Selector }}Mocker) ByFixturePKWithKeys(ctx context.Context, {{ $fieldNamePK }}s []{{ $typePK }}, keys []{{ if eq $lenfld 1 }}{{ $ind.Type }}{{ else }}{{ $PackageName }}.{{ $ind.Type }}{{ end }}) octopus.FixtureType { 376 mocks := []octopus.MockEntities{} 377 378 for _, {{ $fieldNamePK }} := range {{ $fieldNamePK }}s { 379 fix := Get{{ $PublicStructName }}By{{$fieldNamePK}}({{ $fieldNamePK }}) 380 mocks = append(mocks, fix) 381 } 382 383 return m.ByKeysMocks(ctx, keys, mocks) 384 } 385 386 func (m {{ $PublicStructName }}By{{ $ind.Selector }}Mocker) ByKeysMocks(ctx context.Context, keys []{{ if eq $lenfld 1 }}{{ $ind.Type }}{{ else }}{{ $PackageName }}.{{ $ind.Type }}{{ end }}, mocks []octopus.MockEntities) octopus.FixtureType { 387 oft, err := octopus.CreateSelectFixture( 388 func(wsubME []octopus.MockEntities) []byte { 389 return {{ $PackageName }}.New(ctx).Mock{{ $ind.Selector }}sRequest(ctx, keys{{ if not $ind.Unique }}, m.limiter{{ end }}) 390 }, 391 mocks, 392 ) 393 if err != nil { 394 activerecord.Logger().Fatal(ctx, fmt.Sprintf("Error create mock by EmptyByKeys: %s", err)) 395 } 396 397 return oft 398 } 399 400 {{ end }}