github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/plugin/expand_params_test.go (about)

     1  package plugin
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/evergreen-ci/evergreen/command"
     7  	. "github.com/smartystreets/goconvey/convey"
     8  )
     9  
    10  func TestIsExpandable(t *testing.T) {
    11  
    12  	Convey("With a passed in string...", t, func() {
    13  		Convey("IsExpandable should return true if the string is expandable",
    14  			func() {
    15  				So(IsExpandable("${34}"), ShouldEqual, true)
    16  				So(IsExpandable("${34}}"), ShouldEqual, true)
    17  				So(IsExpandable("{${34}"), ShouldEqual, true)
    18  				So(IsExpandable("{${34}}"), ShouldEqual, true)
    19  				So(IsExpandable("${34"), ShouldEqual, false)
    20  				So(IsExpandable("$34"), ShouldEqual, false)
    21  				So(IsExpandable("{$34}}"), ShouldEqual, false)
    22  				So(IsExpandable("34"), ShouldEqual, false)
    23  			})
    24  	})
    25  }
    26  
    27  func TestExpandValues(t *testing.T) {
    28  
    29  	Convey("When expanding struct values", t, func() {
    30  
    31  		expansions := command.NewExpansions(
    32  			map[string]string{
    33  				"exp1": "val1",
    34  			},
    35  		)
    36  
    37  		Convey("if the input value is not a pointer to a struct, an error"+
    38  			" should be returned", func() {
    39  			So(ExpandValues("hello", expansions), ShouldNotBeNil)
    40  			So(ExpandValues(struct{}{}, expansions), ShouldNotBeNil)
    41  			So(ExpandValues([]string{"hi"}, expansions), ShouldNotBeNil)
    42  		})
    43  
    44  		Convey("if any non-string fields are tagged as expandable, an error"+
    45  			" should be returned", func() {
    46  
    47  			type s struct {
    48  				FieldOne string `plugin:"expand"`
    49  				FieldTwo int    `plugin:"expand"`
    50  			}
    51  
    52  			So(ExpandValues(&s{}, expansions), ShouldNotBeNil)
    53  
    54  		})
    55  
    56  		Convey("any fields of the input struct with the appropriate tag should"+
    57  			" be expanded", func() {
    58  
    59  			type s struct {
    60  				FieldOne   string
    61  				FieldTwo   string `plugin:"expand"`
    62  				FieldThree string `plugin:"expand,hello"`
    63  			}
    64  
    65  			s1 := &s{
    66  				FieldOne:   "hello ${exp1}",
    67  				FieldTwo:   "hi ${exp1}",
    68  				FieldThree: "yo ${exp2|yo}",
    69  			}
    70  
    71  			So(ExpandValues(s1, expansions), ShouldBeNil)
    72  
    73  			// make sure the appropriate fields were expanded
    74  			So(s1.FieldOne, ShouldEqual, "hello ${exp1}")
    75  			So(s1.FieldTwo, ShouldEqual, "hi val1")
    76  			So(s1.FieldThree, ShouldEqual, "yo yo")
    77  
    78  		})
    79  
    80  		Convey("any nested structs tagged as expandable should have their"+
    81  			" fields expanded appropriately", func() {
    82  
    83  			type inner struct {
    84  				FieldOne string `plugin:"expand"`
    85  			}
    86  
    87  			type outer struct {
    88  				FieldOne   string `plugin:"expand"`
    89  				FieldTwo   inner  `plugin:"expand"`
    90  				FieldThree inner
    91  			}
    92  
    93  			s := &outer{
    94  				FieldOne: "hello ${exp1}",
    95  				FieldTwo: inner{
    96  					FieldOne: "hi ${exp1}",
    97  				},
    98  				FieldThree: inner{
    99  					FieldOne: "yo ${exp1}",
   100  				},
   101  			}
   102  
   103  			So(ExpandValues(s, expansions), ShouldBeNil)
   104  
   105  			// make sure all fields, including nested ones, were expanded
   106  			// correctly
   107  			So(s.FieldOne, ShouldEqual, "hello val1")
   108  			So(s.FieldTwo.FieldOne, ShouldEqual, "hi val1")
   109  			So(s.FieldThree.FieldOne, ShouldEqual, "yo ${exp1}")
   110  
   111  		})
   112  
   113  		Convey("any nested maps tagged as expandable should have their"+
   114  			" fields expanded appropriately", func() {
   115  
   116  			type outer struct {
   117  				FieldOne string            `plugin:"expand"`
   118  				FieldTwo map[string]string `plugin:"expand"`
   119  			}
   120  
   121  			s := &outer{
   122  				FieldOne: "hello ${exp1}",
   123  				FieldTwo: map[string]string{
   124  					"1":       "hi ${exp1}",
   125  					"${exp1}": "yo ${exp1}",
   126  				},
   127  			}
   128  
   129  			So(ExpandValues(s, expansions), ShouldBeNil)
   130  
   131  			// make sure all fields, including nested maps, were expanded
   132  			So(s.FieldOne, ShouldEqual, "hello val1")
   133  			So(s.FieldTwo["1"], ShouldEqual, "hi val1")
   134  			So(s.FieldTwo["val1"], ShouldEqual, "yo val1")
   135  		})
   136  
   137  		Convey("if the input value is a slice, expansion should work "+
   138  			"for the fields within that slice", func() {
   139  
   140  			type simpleStruct struct {
   141  				StructFieldKeyOne string `plugin:"expand"`
   142  				StructFieldKeyTwo string
   143  			}
   144  			type sliceStruct struct {
   145  				SliceFieldKey []*simpleStruct `plugin:"expand"`
   146  			}
   147  			simpleStruct1 := simpleStruct{
   148  				StructFieldKeyOne: "hello ${exp1}",
   149  				StructFieldKeyTwo: "abc${expl}",
   150  			}
   151  			simpleSlice := make([]*simpleStruct, 0)
   152  			simpleSlice = append(simpleSlice, &simpleStruct1)
   153  			sliceStruct1 := sliceStruct{}
   154  			sliceStruct1.SliceFieldKey = simpleSlice
   155  			So(ExpandValues(&sliceStruct1, expansions), ShouldBeNil)
   156  
   157  			// make sure the appropriate fields were expanded
   158  			So(simpleStruct1.StructFieldKeyOne, ShouldEqual, "hello val1")
   159  			So(simpleStruct1.StructFieldKeyTwo, ShouldEqual, "abc${expl}")
   160  
   161  		})
   162  
   163  		Convey("any nested structs/slices tagged as expandable should have "+
   164  			"their fields expanded appropriately", func() {
   165  
   166  			type innerStruct struct {
   167  				FieldOne string `plugin:"expand"`
   168  			}
   169  
   170  			type innerSlice struct {
   171  				FieldOne string `plugin:"expand"`
   172  			}
   173  
   174  			type middle struct {
   175  				FieldOne   string `plugin:"expand"`
   176  				FieldTwo   string
   177  				FieldThree innerStruct
   178  				FieldFour  []*innerSlice
   179  			}
   180  
   181  			type outer struct {
   182  				FieldOne string    `plugin:"expand"`
   183  				FieldTwo []*middle `plugin:"expand"`
   184  			}
   185  
   186  			innerStructObject := innerStruct{
   187  				FieldOne: "hello ${exp1}",
   188  			}
   189  
   190  			innerSliceField := innerSlice{
   191  				FieldOne: "hi ${exp1}",
   192  			}
   193  
   194  			innerSliceObject := make([]*innerSlice, 0)
   195  			innerSliceObject = append(innerSliceObject, &innerSliceField)
   196  
   197  			middleObjectOne := middle{
   198  				FieldOne: "ab ${exp1}",
   199  				FieldTwo: "abc ${exp1}",
   200  			}
   201  
   202  			middleObjectTwo := middle{
   203  				FieldOne:   "abc ${exp1}",
   204  				FieldTwo:   "abc ${exp1}",
   205  				FieldThree: innerStructObject,
   206  				FieldFour:  innerSliceObject,
   207  			}
   208  
   209  			middleObject := make([]*middle, 0)
   210  			middleObject = append(middleObject, &middleObjectOne)
   211  			middleObject = append(middleObject, &middleObjectTwo)
   212  
   213  			s := &outer{
   214  				FieldOne: "hello ${exp1}",
   215  				FieldTwo: middleObject,
   216  			}
   217  
   218  			So(ExpandValues(s, expansions), ShouldBeNil)
   219  
   220  			// make sure all fields, including nested ones, were expanded
   221  			// correctly
   222  			So(s.FieldOne, ShouldEqual, "hello val1")
   223  			So(s.FieldTwo[0].FieldOne, ShouldEqual, "ab val1")
   224  			So(s.FieldTwo[1].FieldOne, ShouldEqual, "abc val1")
   225  			So(s.FieldTwo[0].FieldTwo, ShouldEqual, "abc ${exp1}")
   226  			So(s.FieldTwo[1].FieldTwo, ShouldEqual, "abc ${exp1}")
   227  			So(s.FieldTwo[1].FieldThree.FieldOne, ShouldEqual, "hello ${exp1}")
   228  			So(s.FieldTwo[1].FieldFour[0].FieldOne, ShouldEqual, "hi ${exp1}")
   229  		})
   230  	})
   231  
   232  	Convey("When expanding map values", t, func() {
   233  		expansions := command.NewExpansions(
   234  			map[string]string{
   235  				"a": "A",
   236  				"b": "B",
   237  				"c": "C",
   238  			},
   239  		)
   240  
   241  		Convey("a simple map expands properly", func() {
   242  			testmap := map[string]string{
   243  				"nope": "nothing",
   244  				"${a}": "key",
   245  				"val":  "${b}",
   246  				"${c}": "${a}",
   247  			}
   248  			So(ExpandValues(&testmap, expansions), ShouldBeNil)
   249  			So(testmap["nope"], ShouldEqual, "nothing")
   250  			So(testmap["A"], ShouldEqual, "key")
   251  			So(testmap["val"], ShouldEqual, "B")
   252  			So(testmap["C"], ShouldEqual, "A")
   253  		})
   254  
   255  		Convey("a recursive map expands properly", func() {
   256  			testmap := map[string]map[string]string{
   257  				"${a}": {
   258  					"deep": "${c}",
   259  					"no":   "same",
   260  				},
   261  			}
   262  			So(ExpandValues(&testmap, expansions), ShouldBeNil)
   263  			So(len(testmap), ShouldEqual, 1)
   264  			So(len(testmap["A"]), ShouldEqual, 2)
   265  			So(testmap["A"]["no"], ShouldEqual, "same")
   266  			So(testmap["A"]["deep"], ShouldEqual, "C")
   267  		})
   268  	})
   269  }