github.com/bilus/oya@v0.0.3-0.20190301162104-da4acbd394c6/pkg/template/scope_test.go (about)

     1  package template_test
     2  
     3  import (
     4  	"encoding/gob"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/bilus/oya/pkg/template"
     9  	tu "github.com/bilus/oya/testutil"
    10  )
    11  
    12  func identity(scope template.Scope) template.Scope {
    13  	return scope
    14  }
    15  
    16  func mutation(scope template.Scope) template.Scope {
    17  	scope["bar"] = "baz"
    18  	return scope
    19  }
    20  
    21  func merge(scope template.Scope) template.Scope {
    22  	return scope.Merge(template.Scope{"bar": "baz"})
    23  }
    24  
    25  func deepcopy(dst, src interface{}) error {
    26  	r, w, err := os.Pipe()
    27  	if err != nil {
    28  		return err
    29  	}
    30  	enc := gob.NewEncoder(w)
    31  	err = enc.Encode(src)
    32  	if err != nil {
    33  		return err
    34  	}
    35  	dec := gob.NewDecoder(r)
    36  	return dec.Decode(dst)
    37  }
    38  
    39  func TestScope_UpdateScopeAt(t *testing.T) {
    40  	testCases := []struct {
    41  		desc          string
    42  		scope         template.Scope
    43  		path          string
    44  		f             func(template.Scope) template.Scope
    45  		expectedScope template.Scope
    46  	}{
    47  		{
    48  			desc:          "empty path, return original",
    49  			scope:         template.Scope{},
    50  			path:          "",
    51  			f:             identity,
    52  			expectedScope: template.Scope{},
    53  		},
    54  		{
    55  			desc:  "empty path, make an in-place update",
    56  			scope: template.Scope{},
    57  			path:  "",
    58  			f:     mutation,
    59  			expectedScope: template.Scope{
    60  				"bar": "baz",
    61  			},
    62  		},
    63  		{
    64  			desc:  "empty path, return updated copy",
    65  			scope: template.Scope{},
    66  			path:  "",
    67  			f:     merge,
    68  			expectedScope: template.Scope{
    69  				"bar": "baz",
    70  			},
    71  		},
    72  		{
    73  			desc:  "non-existent path, return original",
    74  			scope: template.Scope{},
    75  			path:  "foo",
    76  			f:     identity,
    77  			expectedScope: template.Scope{
    78  				"foo": template.Scope{},
    79  			},
    80  		},
    81  		{
    82  			desc:  "non-existent path, make an in-place update",
    83  			scope: template.Scope{},
    84  			path:  "foo",
    85  			f:     mutation,
    86  			expectedScope: template.Scope{
    87  				"foo": template.Scope{
    88  					"bar": "baz",
    89  				},
    90  			},
    91  		},
    92  		{
    93  			desc:  "non-existent path, return updated copy",
    94  			scope: template.Scope{},
    95  			path:  "foo",
    96  			f:     merge,
    97  			expectedScope: template.Scope{
    98  				"foo": template.Scope{
    99  					"bar": "baz",
   100  				},
   101  			},
   102  		},
   103  		{
   104  			desc:  "non-existent deep path, return original",
   105  			scope: template.Scope{},
   106  			path:  "foo.xxx.yyy",
   107  			f:     identity,
   108  			expectedScope: template.Scope{
   109  				"foo": template.Scope{
   110  					"xxx": template.Scope{
   111  						"yyy": template.Scope{},
   112  					},
   113  				},
   114  			},
   115  		},
   116  		{
   117  			desc:  "non-existent path, make an in-place update",
   118  			scope: template.Scope{},
   119  			path:  "foo.xxx.yyy",
   120  			f:     mutation,
   121  			expectedScope: template.Scope{
   122  				"foo": template.Scope{
   123  					"xxx": template.Scope{
   124  						"yyy": template.Scope{
   125  							"bar": "baz",
   126  						},
   127  					},
   128  				},
   129  			},
   130  		},
   131  		{
   132  			desc:  "non-existent path, return updated copy",
   133  			scope: template.Scope{},
   134  			path:  "foo.xxx.yyy",
   135  			f:     merge,
   136  			expectedScope: template.Scope{
   137  				"foo": template.Scope{
   138  					"xxx": template.Scope{
   139  						"yyy": template.Scope{
   140  							"bar": "baz",
   141  						},
   142  					},
   143  				},
   144  			},
   145  		},
   146  	}
   147  
   148  	for _, tc := range testCases {
   149  		var scope template.Scope
   150  		err := deepcopy(&scope, tc.scope) // Because f can mutate it.
   151  		tu.AssertNoErr(t, err, "deepcopy failed")
   152  		err = scope.UpdateScopeAt(tc.path, tc.f)
   153  		tu.AssertNoErr(t, err, "UpdateScopeAt failed in test case %q", tc.desc)
   154  		tu.AssertObjectsEqualMsg(t, tc.expectedScope, scope, "In test case %q", tc.desc)
   155  	}
   156  }