Skip to content

Commit

Permalink
feat(fxgenerate): Added UUIDv6 generation (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
ekkinox authored Nov 18, 2024
1 parent 7aac8f1 commit ddbe283
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 8 deletions.
2 changes: 1 addition & 1 deletion fxgenerate/.golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ linters:
- importas
- ineffassign
- interfacebloat
- logrlint
- loggercheck
- maintidx
- makezero
- misspell
Expand Down
80 changes: 76 additions & 4 deletions fxgenerate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
* [UUID V4](#uuid-v4)
* [Usage](#usage)
* [Testing](#testing)
* [UUID V7](#uuid-v7)
* [UUID V6](#uuid-v6)
* [Usage](#usage-1)
* [Testing](#testing-1)
* [UUID V7](#uuid-v7)
* [Usage](#usage-2)
* [Testing](#testing-2)
* [Override](#override)
<!-- TOC -->

Expand Down Expand Up @@ -108,14 +111,83 @@ func main() {
fx.ResultTags(`name:"generate-test-uuid-value"`),
),
),
fx.Decorate(fxtestuuid.NewFxTestUuidGeneratorFactory), // override the module with the TestUuidGeneratorFactory
fx.Decorate(fxtestuuid.NewFxTestUuidGeneratorFactory), // override the module with the test factory
fx.Invoke(func(generator uuid.UuidGenerator) { // invoke the generator
fmt.Printf("uuid: %s", generator.Generate()) // uuid: some deterministic value
}),
).Run()
}
```

#### UUID V6

##### Usage

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

```go
package main

import (
"fmt"

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

func main() {
fx.New(
fxgenerate.FxGenerateModule, // load the module
fx.Invoke(func(generator uuidv6.UuidV7Generator) {
uuid, _ := generator.Generate() // invoke the uuid v6 generator
fmt.Printf("uuid: %s", uuid.String()) // uuid: 1efa5a47-e5d0-6667-9d00-49bf4f758c68
}),
).Run()
}
```

##### Testing

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

You need to:

- first provide into the Fx container the deterministic value to be used for generation, annotated with `name:"generate-test-uuid-v6-value"`
- then decorate into the Fx container the `UuidV6GeneratorFactory` with the provided [TestUuidGeneratorV6Factory](fxgeneratetest/uuidv6/factory.go)

```go
package main

import (
"fmt"

"github.com/ankorstore/yokai/fxgenerate"
fxtestuuidv6 "github.com/ankorstore/yokai/fxgenerate/fxgeneratetest/uuidv6"
"github.com/ankorstore/yokai/generate/uuidv6"
"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 "1efa5a47-e5d0-6663-99da-f6e8045dd166"
},
fx.ResultTags(`name:"generate-test-uuid-v6-value"`),
),
),
fx.Decorate(fxtestuuidv6.NewFxTestUuidV6GeneratorFactory), // override the module with the test factory
fx.Invoke(func(generator uuidv6.UuidV6Generator) { // invoke the generator
uuid, _ := generator.Generate()
fmt.Printf("uuid: %s", uuid.String()) // uuid: 1efa5a47-e5d0-6663-99da-f6e8045dd166
}),
).Run()
}
```

#### UUID V7

##### Usage
Expand Down Expand Up @@ -176,8 +248,8 @@ func main() {
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
fx.Decorate(fxtestuuidv7.NewFxTestUuidV7GeneratorFactory), // override the module with the test factory
fx.Invoke(func(generator uuidv7.UuidV7Generator) { // invoke the generator
uuid, _ := generator.Generate()
fmt.Printf("uuid: %s", uuid.String()) // uuid: 018fdd68-1b41-7eb0-afad-57f45297c7c1
}),
Expand Down
35 changes: 35 additions & 0 deletions fxgenerate/fxgeneratetest/uuidv6/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package uuidv6

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

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

// TestUuidGeneratorV6Factory is a [uuidv6.Ui] implementation.
type TestUuidGeneratorV6Factory struct {
value string
}

// NewFxTestUuidV6GeneratorFactory returns a new [TestUuidGeneratorV6Factory], implementing [uuidv6.UuidV6GeneratorFactory].
func NewFxTestUuidV6GeneratorFactory(p FxTestUuidV6GeneratorFactoryParam) uuidv6.UuidV6GeneratorFactory {
return &TestUuidGeneratorV6Factory{
value: p.Value,
}
}

// Create returns a new [uuidv6.UuidV6Generator].
func (f *TestUuidGeneratorV6Factory) Create() uuidv6.UuidV6Generator {
generator, err := uuidv6test.NewTestUuidV6Generator(f.value)
if err != nil {
return nil
}

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

import (
"testing"

"github.com/ankorstore/yokai/fxgenerate"
fxgeneratetestuuidv6 "github.com/ankorstore/yokai/fxgenerate/fxgeneratetest/uuidv6"
testuuidv6 "github.com/ankorstore/yokai/fxgenerate/testdata/uuidv6"
"github.com/ankorstore/yokai/generate/uuidv6"
"github.com/stretchr/testify/assert"
"go.uber.org/fx"
"go.uber.org/fx/fxtest"
)

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

var generator uuidv6.UuidV6Generator

fxtest.New(
t,
fx.NopLogger,
fxgenerate.FxGenerateModule,
fx.Provide(
fx.Annotate(
func() string {
return testuuidv6.TestUUIDV6
},
fx.ResultTags(`name:"generate-test-uuid-v6-value"`),
),
),
fx.Decorate(fxgeneratetestuuidv6.NewFxTestUuidV6GeneratorFactory),
fx.Populate(&generator),
).RequireStart().RequireStop()

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

assert.Equal(t, testuuidv6.TestUUIDV6, value.String())
}

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

var generator uuidv6.UuidV6Generator

fxtest.New(
t,
fx.NopLogger,
fxgenerate.FxGenerateModule,
fx.Provide(
fx.Annotate(
func() string {
return "invalid"
},
fx.ResultTags(`name:"generate-test-uuid-v6-value"`),
),
),
fx.Decorate(fxgeneratetestuuidv6.NewFxTestUuidV6GeneratorFactory),
fx.Populate(&generator),
).RequireStart().RequireStop()

assert.Nil(t, generator)
}
2 changes: 1 addition & 1 deletion fxgenerate/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/ankorstore/yokai/fxgenerate
go 1.20

require (
github.com/ankorstore/yokai/generate v1.2.0
github.com/ankorstore/yokai/generate v1.3.0
github.com/google/uuid v1.6.0
github.com/stretchr/testify v1.9.0
go.uber.org/fx v1.22.0
Expand Down
4 changes: 2 additions & 2 deletions fxgenerate/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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/ankorstore/yokai/generate v1.3.0 h1:Fgu3vjjA9pThOqG9GPkWIB30LufSVCLPzGUel5zcPcY=
github.com/ankorstore/yokai/generate v1.3.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 Down
17 changes: 17 additions & 0 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/uuidv6"
"github.com/ankorstore/yokai/generate/uuidv7"
"go.uber.org/fx"
)
Expand All @@ -19,11 +20,16 @@ var FxGenerateModule = fx.Module(
uuid.NewDefaultUuidGeneratorFactory,
fx.As(new(uuid.UuidGeneratorFactory)),
),
fx.Annotate(
uuidv6.NewDefaultUuidV6GeneratorFactory,
fx.As(new(uuidv6.UuidV6GeneratorFactory)),
),
fx.Annotate(
uuidv7.NewDefaultUuidV7GeneratorFactory,
fx.As(new(uuidv7.UuidV7GeneratorFactory)),
),
NewFxUuidGenerator,
NewFxUuidV6Generator,
NewFxUuidV7Generator,
),
)
Expand All @@ -39,6 +45,17 @@ func NewFxUuidGenerator(p FxUuidGeneratorParam) uuid.UuidGenerator {
return p.Factory.Create()
}

// FxUuidV6GeneratorParam allows injection of the required dependencies in [NewFxUuidV6Generator].
type FxUuidV6GeneratorParam struct {
fx.In
Factory uuidv6.UuidV6GeneratorFactory
}

// NewFxUuidV6Generator returns a [uuidv6.UuidV6Generator].
func NewFxUuidV6Generator(p FxUuidV6GeneratorParam) uuidv6.UuidV6Generator {
return p.Factory.Create()
}

// FxUuidV7GeneratorParam allows injection of the required dependencies in [NewFxUuidV7Generator].
type FxUuidV7GeneratorParam struct {
fx.In
Expand Down
54 changes: 54 additions & 0 deletions fxgenerate/module_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
//nolint:dupl
package fxgenerate_test

import (
"testing"

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

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

var generator uuidv6.UuidV6Generator

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 TestModuleUuidV7Generator(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -91,6 +126,25 @@ func TestModuleUuidGeneratorDecoration(t *testing.T) {
assert.Equal(t, "static", generator.Generate())
}

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

var generator uuidv6.UuidV6Generator

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

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

assert.Equal(t, testuuidv6.TestUUIDV6, value.String())
}

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

Expand Down
21 changes: 21 additions & 0 deletions fxgenerate/testdata/uuidv6/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package uuidv6

import (
uuidtest "github.com/ankorstore/yokai/generate/generatetest/uuidv6"
"github.com/ankorstore/yokai/generate/uuidv6"
)

const TestUUIDV6 = "1efa5a47-e5d2-6d70-8953-776e81422ff3"

type TestStaticUuidV6GeneratorFactory struct{}

func NewTestStaticUuidV6GeneratorFactory() uuidv6.UuidV6GeneratorFactory {
return &TestStaticUuidV6GeneratorFactory{}
}

func (f *TestStaticUuidV6GeneratorFactory) Create() uuidv6.UuidV6Generator {
//nolint:errcheck
generator, _ := uuidtest.NewTestUuidV6Generator(TestUUIDV6)

return generator
}

0 comments on commit ddbe283

Please sign in to comment.