Skip to content

Commit

Permalink
feat(fxgenerate): Added UUID V7 generator
Browse files Browse the repository at this point in the history
  • Loading branch information
ekkinox committed Jun 3, 2024
1 parent 35937a9 commit 7b85ce7
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 30 deletions.
98 changes: 84 additions & 14 deletions fxgenerate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
<!-- TOC -->
* [Installation](#installation)
* [Documentation](#documentation)
* [Loading](#loading)
* [Generators](#generators)
* [UUID](#uuid)
* [Usage](#usage)
* [Testing](#testing)
* [Override](#override)
* [Loading](#loading)
* [Generators](#generators)
* [UUID V4](#uuid-v4)
* [Usage](#usage)
* [Testing](#testing)
* [UUID V7](#uuid-v7)
* [Usage](#usage-1)
* [Testing](#testing-1)
* [Override](#override)
<!-- TOC -->

## Installation
Expand Down Expand Up @@ -46,7 +49,7 @@ func main() {

### Generators

#### UUID
#### UUID V4

##### Usage

Expand All @@ -65,8 +68,8 @@ import (

func main() {
fx.New(
fxgenerate.FxGenerateModule, // load the module
fx.Invoke(func(generator *uuid.UuidGenerator) { // invoke the uuid generator
fxgenerate.FxGenerateModule, // load the module
fx.Invoke(func(generator uuid.UuidGenerator) { // invoke the uuid generator
fmt.Printf("uuid: %s", generator.Generate()) // uuid: dcb5d8b3-4517-4957-a42c-604d11758561
}),
).Run()
Expand Down Expand Up @@ -106,18 +109,85 @@ func main() {
),
),
fx.Decorate(fxtestuuid.NewFxTestUuidGeneratorFactory), // override the module with the TestUuidGeneratorFactory
fx.Invoke(func(generator *uuid.UuidGenerator) { // invoke the generator
fx.Invoke(func(generator uuid.UuidGenerator) { // invoke the generator
fmt.Printf("uuid: %s", generator.Generate()) // uuid: some deterministic value
}),
).Run()
}
```

### Override
#### UUID V7

##### Usage

This module provides a [UuidV7Generator](https://github.com/ankorstore/yokai/blob/main/generate/uuidv7/generator.go), made available into the Fx container.

```go
package main

import (
"fmt"

"github.com/ankorstore/yokai/generate/uuidv7"
"github.com/ankorstore/yokai/fxgenerate"
"go.uber.org/fx"
)

func main() {
fx.New(
fxgenerate.FxGenerateModule, // load the module
fx.Invoke(func(generator uuidv7.UuidV7Generator) {
uuid, _ := generator.Generate() // invoke the uuid v7 generator
fmt.Printf("uuid: %s", uuid.String()) // uuid: 018fdd68-1b41-7eb0-afad-57f45297c7c1
}),
).Run()
}
```

##### Testing

This module provides the possibility to make your [UuidV7Generator](https://github.com/ankorstore/yokai/blob/main/generate/uuidv7/generator.go) generate deterministic values, for testing purposes.

You need to:

By default, the `uuid.UuidGenerator` is created by the [DefaultUuidGeneratorFactory](https://github.com/ankorstore/yokai/blob/main/generate/uuid/factory.go).
- first provide into the Fx container the deterministic value to be used for generation, annotated with `name:"generate-test-uuid-v7-value"`
- then decorate into the Fx container the `UuidV7GeneratorFactory` with the provided [TestUuidGeneratorV7Factory](fxgeneratetest/uuidv7/factory.go)

```go
package main

import (
"fmt"

"github.com/ankorstore/yokai/fxgenerate"
fxtestuuidv7 "github.com/ankorstore/yokai/fxgenerate/fxgeneratetest/uuidv7"
"github.com/ankorstore/yokai/generate/uuidv7"
"go.uber.org/fx"
)

func main() {
fx.New(
fxgenerate.FxGenerateModule, // load the module
fx.Provide( // provide and annotate the deterministic value
fx.Annotate(
func() string {
return "018fdd68-1b41-7eb0-afad-57f45297c7c1"
},
fx.ResultTags(`name:"generate-test-uuid-v7-value"`),
),
),
fx.Decorate(fxtestuuidv7.NewFxTestUuidV7GeneratorFactory), // override the module with the TestUuidGeneratorFactory
fx.Invoke(func(generator uuidv7.UuidV7Generator) { // invoke the generator
uuid, _ := generator.Generate()
fmt.Printf("uuid: %s", uuid.String()) // uuid: 018fdd68-1b41-7eb0-afad-57f45297c7c1
}),
).Run()
}
```

### Override

If needed, you can provide your own factory and override the module:
If needed, you can provide your own factories and override the module:

```go
package main
Expand All @@ -135,7 +205,7 @@ func main() {
fx.New(
fxgenerate.FxGenerateModule, // load the module
fx.Decorate(testuuid.NewTestStaticUuidGeneratorFactory), // override the module with a custom factory
fx.Invoke(func(generator *uuid.UuidGenerator) { // invoke the custom generator
fx.Invoke(func(generator uuid.UuidGenerator) { // invoke the custom generator
fmt.Printf("uuid: %s", generator.Generate()) // uuid: static
}),
).Run()
Expand Down
35 changes: 35 additions & 0 deletions fxgenerate/fxgeneratetest/uuidv7/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package uuidv7

import (
uuidv7test "github.com/ankorstore/yokai/generate/generatetest/uuidv7"
"github.com/ankorstore/yokai/generate/uuidv7"
"go.uber.org/fx"
)

// FxTestUuidV7GeneratorFactoryParam is used to retrieve the provided generate-test-uuid-V7-value from Fx.
type FxTestUuidV7GeneratorFactoryParam struct {
fx.In
Value string `name:"generate-test-uuid-v7-value"`
}

// TestUuidGeneratorV7Factory is a [uuidv7.Ui] implementation.
type TestUuidGeneratorV7Factory struct {
value string
}

// NewFxTestUuidV7GeneratorFactory returns a new [TestUuidGeneratorV7Factory], implementing [uuidv7.UuidV7GeneratorFactory].
func NewFxTestUuidV7GeneratorFactory(p FxTestUuidV7GeneratorFactoryParam) uuidv7.UuidV7GeneratorFactory {
return &TestUuidGeneratorV7Factory{
value: p.Value,
}
}

// Create returns a new [uuidv7.UuidV7Generator].
func (f *TestUuidGeneratorV7Factory) Create() uuidv7.UuidV7Generator {
generator, err := uuidv7test.NewTestUuidV7Generator(f.value)
if err != nil {
return nil
}

Check warning on line 32 in fxgenerate/fxgeneratetest/uuidv7/factory.go

View check run for this annotation

Codecov / codecov/patch

fxgenerate/fxgeneratetest/uuidv7/factory.go#L31-L32

Added lines #L31 - L32 were not covered by tests

return generator
}
40 changes: 40 additions & 0 deletions fxgenerate/fxgeneratetest/uuidv7/factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package uuidv7_test

import (
"testing"

"github.com/ankorstore/yokai/fxgenerate"
fxgeneratetestuuidv7 "github.com/ankorstore/yokai/fxgenerate/fxgeneratetest/uuidv7"
testuuidv7 "github.com/ankorstore/yokai/fxgenerate/testdata/uuidv7"
"github.com/ankorstore/yokai/generate/uuidv7"
"github.com/stretchr/testify/assert"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"
)

func TestTestUuidV7Generator(t *testing.T) {
t.Parallel()

var generator uuidv7.UuidV7Generator

fxtest.New(
t,
fx.NopLogger,
fxgenerate.FxGenerateModule,
fx.Provide(
fx.Annotate(
func() string {
return testuuidv7.TestUUIDV7
},
fx.ResultTags(`name:"generate-test-uuid-v7-value"`),
),
),
fx.Decorate(fxgeneratetestuuidv7.NewFxTestUuidV7GeneratorFactory),
fx.Populate(&generator),
).RequireStart().RequireStop()

value, err := generator.Generate()
assert.NoError(t, err)

assert.Equal(t, testuuidv7.TestUUIDV7, value.String())
}
4 changes: 2 additions & 2 deletions fxgenerate/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ module github.com/ankorstore/yokai/fxgenerate
go 1.20

require (
github.com/ankorstore/yokai/generate v1.1.0
github.com/ankorstore/yokai/generate v1.2.0
github.com/google/uuid v1.6.0
github.com/stretchr/testify v1.9.0
go.uber.org/fx v1.21.0
go.uber.org/fx v1.22.0
)

require (
Expand Down
16 changes: 5 additions & 11 deletions fxgenerate/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/ankorstore/yokai/generate v1.1.0 h1:tu3S+uEYh+2qNo8Rf/WxWneDjh49YgDPzSnJfF8JkXA=
github.com/ankorstore/yokai/generate v1.1.0/go.mod h1:gqS/i20wnvCOhcXydYdiGcASzBaeuW7GK6YYg/kkuY4=
github.com/ankorstore/yokai/generate v1.2.0 h1:37siukjPGSS2kRnCnPhiuiF373+0tgwp0teXHnMsBhA=
github.com/ankorstore/yokai/generate v1.2.0/go.mod h1:gqS/i20wnvCOhcXydYdiGcASzBaeuW7GK6YYg/kkuY4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
Expand All @@ -10,19 +10,13 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc=
go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.21.0 h1:qqD6k7PyFHONffW5speYx403ywanuASqU4Rqdpc22XY=
go.uber.org/fx v1.21.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM=
go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
Expand Down
26 changes: 23 additions & 3 deletions fxgenerate/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fxgenerate

import (
"github.com/ankorstore/yokai/generate/uuid"
"github.com/ankorstore/yokai/generate/uuidv7"
"go.uber.org/fx"
)

Expand All @@ -14,8 +15,16 @@ const ModuleName = "generate"
var FxGenerateModule = fx.Module(
ModuleName,
fx.Provide(
uuid.NewDefaultUuidGeneratorFactory,
fx.Annotate(
uuid.NewDefaultUuidGeneratorFactory,
fx.As(new(uuid.UuidGeneratorFactory)),
),
fx.Annotate(
uuidv7.NewDefaultUuidV7GeneratorFactory,
fx.As(new(uuidv7.UuidV7GeneratorFactory)),
),
NewFxUuidGenerator,
NewFxUuidV7Generator,
),
)

Expand All @@ -26,6 +35,17 @@ type FxUuidGeneratorParam struct {
}

// NewFxUuidGenerator returns a [uuid.UuidGenerator].
func NewFxUuidGenerator(p FxUuidGeneratorParam) (uuid.UuidGenerator, error) {
return p.Factory.Create(), nil
func NewFxUuidGenerator(p FxUuidGeneratorParam) uuid.UuidGenerator {
return p.Factory.Create()
}

// FxUuidV7GeneratorParam allows injection of the required dependencies in [NewFxUuidGenerator].
type FxUuidV7GeneratorParam struct {
fx.In
Factory uuidv7.UuidV7GeneratorFactory
}

// NewFxUuidV7Generator returns a [uuidv7.UuidV7Generator].
func NewFxUuidV7Generator(p FxUuidV7GeneratorParam) uuidv7.UuidV7Generator {
return p.Factory.Create()
}
53 changes: 53 additions & 0 deletions fxgenerate/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (

"github.com/ankorstore/yokai/fxgenerate"
testuuid "github.com/ankorstore/yokai/fxgenerate/testdata/uuid"
testuuidv7 "github.com/ankorstore/yokai/fxgenerate/testdata/uuidv7"
"github.com/ankorstore/yokai/generate/uuid"
"github.com/ankorstore/yokai/generate/uuidv7"
googleuuid "github.com/google/uuid"
"github.com/stretchr/testify/assert"
"go.uber.org/fx"
Expand Down Expand Up @@ -41,6 +43,38 @@ func TestModuleUuidGenerator(t *testing.T) {
assert.Equal(t, value2, parsedValue2.String())
}

func TestModuleUuidV7Generator(t *testing.T) {
t.Parallel()

var generator uuidv7.UuidV7Generator

fxtest.New(
t,
fx.NopLogger,
fxgenerate.FxGenerateModule,
fx.Populate(&generator),
).RequireStart().RequireStop()

value1, err := generator.Generate()
assert.NoError(t, err)

value2, err := generator.Generate()
assert.NoError(t, err)

assert.NotEqual(t, value1, value2)

parsedValue1, err := googleuuid.Parse(value1.String())
assert.NoError(t, err)

parsedValue2, err := googleuuid.Parse(value2.String())
assert.NoError(t, err)

assert.NotEqual(t, parsedValue1.String(), parsedValue2.String())

assert.Equal(t, value1.String(), parsedValue1.String())
assert.Equal(t, value2.String(), parsedValue2.String())
}

func TestModuleUuidGeneratorDecoration(t *testing.T) {
t.Parallel()

Expand All @@ -56,3 +90,22 @@ func TestModuleUuidGeneratorDecoration(t *testing.T) {

assert.Equal(t, "static", generator.Generate())
}

func TestModuleUuidV7GeneratorDecoration(t *testing.T) {
t.Parallel()

var generator uuidv7.UuidV7Generator

fxtest.New(
t,
fx.NopLogger,
fxgenerate.FxGenerateModule,
fx.Decorate(testuuidv7.NewTestStaticUuidV7GeneratorFactory),
fx.Populate(&generator),
).RequireStart().RequireStop()

value, err := generator.Generate()
assert.NoError(t, err)

assert.Equal(t, testuuidv7.TestUUIDV7, value.String())
}
Loading

0 comments on commit 7b85ce7

Please sign in to comment.