Skip to content

Instantly share code, notes, and snippets.

@avrebarra
Last active December 2, 2021 03:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avrebarra/5a6acf7ff31df7acc548d16e029ac97c to your computer and use it in GitHub Desktop.
Save avrebarra/5a6acf7ff31df7acc548d16e029ac97c to your computer and use it in GitHub Desktop.
avrebarra.github.io/structuring-go-module
package numstore
import (
"context"
"fmt"
)
var (
ErrNotImplemented = fmt.Errorf("feature not implemented")
ErrNotFound = fmt.Errorf("not found")
)
type NumberStore interface {
Store(ctx context.Context, in StoreInput) (err error)
Retrieve(ctx context.Context) (out RetrieveOutput, err error)
}
type StoreInput struct {
Number Number
}
type RetrieveOutput struct {
Number Number
}
// ***
// datatypes
type Number struct {
MainNum int
DecimalNum int
}
// ***
// general utilities
func CombineNumber(in1 Number, in2 Number) (out Number) {
out = Number{
MainNum: in1.MainNum * in2.MainNum,
DecimalNum: in1.DecimalNum * in1.DecimalNum,
}
return
}
package numstore
import (
"context"
"fmt"
"github.com/avrebarra/valeed"
)
type ConfigMemory struct {
StorageArray []Number `validate:"required"`
}
type Memory struct {
config ConfigMemory
}
func NewMemory(cfg ConfigMemory) (NumberStore, error) {
if err := valeed.Validate(cfg); err != nil {
return nil, err
}
e := &Memory{config: cfg}
return e, nil
}
func (e *Memory) Store(ctx context.Context, in StoreInput) (err error) {
// perform process
e.config.StorageArray = append(e.config.StorageArray, in.Number)
return
}
func (e *Memory) Retrieve(ctx context.Context) (out RetrieveOutput, err error) {
// perform process
// ** validate count
count := len(e.config.StorageArray)
if count <= 0 {
err = fmt.Errorf("%w: empty storage", ErrNotFound)
return
}
// ** fetch
resid := count - 1
num := e.config.StorageArray[resid]
// build output
out = RetrieveOutput{
Number: num,
}
return
}
package numstore_test
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/my/module/numstore"
)
func TestNewMemory(t *testing.T) {
t.Run("ok", func(t *testing.T) {
// arrange
storagearray := []numstore.Number{}
// act
x, err := numstore.NewMemory(numstore.ConfigMemory{
StorageArray: storagearray,
})
// assert
assert.NotEmpty(t, x)
assert.NoError(t, err)
})
t.Run("err bad deps", func(t *testing.T) {
// arrange
// act
x, err := numstore.NewMemory(numstore.ConfigMemory{})
// assert
assert.Empty(t, x)
assert.Error(t, err)
})
}
func TestMemory_Store(t *testing.T) {
t.Run("ok", func(t *testing.T) {
// arrange
x, err := numstore.NewMemory(numstore.ConfigMemory{StorageArray: []numstore.Number{}})
require.NoError(t, err)
// act
err = x.Store(context.Background(), numstore.StoreInput{
Number: numstore.Number{
MainNum: 6,
DecimalNum: 76,
},
})
// assert
assert.NoError(t, err)
})
}
func TestMemory_Retrieve(t *testing.T) {
t.Run("ok", func(t *testing.T) {
// arrange
x, err := numstore.NewMemory(numstore.ConfigMemory{StorageArray: []numstore.Number{}})
require.NoError(t, err)
err = x.Store(context.Background(), numstore.StoreInput{
Number: numstore.Number{MainNum: 6, DecimalNum: 76},
})
require.NoError(t, err)
// act
out, err := x.Retrieve(context.Background())
// assert
assert.NoError(t, err)
assert.NotEmpty(t, out)
assert.Equal(t, 6, out.Number.MainNum)
})
}
package numstore
import (
"context"
"fmt"
"github.com/avrebarra/valeed"
"go.mongodb.org/mongo-driver/mongo"
)
const (
MongoCollectionName = "numstore"
)
type ConfigMongo struct {
MongoClient mongo.Client `validate:"required"`
}
type Mongo struct {
config ConfigMongo
}
func NewMongo(cfg ConfigMongo) (NumberStore, error) {
if err := valeed.Validate(cfg); err != nil {
return nil, err
}
e := &Mongo{config: cfg}
return e, nil
}
func (e *Mongo) Store(ctx context.Context, in StoreInput) (err error) {
err = fmt.Errorf("%w: code yet unfinished", ErrNotImplemented)
return
}
func (e *Mongo) Retrieve(ctx context.Context) (out RetrieveOutput, err error) {
err = fmt.Errorf("%w: code yet unfinished", ErrNotImplemented)
return
}
// ***
type MongoNumber struct {
MainNum int `json:"main_num" bson:"main_num"`
DecimalNum int `json:"decimal_num" bson:"decimal_num"`
}
package numstore_test
import (
"testing"
)
func TestNewMongo(t *testing.T) {
t.SkipNow()
}
func TestMongo_Store(t *testing.T) {
t.SkipNow()
}
func TestMongo_Retrieve(t *testing.T) {
t.SkipNow()
}
package numstore
import (
"context"
"fmt"
"strings"
"github.com/avrebarra/valeed"
"github.com/go-redis/redis/v8"
)
type ConfigRedis struct {
RedisClient redis.UniversalClient `validate:"required"`
KeyPrefix string `validate:"required,endswith=/"`
}
type Redis struct {
config ConfigRedis
}
func NewRedis(cfg ConfigRedis) (NumberStore, error) {
if err := valeed.Validate(cfg); err != nil {
return nil, err
}
e := &Redis{config: cfg}
return e, nil
}
func (e *Redis) Store(ctx context.Context, in StoreInput) (err error) {
err = fmt.Errorf("%w: code yet unfinished", ErrNotImplemented)
return
}
func (e *Redis) Retrieve(ctx context.Context) (out RetrieveOutput, err error) {
err = fmt.Errorf("%w: code yet unfinished", ErrNotImplemented)
return
}
// ***
func (e *Redis) getkey(ctx context.Context, restype, resid string) (out string) {
return fmt.Sprintf("%s:%s/%s", e.config.KeyPrefix, strings.ToLower(restype), resid)
}
package numstore_test
import (
"testing"
)
func TestNewRedis(t *testing.T) {
t.SkipNow()
}
func TestRedis_Store(t *testing.T) {
t.SkipNow()
}
func TestRedis_Retrieve(t *testing.T) {
t.SkipNow()
}
package numstore_test
import (
"testing"
)
func TestCombineNumber(t *testing.T) {
t.SkipNow()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment