Skip to content

Commit 7b85ce7

Browse files
committed
feat(fxgenerate): Added UUID V7 generator
1 parent 35937a9 commit 7b85ce7

File tree

8 files changed

+265
-30
lines changed

8 files changed

+265
-30
lines changed

fxgenerate/README.md

+84-14
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
<!-- TOC -->
1212
* [Installation](#installation)
1313
* [Documentation](#documentation)
14-
* [Loading](#loading)
15-
* [Generators](#generators)
16-
* [UUID](#uuid)
17-
* [Usage](#usage)
18-
* [Testing](#testing)
19-
* [Override](#override)
14+
* [Loading](#loading)
15+
* [Generators](#generators)
16+
* [UUID V4](#uuid-v4)
17+
* [Usage](#usage)
18+
* [Testing](#testing)
19+
* [UUID V7](#uuid-v7)
20+
* [Usage](#usage-1)
21+
* [Testing](#testing-1)
22+
* [Override](#override)
2023
<!-- TOC -->
2124

2225
## Installation
@@ -46,7 +49,7 @@ func main() {
4649

4750
### Generators
4851

49-
#### UUID
52+
#### UUID V4
5053

5154
##### Usage
5255

@@ -65,8 +68,8 @@ import (
6568

6669
func main() {
6770
fx.New(
68-
fxgenerate.FxGenerateModule, // load the module
69-
fx.Invoke(func(generator *uuid.UuidGenerator) { // invoke the uuid generator
71+
fxgenerate.FxGenerateModule, // load the module
72+
fx.Invoke(func(generator uuid.UuidGenerator) { // invoke the uuid generator
7073
fmt.Printf("uuid: %s", generator.Generate()) // uuid: dcb5d8b3-4517-4957-a42c-604d11758561
7174
}),
7275
).Run()
@@ -106,18 +109,85 @@ func main() {
106109
),
107110
),
108111
fx.Decorate(fxtestuuid.NewFxTestUuidGeneratorFactory), // override the module with the TestUuidGeneratorFactory
109-
fx.Invoke(func(generator *uuid.UuidGenerator) { // invoke the generator
112+
fx.Invoke(func(generator uuid.UuidGenerator) { // invoke the generator
110113
fmt.Printf("uuid: %s", generator.Generate()) // uuid: some deterministic value
111114
}),
112115
).Run()
113116
}
114117
```
115118

116-
### Override
119+
#### UUID V7
120+
121+
##### Usage
122+
123+
This module provides a [UuidV7Generator](https://github.com/ankorstore/yokai/blob/main/generate/uuidv7/generator.go), made available into the Fx container.
124+
125+
```go
126+
package main
127+
128+
import (
129+
"fmt"
130+
131+
"github.com/ankorstore/yokai/generate/uuidv7"
132+
"github.com/ankorstore/yokai/fxgenerate"
133+
"go.uber.org/fx"
134+
)
135+
136+
func main() {
137+
fx.New(
138+
fxgenerate.FxGenerateModule, // load the module
139+
fx.Invoke(func(generator uuidv7.UuidV7Generator) {
140+
uuid, _ := generator.Generate() // invoke the uuid v7 generator
141+
fmt.Printf("uuid: %s", uuid.String()) // uuid: 018fdd68-1b41-7eb0-afad-57f45297c7c1
142+
}),
143+
).Run()
144+
}
145+
```
146+
147+
##### Testing
148+
149+
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.
150+
151+
You need to:
117152

118-
By default, the `uuid.UuidGenerator` is created by the [DefaultUuidGeneratorFactory](https://github.com/ankorstore/yokai/blob/main/generate/uuid/factory.go).
153+
- first provide into the Fx container the deterministic value to be used for generation, annotated with `name:"generate-test-uuid-v7-value"`
154+
- then decorate into the Fx container the `UuidV7GeneratorFactory` with the provided [TestUuidGeneratorV7Factory](fxgeneratetest/uuidv7/factory.go)
155+
156+
```go
157+
package main
158+
159+
import (
160+
"fmt"
161+
162+
"github.com/ankorstore/yokai/fxgenerate"
163+
fxtestuuidv7 "github.com/ankorstore/yokai/fxgenerate/fxgeneratetest/uuidv7"
164+
"github.com/ankorstore/yokai/generate/uuidv7"
165+
"go.uber.org/fx"
166+
)
167+
168+
func main() {
169+
fx.New(
170+
fxgenerate.FxGenerateModule, // load the module
171+
fx.Provide( // provide and annotate the deterministic value
172+
fx.Annotate(
173+
func() string {
174+
return "018fdd68-1b41-7eb0-afad-57f45297c7c1"
175+
},
176+
fx.ResultTags(`name:"generate-test-uuid-v7-value"`),
177+
),
178+
),
179+
fx.Decorate(fxtestuuidv7.NewFxTestUuidV7GeneratorFactory), // override the module with the TestUuidGeneratorFactory
180+
fx.Invoke(func(generator uuidv7.UuidV7Generator) { // invoke the generator
181+
uuid, _ := generator.Generate()
182+
fmt.Printf("uuid: %s", uuid.String()) // uuid: 018fdd68-1b41-7eb0-afad-57f45297c7c1
183+
}),
184+
).Run()
185+
}
186+
```
187+
188+
### Override
119189

120-
If needed, you can provide your own factory and override the module:
190+
If needed, you can provide your own factories and override the module:
121191

122192
```go
123193
package main
@@ -135,7 +205,7 @@ func main() {
135205
fx.New(
136206
fxgenerate.FxGenerateModule, // load the module
137207
fx.Decorate(testuuid.NewTestStaticUuidGeneratorFactory), // override the module with a custom factory
138-
fx.Invoke(func(generator *uuid.UuidGenerator) { // invoke the custom generator
208+
fx.Invoke(func(generator uuid.UuidGenerator) { // invoke the custom generator
139209
fmt.Printf("uuid: %s", generator.Generate()) // uuid: static
140210
}),
141211
).Run()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package uuidv7
2+
3+
import (
4+
uuidv7test "github.com/ankorstore/yokai/generate/generatetest/uuidv7"
5+
"github.com/ankorstore/yokai/generate/uuidv7"
6+
"go.uber.org/fx"
7+
)
8+
9+
// FxTestUuidV7GeneratorFactoryParam is used to retrieve the provided generate-test-uuid-V7-value from Fx.
10+
type FxTestUuidV7GeneratorFactoryParam struct {
11+
fx.In
12+
Value string `name:"generate-test-uuid-v7-value"`
13+
}
14+
15+
// TestUuidGeneratorV7Factory is a [uuidv7.Ui] implementation.
16+
type TestUuidGeneratorV7Factory struct {
17+
value string
18+
}
19+
20+
// NewFxTestUuidV7GeneratorFactory returns a new [TestUuidGeneratorV7Factory], implementing [uuidv7.UuidV7GeneratorFactory].
21+
func NewFxTestUuidV7GeneratorFactory(p FxTestUuidV7GeneratorFactoryParam) uuidv7.UuidV7GeneratorFactory {
22+
return &TestUuidGeneratorV7Factory{
23+
value: p.Value,
24+
}
25+
}
26+
27+
// Create returns a new [uuidv7.UuidV7Generator].
28+
func (f *TestUuidGeneratorV7Factory) Create() uuidv7.UuidV7Generator {
29+
generator, err := uuidv7test.NewTestUuidV7Generator(f.value)
30+
if err != nil {
31+
return nil
32+
}
33+
34+
return generator
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package uuidv7_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/ankorstore/yokai/fxgenerate"
7+
fxgeneratetestuuidv7 "github.com/ankorstore/yokai/fxgenerate/fxgeneratetest/uuidv7"
8+
testuuidv7 "github.com/ankorstore/yokai/fxgenerate/testdata/uuidv7"
9+
"github.com/ankorstore/yokai/generate/uuidv7"
10+
"github.com/stretchr/testify/assert"
11+
"go.uber.org/fx"
12+
"go.uber.org/fx/fxtest"
13+
)
14+
15+
func TestTestUuidV7Generator(t *testing.T) {
16+
t.Parallel()
17+
18+
var generator uuidv7.UuidV7Generator
19+
20+
fxtest.New(
21+
t,
22+
fx.NopLogger,
23+
fxgenerate.FxGenerateModule,
24+
fx.Provide(
25+
fx.Annotate(
26+
func() string {
27+
return testuuidv7.TestUUIDV7
28+
},
29+
fx.ResultTags(`name:"generate-test-uuid-v7-value"`),
30+
),
31+
),
32+
fx.Decorate(fxgeneratetestuuidv7.NewFxTestUuidV7GeneratorFactory),
33+
fx.Populate(&generator),
34+
).RequireStart().RequireStop()
35+
36+
value, err := generator.Generate()
37+
assert.NoError(t, err)
38+
39+
assert.Equal(t, testuuidv7.TestUUIDV7, value.String())
40+
}

fxgenerate/go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ module github.com/ankorstore/yokai/fxgenerate
33
go 1.20
44

55
require (
6-
github.com/ankorstore/yokai/generate v1.1.0
6+
github.com/ankorstore/yokai/generate v1.2.0
77
github.com/google/uuid v1.6.0
88
github.com/stretchr/testify v1.9.0
9-
go.uber.org/fx v1.21.0
9+
go.uber.org/fx v1.22.0
1010
)
1111

1212
require (

fxgenerate/go.sum

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
github.com/ankorstore/yokai/generate v1.1.0 h1:tu3S+uEYh+2qNo8Rf/WxWneDjh49YgDPzSnJfF8JkXA=
2-
github.com/ankorstore/yokai/generate v1.1.0/go.mod h1:gqS/i20wnvCOhcXydYdiGcASzBaeuW7GK6YYg/kkuY4=
1+
github.com/ankorstore/yokai/generate v1.2.0 h1:37siukjPGSS2kRnCnPhiuiF373+0tgwp0teXHnMsBhA=
2+
github.com/ankorstore/yokai/generate v1.2.0/go.mod h1:gqS/i20wnvCOhcXydYdiGcASzBaeuW7GK6YYg/kkuY4=
33
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
55
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -10,19 +10,13 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
1010
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
1111
go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc=
1212
go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
13-
go.uber.org/fx v1.21.0 h1:qqD6k7PyFHONffW5speYx403ywanuASqU4Rqdpc22XY=
14-
go.uber.org/fx v1.21.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48=
15-
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
16-
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
17-
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
13+
go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM=
14+
go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48=
15+
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
1816
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
1917
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
20-
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
21-
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
2218
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
2319
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
24-
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
25-
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2620
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
2721
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
2822
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

fxgenerate/module.go

+23-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package fxgenerate
22

33
import (
44
"github.com/ankorstore/yokai/generate/uuid"
5+
"github.com/ankorstore/yokai/generate/uuidv7"
56
"go.uber.org/fx"
67
)
78

@@ -14,8 +15,16 @@ const ModuleName = "generate"
1415
var FxGenerateModule = fx.Module(
1516
ModuleName,
1617
fx.Provide(
17-
uuid.NewDefaultUuidGeneratorFactory,
18+
fx.Annotate(
19+
uuid.NewDefaultUuidGeneratorFactory,
20+
fx.As(new(uuid.UuidGeneratorFactory)),
21+
),
22+
fx.Annotate(
23+
uuidv7.NewDefaultUuidV7GeneratorFactory,
24+
fx.As(new(uuidv7.UuidV7GeneratorFactory)),
25+
),
1826
NewFxUuidGenerator,
27+
NewFxUuidV7Generator,
1928
),
2029
)
2130

@@ -26,6 +35,17 @@ type FxUuidGeneratorParam struct {
2635
}
2736

2837
// NewFxUuidGenerator returns a [uuid.UuidGenerator].
29-
func NewFxUuidGenerator(p FxUuidGeneratorParam) (uuid.UuidGenerator, error) {
30-
return p.Factory.Create(), nil
38+
func NewFxUuidGenerator(p FxUuidGeneratorParam) uuid.UuidGenerator {
39+
return p.Factory.Create()
40+
}
41+
42+
// FxUuidV7GeneratorParam allows injection of the required dependencies in [NewFxUuidGenerator].
43+
type FxUuidV7GeneratorParam struct {
44+
fx.In
45+
Factory uuidv7.UuidV7GeneratorFactory
46+
}
47+
48+
// NewFxUuidV7Generator returns a [uuidv7.UuidV7Generator].
49+
func NewFxUuidV7Generator(p FxUuidV7GeneratorParam) uuidv7.UuidV7Generator {
50+
return p.Factory.Create()
3151
}

fxgenerate/module_test.go

+53
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55

66
"github.com/ankorstore/yokai/fxgenerate"
77
testuuid "github.com/ankorstore/yokai/fxgenerate/testdata/uuid"
8+
testuuidv7 "github.com/ankorstore/yokai/fxgenerate/testdata/uuidv7"
89
"github.com/ankorstore/yokai/generate/uuid"
10+
"github.com/ankorstore/yokai/generate/uuidv7"
911
googleuuid "github.com/google/uuid"
1012
"github.com/stretchr/testify/assert"
1113
"go.uber.org/fx"
@@ -41,6 +43,38 @@ func TestModuleUuidGenerator(t *testing.T) {
4143
assert.Equal(t, value2, parsedValue2.String())
4244
}
4345

46+
func TestModuleUuidV7Generator(t *testing.T) {
47+
t.Parallel()
48+
49+
var generator uuidv7.UuidV7Generator
50+
51+
fxtest.New(
52+
t,
53+
fx.NopLogger,
54+
fxgenerate.FxGenerateModule,
55+
fx.Populate(&generator),
56+
).RequireStart().RequireStop()
57+
58+
value1, err := generator.Generate()
59+
assert.NoError(t, err)
60+
61+
value2, err := generator.Generate()
62+
assert.NoError(t, err)
63+
64+
assert.NotEqual(t, value1, value2)
65+
66+
parsedValue1, err := googleuuid.Parse(value1.String())
67+
assert.NoError(t, err)
68+
69+
parsedValue2, err := googleuuid.Parse(value2.String())
70+
assert.NoError(t, err)
71+
72+
assert.NotEqual(t, parsedValue1.String(), parsedValue2.String())
73+
74+
assert.Equal(t, value1.String(), parsedValue1.String())
75+
assert.Equal(t, value2.String(), parsedValue2.String())
76+
}
77+
4478
func TestModuleUuidGeneratorDecoration(t *testing.T) {
4579
t.Parallel()
4680

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

5791
assert.Equal(t, "static", generator.Generate())
5892
}
93+
94+
func TestModuleUuidV7GeneratorDecoration(t *testing.T) {
95+
t.Parallel()
96+
97+
var generator uuidv7.UuidV7Generator
98+
99+
fxtest.New(
100+
t,
101+
fx.NopLogger,
102+
fxgenerate.FxGenerateModule,
103+
fx.Decorate(testuuidv7.NewTestStaticUuidV7GeneratorFactory),
104+
fx.Populate(&generator),
105+
).RequireStart().RequireStop()
106+
107+
value, err := generator.Generate()
108+
assert.NoError(t, err)
109+
110+
assert.Equal(t, testuuidv7.TestUUIDV7, value.String())
111+
}

0 commit comments

Comments
 (0)