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 }}