Skip to content

Commit

Permalink
Test and comments re unbound vars; closes #70
Browse files Browse the repository at this point in the history
  • Loading branch information
jsccast committed Apr 9, 2021
1 parent 9176efc commit d3e3bb3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 7 deletions.
18 changes: 11 additions & 7 deletions subst/bindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,8 @@ func (bs *Bindings) Set(value string) error {
return bs.SetJSON(pv[0], pv[1])
}

// replaceBindings replaces all variables in x with their
// corresponding values in bs (if any).
//
// This operation is destructive (and probably shouldn't be).
//
// An array or map should have interface{}-typed elements or values.
// replaceBindings replaces all structural variables in x with their
// corresponding values in bs (if any). See docs for Bindings.Bind().
func (bs *Bindings) replaceBindings(ctx *Ctx, x interface{}) (interface{}, error) {
b := *bs
switch vv := x.(type) {
Expand Down Expand Up @@ -165,7 +161,15 @@ func (bs *Bindings) replaceBindings(ctx *Ctx, x interface{}) (interface{}, error
}
}

// Bind replaces all bindings in the given (structured) thing.
// Bind replaces all structural variables in x with their
// corresponding values in bs (if any).
//
// This operation is destructive (and probably shouldn't be).
//
// An array or map should have interface{}-typed elements or values.
//
// An unbound variable does not result in an error. See some comments
// in the Subber type.
func (bs *Bindings) Bind(ctx *Ctx, x interface{}) (interface{}, error) {
return bs.replaceBindings(ctx, x)
}
Expand Down
10 changes: 10 additions & 0 deletions subst/subst.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ type Subber struct {
// pipePattern is the (compiled) Regexp that included the
// delimiters provided to NewSubber.
pipePattern *regexp.Regexp

// ToDo: We might want a switch that controls whether the
// Subber returns an error when it encounters a string-based
// VAR that is not bound. There are some (exotic?) situations
// where an unbound VAR is a string-based substitution
// expression should be left as is and without and error.
// Note that a structured unbound VAR is usually fine in a
// 'recv' context because the point can be to bind that var
// via pattern matching. A switch could be helpful to get the
// right behavior in different contexts.
}

// NewSubber makes a new Subber with the pipe expression delimiters
Expand Down
24 changes: 24 additions & 0 deletions subst/subst_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,30 @@ func TestSubberWithProcs(t *testing.T) {

}

func TestUnbound(t *testing.T) {
var (
ctx = NewCtx(context.Background(), nil)
bs = NewBindings()
b, err = NewSubber("")
)
if err != nil {
t.Fatal(err)
}

s, err := b.Sub(ctx, bs, `{?NOPE}`)
if err == nil {
t.Fatal(s)
}
// source '?NOPE' variable not bound in '{?NOPE}'

// We do not want to complain (in recv cases at least) if a
// structured VAR isn't bound.
s, err = b.Sub(ctx, bs, `"?NOPE"`)
if err != nil {
t.Fatal(err)
}
}

func TestLimit(t *testing.T) {
var (
ctx = NewCtx(context.Background(), nil)
Expand Down

0 comments on commit d3e3bb3

Please sign in to comment.