Skip to content

Commit

Permalink
add functional option pattern; testing first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
deemount committed Mar 20, 2024
1 parent c81b392 commit ec6aff8
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 113 deletions.
94 changes: 50 additions & 44 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,81 @@ package gobpmn_builder

import (
"fmt"
"log"
"os"
"reflect"

gobpmn_count "github.com/deemount/gobpmnCounter"
"github.com/deemount/gobpmnModels/pkg/core"
)

var (
options Options
path string
)

type (

// Option ...
Option func(o Options) Options

// BuilderRepository ...
// BuilderRepository is the interface for the builder repository.
// The interface defines the methods for the builder repository.
// The methods are used to set the definitions, set the definitions by argument,
// set the defaults, convert the model to bpmn, convert the model to json,
// get the currently created filename, and build the model.
BuilderRepository interface {
Build() (Builder, error)
SetDefinitions()
SetDefinitionsByArg(r core.DefinitionsRepository)
Defaults(p interface{}, c *gobpmn_count.Quantities)
ToBPMN() error
ToBPMN() error // Sets the bpmn file
ToJSON() error // Sets the json file
GetCurrentlyCreatedFilename() string
Build() (Builder, error)
}

// Builder ...
// Builder is the main struct of the builder package and holds
// the options and the current file. The options are the parameters
// for the builder and the current file is the name of the current
// bpmn file in the particular directory.
Builder struct {
Options Options
Counter int // Counter is the number of created files
FilenamePrefix string // CurrentFile is the name of the current file
ModelType string // ModelType is the type of the model (can be human or technical)
FilePathBPMN string // FilePathBPMN is the path to the bpmn files
FilePathJSON string // FilePathJSON is the path to the json files
Def *core.Definitions // Def is the definition of the model
Repo core.DefinitionsRepository // Repo is the repository of the model
}
)

// New ...
func New(option ...Option) BuilderRepository {
//
for _, o := range option {
options = o(options)
}

// path to bpmn files
path = "files/bpmn"
files, err := os.ReadDir(path)
if err != nil {
log.Panic(err)
// New initializes the builder with the given options
// and returns the builder repository.
// The method sets the default values and applies the options
// to the builder.
func New(opts ...Option) BuilderRepository {
// Set the default values
bldr := &Builder{
Counter: 1,
FilenamePrefix: "diagram",
ModelType: "human",
FilePathBPMN: "files/bpmn",
FilePathJSON: "files/json",
Def: nil,
Repo: nil,
}

// set number and count up for each created file
if options.Counter == 0 {
options.Counter = len(files)
} else {
options.Counter += 1
// Apply the options to the builder
for _, opt := range opts {
opt(bldr)
}

// set default name for bpmn-file
options.CurrentFile = "diagram_" + fmt.Sprintf("%d", options.Counter)

return &Builder{Options: options}
return bldr
}

// SetDefinitions ...
func (bldr *Builder) SetDefinitions() {
bldr.Options.Repo = core.NewDefinitions()
bldr.Repo = core.NewDefinitions()
}

// SetDefinitionsByArg ...
func (bldr *Builder) SetDefinitionsByArg(r core.DefinitionsRepository) {
bldr.Options.Repo = r
bldr.Repo = r
}

// Defaults receives the definitions repository by the app in p argument
// and calls the main elements to set the maps, including process parameters
// n of process. The method contains the reflected process definition (p interface{})
// and calls it by the reflected method name.
// This method hides specific setters (SetProcess, SetCollaboration, SetDiagram).
// Note: This method hides specific setters (SetProcess, SetCollaboration, SetDiagram).
func (bldr *Builder) Defaults(p interface{}, c *gobpmn_count.Quantities) {

// el is the interface {} of a given definition
Expand Down Expand Up @@ -111,15 +110,22 @@ func (bldr *Builder) Defaults(p interface{}, c *gobpmn_count.Quantities) {
*/
}

// GetCurrentlyCreatedFilename ...
// GetCurrentlyCreatedFilename returns the current bpmn filename
// It is a helper method to get the current bpmn filename, which
// relies on the same instance
func (bldr Builder) GetCurrentlyCreatedFilename() string {
return bldr.Options.CurrentFile
return fmt.Sprintf("%s_%d", bldr.FilenamePrefix, bldr.Counter)
}

// Build...
// Build builds the bpmn and json files and returns the builder
// and an error if an error occurs during the process.
// The method calls the ToBPMN and ToJSON methods.
func (bldr Builder) Build() (Builder, error) {
if err := bldr.ToBPMN(); err != nil {
return Builder{}, err
}
if err := bldr.ToJSON(); err != nil {
return Builder{}, err
}
return bldr, nil
}
67 changes: 27 additions & 40 deletions builder_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package gobpmn_builder
package gobpmn_builder_test

import (
"encoding/xml"
"fmt"
"os"
"reflect"
"testing"

"github.com/stretchr/testify/mock"

"github.com/deemount/gobpmnModels/pkg/core"
)

func TestReflectCounter(t *testing.T) {
// TestReflectQuantities
func TestReflectQuantities(t *testing.T) {

type Quantities struct {
Process int
}

type A struct{ Process int }
a := A{Process: 1}
a := Quantities{Process: 1}

r := reflect.ValueOf(&a).Elem()
r1 := r.FieldByName("Process").Int()
Expand All @@ -22,38 +25,22 @@ func TestReflectCounter(t *testing.T) {

}

func TestToBPMN(t *testing.T) {
var err error
// create a new repository
repo := core.NewDefinitions()
repo.SetDefaultAttributes()
repo.SetID("definitions", "1234")
repo.SetMainElements(1)
proc := repo.GetProcess(0)
t.Logf("result of proc is %v", proc)
// marshal xml to byte slice
b, err := xml.MarshalIndent(&repo, " ", " ")
if err != nil {
t.Errorf("expected nil, got %v", err)
}
// path to temporary bpmn files
path := "temp"
// create .bpmn file
f, err := os.Create(path + "/test.bpmn")
if err != nil {
t.Errorf("expected nil, got %v", err)
}
defer f.Close()
// add xml header
w := []byte(fmt.Sprintf("%v", xml.Header+string(b)))
// write bytes to file
_, err = f.Write(w)
if err != nil {
t.Errorf("expected nil, got %v", err)
}
err = f.Sync()
if err != nil {
t.Errorf("expected nil, got %v", err)
}
type mockOptions struct {
mock.Mock
Counter int // Counter is the number of created files
CurrentFile string // CurrentFile is the name of the current file
ModelType string // ModelType is the type of the model (can be human or technical)
FilePathBPMN string // FilePathBPMN is the path to the bpmn files
FilePathJSON string // FilePathJSON is the path to the json files
Def *core.Definitions // Def is the definition of the model
Repo core.DefinitionsRepository // Repo is the repository of the model
}

type mockOption func(opt mockOptions) mockOptions

func TestSetOptions(t *testing.T) {

opt := mockOptions{}
t.Logf("result of o is %+v", opt)

}
1 change: 1 addition & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package gobpmn_builder
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ go 1.21.7

require (
github.com/deemount/gobpmnCounter v0.0.0-20240312102840-227373d7f040
github.com/deemount/gobpmnModels v0.0.0-20240315195348-76e2d8110fe8
github.com/deemount/gobpmnModels v0.0.0-20240316085912-7831ff39ffa4
github.com/stretchr/testify v1.9.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deemount/gobpmnReflection v0.0.0-20240315112013-036495e4c08d // indirect
github.com/deemount/gobpmnTypes v0.0.0-20240315111519-43046016ad9f // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
18 changes: 14 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
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/deemount/gobpmnCounter v0.0.0-20240312102840-227373d7f040 h1:vMsKGBWBsdy2UEDaOO+yCG4RLjYVyoLNARopS8o1/XM=
github.com/deemount/gobpmnCounter v0.0.0-20240312102840-227373d7f040/go.mod h1:gtlVIb4tlWVLxCZmme7ORdXFpbeVajRXKCI4KtaQ0l0=
github.com/deemount/gobpmnModels v0.0.0-20240315195348-76e2d8110fe8 h1:GIBwEU2hQIfXphDxI6Anv3dwO4Iorp6EFMRgTFIZ3Co=
github.com/deemount/gobpmnModels v0.0.0-20240315195348-76e2d8110fe8/go.mod h1:bv2zkkqCzzaGV5gYP3gDQfMXuqjxMBjSl9GjHFo2mY8=
github.com/deemount/gobpmnReflection v0.0.0-20240312080001-0601dc0824b6 h1:ZRHog+R0LurHMet3bliWHEUDM4z6mTe7j/eVGocMyrs=
github.com/deemount/gobpmnReflection v0.0.0-20240312080001-0601dc0824b6/go.mod h1:j8WCmdzEkTq/FVsWJAdoPtjTiRryLZp/WjOLcIqtt5c=
github.com/deemount/gobpmnModels v0.0.0-20240316085912-7831ff39ffa4 h1:xAqg4ZIeMDxME0O8O4UpwpcS3AeXB+3IspauNX2G2AA=
github.com/deemount/gobpmnModels v0.0.0-20240316085912-7831ff39ffa4/go.mod h1:bv2zkkqCzzaGV5gYP3gDQfMXuqjxMBjSl9GjHFo2mY8=
github.com/deemount/gobpmnReflection v0.0.0-20240315112013-036495e4c08d h1:yQY4ikw/HuvVlPu3hGc0X8gntQnSbLqMnUw/nHRRCKU=
github.com/deemount/gobpmnReflection v0.0.0-20240315112013-036495e4c08d/go.mod h1:j8WCmdzEkTq/FVsWJAdoPtjTiRryLZp/WjOLcIqtt5c=
github.com/deemount/gobpmnTypes v0.0.0-20240315111519-43046016ad9f h1:0gux6KtY8XgrN/L9tiZ7B+wx3th7x4hBYu1+wtUkHYY=
github.com/deemount/gobpmnTypes v0.0.0-20240315111519-43046016ad9f/go.mod h1:Dw7Jo8/vr0DzNHNMnbwQu0JSMWm2klNdo00rcxHCzJs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
58 changes: 49 additions & 9 deletions options.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,52 @@
package gobpmn_builder

import "github.com/deemount/gobpmnModels/pkg/core"

// Options
type Options struct {
Counter int
CurrentFile string
ModelType string
Def *core.Definitions
Repo core.DefinitionsRepository
import (
"log"
"os"

"github.com/deemount/gobpmnModels/pkg/core"
)

/*
Functional Options Pattern Type and Functions for the Builder
*/

// Option ...
type Option = func(bldr *Builder)

// WithPath ...
func WithPath(FilePathBPMN, FilePathJSON string) Option {
return func(bldr *Builder) {
bldr.FilePathBPMN = FilePathBPMN
bldr.FilePathJSON = FilePathJSON
}
}

// WithCounter ...
func WithCounter(filePath string) Option {
return func(bldr *Builder) {
// reading the directory with the path to the specified files
files, err := os.ReadDir(filePath)
if err != nil {
log.Panic(err)
}
// set number and count up for each created file
if len(files) == 0 {
bldr.Counter = 1
} else {
bldr.Counter += 1
}
}
}

func WithCurrentFile(filenamePrefix string) Option {
return func(bldr *Builder) {
bldr.FilenamePrefix = filenamePrefix
}
}

func WithDefinitions(Repo core.DefinitionsRepository) Option {
return func(bldr *Builder) {
bldr.Repo = Repo
}
}
18 changes: 7 additions & 11 deletions toBPMN.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import (
"os"
)

// toBPMN ...
// ToBPMN marshals the repository to a bpmn file
// and writes the file to the file system.
// The method returns an error if the file could not be created.
// The method returns nil if the file was created successfully.
func (bldr *Builder) ToBPMN() error {

var err error

// marshal xml to byte slice
b, _ := xml.MarshalIndent(&bldr.Options.Repo, " ", " ")
b, _ := xml.MarshalIndent(&bldr.Repo, " ", " ")

// path to bpmn files
path := "files/bpmn"
// create .bpmn file
f, err := os.Create(path + "/" + bldr.Options.CurrentFile + ".bpmn")
currFile := bldr.GetCurrentlyCreatedFilename()
f, err := os.Create(bldr.FilePathBPMN + "/" + currFile + ".bpmn")
if err != nil {
return err
}
Expand All @@ -36,12 +38,6 @@ func (bldr *Builder) ToBPMN() error {
return err
}

// create .json
err = bldr.toJSON()
if err != nil {
return err
}

return nil

}
Loading

0 comments on commit ec6aff8

Please sign in to comment.