فهرست منبع

Refactored registry to a single add function

luis 7 سال پیش
والد
کامیت
cab3413f93

+ 7 - 8
go/src/flow/flow_test.go

@@ -223,8 +223,7 @@ func TestLocalRegistry(t *testing.T) {
 	a := assert.A(t)
 
 	r := registry.New()
-	e, err := r.Register("test", func() string { return "" })
-	a.Eq(err, nil, "should not error registering a func")
+	e := r.Add("test", func() string { return "" })
 	a.NotEq(e, nil, "registered in a local register")
 
 	f := flow.New()
@@ -232,16 +231,16 @@ func TestLocalRegistry(t *testing.T) {
 	op, _ := f.Op("test")
 	a.NotEq(op, nil, "operation should be valid")
 
-	op, err = f.Op("none")
+	op, err := f.Op("none")
 	a.NotEq(err, nil, "flow should contain an error")
 }
 
 func init() {
-	registry.Register("vecmul", VecMul)
-	registry.Register("vecadd", VecAdd)
-	registry.Register("vecdiv", VecDiv)
-	registry.Register("inc", Inc)
-	registry.Register("add", Add)
+	registry.Add("vecmul", VecMul)
+	registry.Add("vecadd", VecAdd)
+	registry.Add("vecdiv", VecDiv)
+	registry.Add("inc", Inc)
+	registry.Add("add", Add)
 }
 
 func prepareComplex() (*flow.Flow, flow.Operation) {

+ 5 - 1
go/src/flow/operation.go

@@ -110,7 +110,7 @@ func (f *Flow) makeExecutor(id string, fn interface{}) executorFunc {
 		fnval := reflect.ValueOf(fn)
 		callParam, err := f.processInputs(ctx, op, fnval, params...)
 		if err != nil {
-			log.Println("ERR", err)
+			//log.Println("ERR", err)
 			return nil, err
 		}
 
@@ -164,6 +164,7 @@ func (f *Flow) processInputs(ctx OpCtx, op *operation, fnval reflect.Value, para
 			/////////////////
 			// Executor
 			fr, err := in.executor(ctx, params...)
+			//log.Println("Executing:", in.id, in.name, fr)
 
 			paramMutex.Lock()
 			defer paramMutex.Unlock()
@@ -172,6 +173,7 @@ func (f *Flow) processInputs(ctx OpCtx, op *operation, fnval reflect.Value, para
 				return
 			}
 			if fr == nil {
+				log.Println("Zero value", inTyp)
 				callParam[i] = reflect.Zero(inTyp)
 				return
 			}
@@ -184,6 +186,7 @@ func (f *Flow) processInputs(ctx OpCtx, op *operation, fnval reflect.Value, para
 				callErrors += fmt.Sprintf("Input %d invalid\n", i)
 				return
 			case !res.Type().ConvertibleTo(inTyp):
+				log.Println("Conversible")
 				if inTyp.Kind() != reflect.String {
 					callErrors += fmt.Sprintf("Input %d type: %v(%v) cannot be converted to %v\n", i, res.Type(), res.Interface(), inTyp)
 					log.Println(f)
@@ -199,6 +202,7 @@ func (f *Flow) processInputs(ctx OpCtx, op *operation, fnval reflect.Value, para
 	}
 	wg.Wait()
 	if callErrors != "" {
+		log.Println("Call errors:", callErrors)
 		return nil, errors.New(callErrors)
 	}
 

+ 24 - 32
go/src/flow/registry/describer.go

@@ -14,29 +14,33 @@ type Description struct {
 }
 
 //EDescriber helper to batch set properties
-type EDescriber []*Entry
+type EDescriber struct {
+	entries []*Entry
+	Err     error
+}
 
 // Describer returns a batch of entries for easy manipulation
-func Describer(params ...interface{}) EDescriber {
-	ret := EDescriber{}
+func Describer(params ...interface{}) *EDescriber {
+	ret := &EDescriber{[]*Entry{}, nil}
 	for _, el := range params {
 		switch v := el.(type) {
-		case EDescriber:
-			ret = append(ret, v...)
+		case *EDescriber:
+			ret.entries = append(ret.entries, v.entries...)
 		case *Entry:
-			ret = append(ret, v)
+			ret.entries = append(ret.entries, v)
 		}
 	}
 	return ret
 }
 
-// Description set node description
-func (d EDescriber) Description(m string) EDescriber {
-	for _, e := range d {
-		if e.Description == nil {
-			continue
-		}
+// Entries return entries from describer
+func (d *EDescriber) Entries() []*Entry {
+	return d.entries
+}
 
+// Description set node description
+func (d *EDescriber) Description(m string) *EDescriber {
+	for _, e := range d.entries {
 		e.Description.Desc = m
 	}
 	return d
@@ -44,22 +48,16 @@ func (d EDescriber) Description(m string) EDescriber {
 }
 
 //Tags set categories of the group
-func (d EDescriber) Tags(tags ...string) EDescriber {
-	for _, e := range d {
-		if e.Description == nil {
-			continue
-		}
+func (d *EDescriber) Tags(tags ...string) *EDescriber {
+	for _, e := range d.entries {
 		e.Description.Tags = tags
 	}
 	return d
 }
 
 // Inputs describe inputs
-func (d EDescriber) Inputs(inputs ...string) EDescriber {
-	for _, e := range d {
-		if e.Description == nil {
-			continue
-		}
+func (d *EDescriber) Inputs(inputs ...string) *EDescriber {
+	for _, e := range d.entries {
 
 		for i, dstr := range inputs {
 			if i >= len(e.Description.Inputs) { // do nothing
@@ -73,22 +71,16 @@ func (d EDescriber) Inputs(inputs ...string) EDescriber {
 }
 
 // Output describe the output
-func (d EDescriber) Output(output string) EDescriber {
-	for _, e := range d {
-		if e.Description == nil {
-			continue
-		}
+func (d *EDescriber) Output(output string) *EDescriber {
+	for _, e := range d.entries {
 		e.Description.Output = DescType{e.Description.Output.Type, output}
 	}
 	return d
 }
 
 // Extra set extras of the group
-func (d EDescriber) Extra(name string, value interface{}) EDescriber {
-	for _, e := range d {
-		if e.Description == nil {
-			continue
-		}
+func (d *EDescriber) Extra(name string, value interface{}) *EDescriber {
+	for _, e := range d.entries {
 		e.Description.Extra[name] = value
 	}
 	return d

+ 25 - 19
go/src/flow/registry/describer_test.go

@@ -11,37 +11,43 @@ func TestMakeBatch(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
 
-	b := registry.Describer(
-		r.MustAdd(strings.Split, strings.Join),
-		r.MustAdd(strings.Compare),
-		r.MustRegister("named", strings.Compare),
+	d := registry.Describer(
+		r.Add(strings.Split, strings.Join),
+		r.Add(strings.Compare),
+		r.Add("named", strings.Compare),
 	)
-	a.Eq(len(b), 4, "should have 3 entries in batch")
+	a.Eq(len(d.Entries()), 4, "should have 4 entries in batch")
 
-	b.Inputs("str")
-	b.Output("result")
+	d.Inputs("str")
+	d.Output("result")
 
-	for _, en := range b {
+	for _, en := range d.Entries() {
 		a.Eq(en.Description.Inputs[0].Name, "str", "first input should be string")
 		a.Eq(en.Description.Output.Name, "result", "output should be equal")
 	}
 }
-func TestNilDescription(t *testing.T) {
+
+/*func TestNilDescription(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
 
-	r.MustRegister("test", strings.Compare)
+	r.Add("test", strings.Compare)
 	e, _ := r.Entry("test")
 	e.Description = nil
 
-	b := registry.Describer(e)
-	a.Eq(len(b), 1, "should have 3 entries in batch")
+	d := registry.Describer(e)
+	a.Eq(len(d.Entries()), 1, "should have 3 entries in batch")
 
 	// Testing adding to a nil description
-	b.Tags("")
-	b.Description("")
-	b.Inputs("str")
-	b.Output("result")
-	b.Extra("v", "v")
-
-}
+	d.Tags("")
+	a.NotEq(d.Err, nil, "err should not be nil while adding tags")
+	d.Description("")
+	a.NotEq(d.Err, nil, "err should not be nil while adding a description")
+	d.Inputs("str")
+	a.NotEq(d.Err, nil, "err should not be nil describing inputs")
+	d.Output("result")
+	a.NotEq(d.Err, nil, "err should not be nil describing the output")
+	d.Extra("v", "v")
+	a.NotEq(d.Err, nil, "err should not be nil setting extra")
+
+}*/

+ 3 - 3
go/src/flow/registry/entry.go

@@ -17,7 +17,7 @@ type Entry struct {
 	fn          interface{}
 	Inputs      []reflect.Type
 	Output      reflect.Type
-	Description *Description
+	Description Description
 	Err         error
 }
 
@@ -50,7 +50,7 @@ func NewEntry(r *R, fn interface{}) (*Entry, error) {
 		e.Inputs = append(e.Inputs, inTyp) // ?
 	}
 
-	e.Description = &Description{
+	e.Description = Description{
 		Tags:   []string{"generic"},
 		Inputs: Inputs,
 		Output: Output,
@@ -60,6 +60,6 @@ func NewEntry(r *R, fn interface{}) (*Entry, error) {
 }
 
 // Describer return a description builder
-func (e *Entry) Describer() EDescriber {
+func (e *Entry) Describer() *EDescriber {
 	return Describer(e)
 }

+ 8 - 7
go/src/flow/registry/entry_test.go

@@ -13,7 +13,7 @@ func TestFlowFunc(t *testing.T) {
 	f := flow.New()
 	f.SetRegistry(r)
 
-	r.Register("flowfunc", func(paramFlow *flow.Flow) int {
+	r.Add("flowfunc", func(paramFlow *flow.Flow) int {
 		a.Eq(paramFlow, f, "Flow should be equal")
 		return 0
 	})
@@ -71,14 +71,15 @@ func TestEntryBatch(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
 
-	b := registry.Describer(
-		r.MustAdd(func() int { return 0 }),
-		r.MustAdd(func() int { return 0 }),
-		r.MustAdd(func() int { return 0 }),
+	d := registry.Describer(
+		r.Add(func() int { return 0 }),
+		r.Add(func() int { return 0 }),
+		r.Add(func() int { return 0 }),
 	).Tags("test").Extra("name", 1)
 
-	a.Eq(len(b), 3, "should have 3 items")
-	for _, e := range b {
+	a.Eq(d.Err, nil, "should not error registering funcs")
+	a.Eq(len(d.Entries()), 3, "should have 3 items")
+	for _, e := range d.Entries() {
 		a.Eq(e.Description.Tags[0], "test", "It should be of category test")
 		a.Eq(e.Description.Extra["name"], 1, "It should contain extra")
 	}

+ 18 - 9
go/src/flow/registry/registry.go

@@ -39,28 +39,33 @@ func (r *R) Clone() *R {
 }
 
 // Add function to registry
-func (r *R) Add(args ...interface{}) EDescriber {
+func (r *R) Add(args ...interface{}) *EDescriber {
 
 	var nextName string
 	var name string
 	var fn interface{}
 
-	b := EDescriber{}
+	d := &EDescriber{[]*Entry{}, nil}
 	for _, a := range args {
 		switch f := a.(type) {
 		case string:
+			if nextName != "" {
+				d.Err = ErrNotAFunc
+				return d
+			}
 			nextName = f
 			continue
 		default:
 			fn = a
-			if reflect.TypeOf(fn).Kind() != reflect.Func {
-				panic(ErrNotAFunc)
-			}
 			// consume name
 			if nextName != "" {
 				name = nextName
 				nextName = ""
 			} else {
+				if reflect.TypeOf(fn).Kind() != reflect.Func {
+					d.Err = ErrNotAFunc
+					return d
+				}
 				// Automatic naming
 				name = runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
 				name = path.Ext(name)[1:]
@@ -69,12 +74,16 @@ func (r *R) Add(args ...interface{}) EDescriber {
 
 		e, err := r.register(name, fn)
 		if err != nil {
-			panic(err)
+			d.Err = err
+			return d
 		}
-		b = append(b, e)
+		d.entries = append(d.entries, e)
+	}
+	if nextName != "" {
+		d.Err = ErrNotAFunc
 	}
 
-	return b
+	return d
 }
 
 //Register should be a func only register
@@ -127,7 +136,7 @@ func (r *R) Entry(name string) (*Entry, error) {
 func (r *R) Descriptions() (map[string]Description, error) {
 	ret := map[string]Description{}
 	for k, e := range r.data {
-		ret[k] = *e.Description
+		ret[k] = e.Description
 	}
 	return ret, nil
 }

+ 38 - 54
go/src/flow/registry/registry_test.go

@@ -4,13 +4,18 @@ import (
 	"flow/internal/assert"
 	"flow/registry"
 	"testing"
+
+	"github.com/gohxs/prettylog"
 )
 
+func init() {
+	prettylog.Global()
+}
 func TestRegistry(t *testing.T) {
 	a := assert.A(t)
 
 	r := registry.New()
-	r.Register("vecadd", dummy1)
+	r.Add("vecadd", dummy1)
 
 	e, err := r.Entry("vecadd")
 	a.Eq(err, nil, "fetching entry")
@@ -34,38 +39,32 @@ func TestEntry(t *testing.T) {
 
 }
 
-func TestRegister(t *testing.T) {
-	a := assert.A(t)
-	r := registry.New()
-	_, err := r.Register("func", func(a, b int) int { return 0 })
-	a.Eq(err, nil, "should register a function")
-}
 func TestRegisterDuplicate(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
-	r.Register("func", func(a, b int) int { return 0 })
-	_, err := r.Register("func", func(b int) int { return 0 })
-	a.Eq(err, nil, "should allow duplicate")
+	r.Add("func", func(a, b int) int { return 0 })
+	d := r.Add("func", func(b int) int { return 0 })
+	a.Eq(d.Err, nil, "should allow duplicate")
 }
 func TestRegisterOutput(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
-	_, err := r.Register("func", func(a int) {})
-	a.Eq(err, nil, "should not give output error")
+	d := r.Add("func", func(a int) {})
+	a.Eq(d.Err, nil, "should not give output error")
 }
 
 func TestRegisterInvalidInput(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
-	_, err := r.Register("func", func() int { return 0 })
-	a.Eq(err, nil, "should register a func without params")
+	d := r.Add("func", func() int { return 0 })
+	a.Eq(d.Err, nil, "should register a func without params")
 }
 
 func TestRegistryGet(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
-	_, err := r.Register("func", func() int { return 0 })
-	a.Eq(err, nil, "should register func")
+	d := r.Add("func", func() int { return 0 })
+	a.Eq(d.Err, nil, "should register func")
 
 	fn, err := r.Get("func")
 	a.Eq(err, nil, "should fetch a function")
@@ -82,12 +81,12 @@ func TestRegistryGetEmpty(t *testing.T) {
 func TestRegistryGetConstructor(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
-	_, err := r.Register("func", func() func() int {
+	d := r.Add("func", func() func() int {
 		return func() int {
 			return 0
 		}
 	})
-	a.Eq(err, nil, "should register the constructor func")
+	a.Eq(d.Err, nil, "should register the constructor func")
 
 	ifn, err := r.Get("func")
 	a.Eq(err, nil, "get should not error")
@@ -103,12 +102,12 @@ func TestRegistryGetConstructorParam(t *testing.T) {
 	a := assert.A(t)
 
 	r := registry.New()
-	_, err := r.Register("func2", func(a, b int) func() int {
+	d := r.Add("func2", func(a, b int) func() int {
 		return func() int {
 			return a + b
 		}
 	})
-	a.Eq(err, nil)
+	a.Eq(d.Err, nil)
 	ifn, err := r.Get("func2", 1, 1)
 	a.Eq(err, nil, "should not fail passing params to constructor")
 	a.NotEq(ifn, nil, "should return a function")
@@ -125,8 +124,8 @@ func TestDescriptions(t *testing.T) {
 	a := assert.A(t)
 
 	r := registry.New()
-	r.Register("vecadd", dummy1)
-	r.Register("vecstr", dummy2)
+	r.Add("vecadd", dummy1)
+	r.Add("vecstr", dummy2)
 
 	d, err := r.Descriptions()
 	a.Eq(err, nil, "should fetch Descriptions")
@@ -137,16 +136,16 @@ func TestDescriptions(t *testing.T) {
 func TestClone(t *testing.T) {
 	a := assert.A(t)
 	r := registry.New()
-	r.Register("vecadd", dummy1)
+	r.Add("vecadd", dummy1)
 
-	d, err := r.Descriptions()
+	desc, err := r.Descriptions()
 	a.Eq(err, nil, "should not error fetching description")
 
-	a.Eq(len(d), 1, "should contain 1 descriptions")
+	a.Eq(len(desc), 1, "should contain 1 descriptions")
 
 	r2 := r.Clone()
-	r2.Register("vecmul", dummy2)
-	a.Eq(len(d), 1, "should contain 1 descriptions")
+	r2.Add("vecmul", dummy2)
+	a.Eq(len(desc), 1, "should contain 1 descriptions")
 
 	d2, err := r2.Descriptions()
 	a.Eq(err, nil, "should not error fetching descriptions")
@@ -155,42 +154,27 @@ func TestClone(t *testing.T) {
 	_, ok := d2["vecmul"]
 	a.Eq(ok, true, "should be equal")
 }
+
 func TestNotAFunc(t *testing.T) {
+	a := assert.A(t)
 	r := registry.New()
 
-	_, err := r.Add("test")
-	assert.Eq(t, err, registry.ErrNotAFunc, "should give not a func error")
-}
+	d := r.Add("test", []string{})
+	a.Eq(d.Err, registry.ErrNotAFunc, "should give a func error")
 
-func TestRegisterErr(t *testing.T) {
-	r := registry.New()
+	d = r.Add("test")
+	a.Eq(d.Err, registry.ErrNotAFunc, "should give a func error")
+
+	d = r.Add([]string{})
+	a.Eq(d.Err, registry.ErrNotAFunc, "should give a func error")
 
-	_, err := r.Register("name", "notfunc")
-	assert.Eq(t, err, registry.ErrNotAFunc, "should give not a func error")
 }
 
-func TestRegisterMust(t *testing.T) {
-	a := assert.A(t)
+func TestRegisterErr(t *testing.T) {
 	r := registry.New()
 
-	func() {
-		defer func() {
-			p := recover()
-			a.Eq(p, registry.ErrNotAFunc, "should panic giving ErrNotAFunc")
-		}()
-
-		r.MustRegister("name", "notfunc")
-	}()
-
-	func() {
-		defer func() {
-			p := recover()
-			a.Eq(p, registry.ErrNotAFunc, "should panic giving ErrNotAFunc")
-		}()
-
-		r.MustAdd("name", "notfunc")
-
-	}()
+	d := r.Add("name", "notfunc")
+	assert.Eq(t, d.Err, registry.ErrNotAFunc, "should give a func error")
 }
 
 /*func TestAddEntry(t *testing.T) {