func TestFnFor_PreProcessArgs(t *testing.T) { stack := deepstack.DeepStack{} templateRules := template.Rules{} templateRules.Attach(func(path []interface{}, node interface{}) (interface{}, interface{}) { key := interface{}(nil) if len(path) > 0 { key = path[len(path)-1] } aString, ok := node.(string) if !ok { return key, node } if aString == "skip" { return true, nil } if aString == "refNames" { return key, []interface{}{"key", "value"} } if aString == "values" { return key, []interface{}{"a"} } if aString == "template" { _, hasKey := stack.Get([]string{"value"}) if hasKey { return key, "processed-template" } return key, "preprocessed-template" } return key, node }) fnFor := MakeFnFor(&stack, &templateRules) input := interface{}(map[string]interface{}{ "Fn::For": []interface{}{"skip", "refNames", "skip", "values", "skip", "template", "skip"}, }) expected := []interface{}{"processed-template"} newKey, newNode := fnFor([]interface{}{"x", "y"}, input) if newKey != "y" { t.Fatalf("FnFor modified the path (%v instead of %v)", newKey, "y") } if !reflect.DeepEqual(newNode, expected) { t.Fatalf("FnFor with did not return the expected result (%#v instead of %#v)", newNode, expected) } }
func TestFnFor_StackWithArray(t *testing.T) { stack := deepstack.DeepStack{} stack.Push(fallbackmap.DeepMap(map[string]interface{}{"outer": "outerValue", "masked": "outerMasked"})) testRefNames := []interface{}{ []interface{}{"key", "masked"}, []interface{}{nil, "masked"}, []interface{}{"key", nil}, []interface{}{nil, nil}, []interface{}{"masked"}, "masked", } expected := []interface{}{ []interface{}{ map[string]interface{}{ "outer": []interface{}{"outerValue", true}, "masked": []interface{}{"innerMasking", true}, "key": []interface{}{float64(0), true}, }, }, []interface{}{ map[string]interface{}{ "outer": []interface{}{"outerValue", true}, "masked": []interface{}{"innerMasking", true}, }, }, []interface{}{ map[string]interface{}{ "outer": []interface{}{"outerValue", true}, "masked": []interface{}{"outerMasked", true}, "key": []interface{}{float64(0), true}, }, }, []interface{}{ map[string]interface{}{ "outer": []interface{}{"outerValue", true}, "masked": []interface{}{"outerMasked", true}, }, }, []interface{}{ map[string]interface{}{ "outer": []interface{}{"outerValue", true}, "masked": []interface{}{"innerMasking", true}, }, }, []interface{}{ map[string]interface{}{ "outer": []interface{}{"outerValue", true}, "masked": []interface{}{"innerMasking", true}, }, }, } for i, refNames := range testRefNames { input := interface{}(map[string]interface{}{ "Fn::For": []interface{}{ refNames, []interface{}{"innerMasking"}, "aTemplate", }, }) templateRules := template.Rules{} templateRules.Attach(func(path []interface{}, node interface{}) (interface{}, interface{}) { key := interface{}(nil) if len(path) > 0 { key = path[len(path)-1] } if stringVal, ok := node.(string); !ok || stringVal != "aTemplate" { return key, node } generated := map[string]interface{}{} for binding, _ := range expected[i].([]interface{})[0].(map[string]interface{}) { value, has_key := stack.Get([]string{binding}) generated[binding] = []interface{}{value, has_key} } return key, generated }) fnFor := MakeFnFor(&stack, &templateRules) newKey, newNode := fnFor([]interface{}{"x", "y"}, input) if newKey != "y" { t.Fatalf("FnFor modified the path (%v instead of %v)", newKey, "y") } if !reflect.DeepEqual(newNode, expected[i]) { t.Fatalf("FnFor did not have the correct stack values with refNames %v during templateRule (%#v instead of %#v)", refNames, newNode, expected[i], ) } } }
func TestFnWith_StackWithArray(t *testing.T) { stack := deepstack.DeepStack{} stack.Push(fallbackmap.DeepMap(map[string]interface{}{"outer": "outer-value", "masked": "masked-value"})) input := interface{}(map[string]interface{}{ "Fn::With": []interface{}{ map[string]interface{}{ "masked": "masking-value", "inner": "inner-value", }, map[string]interface{}{ "outer": "replace-with-outer", "masked": "replace-with-masked", "inner": "replace-with-inner", "untouched": "stay-the-same", }, }, }) expected := interface{}(map[string]interface{}{ "outer": "outer-value", "masked": "masking-value", "inner": "inner-value", "untouched": "stay-the-same", }) templateRules := template.Rules{} templateRules.Attach(func(path []interface{}, node interface{}) (interface{}, interface{}) { key := interface{}(nil) if len(path) > 0 { key = path[len(path)-1] } newNode := make(map[string]interface{}) if nodeMap, ok := node.(map[string]interface{}); ok { if _, ok := node.(map[string]interface{})["untouched"]; ok { for key, value := range nodeMap { newValue, hasKey := stack.Get([]string{key}) if hasKey { newNode[key] = newValue } else { newNode[key] = value } } return key, newNode } } return key, node }) fnWith := MakeFnWith(&stack, &templateRules) newKey, newNode := fnWith([]interface{}{"x", "y"}, input) if newKey != "y" { t.Fatalf("FnWith modified the path (%v instead of %v)", newKey, "y") } if !reflect.DeepEqual(newNode, expected) { t.Fatalf("FnWith did not have the correct stack values during templateRule (%#v instead of %#v)", newNode, expected, ) } }