github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/views/json/output_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package json 5 6 import ( 7 "encoding/json" 8 "testing" 9 10 "github.com/google/go-cmp/cmp" 11 "github.com/terramate-io/tf/addrs" 12 "github.com/terramate-io/tf/lang/marks" 13 "github.com/terramate-io/tf/plans" 14 "github.com/terramate-io/tf/states" 15 "github.com/zclconf/go-cty/cty" 16 ) 17 18 func TestOutputsFromMap(t *testing.T) { 19 got, diags := OutputsFromMap(map[string]*states.OutputValue{ 20 // Normal non-sensitive output 21 "boop": { 22 Value: cty.NumberIntVal(1234), 23 }, 24 // Sensitive string output 25 "beep": { 26 Value: cty.StringVal("horse-battery").Mark(marks.Sensitive), 27 Sensitive: true, 28 }, 29 // Sensitive object output which is marked at the leaf 30 "blorp": { 31 Value: cty.ObjectVal(map[string]cty.Value{ 32 "a": cty.ObjectVal(map[string]cty.Value{ 33 "b": cty.ObjectVal(map[string]cty.Value{ 34 "c": cty.StringVal("oh, hi").Mark(marks.Sensitive), 35 }), 36 }), 37 }), 38 Sensitive: true, 39 }, 40 // Null value 41 "honk": { 42 Value: cty.NullVal(cty.Map(cty.Bool)), 43 }, 44 }) 45 if len(diags) > 0 { 46 t.Fatal(diags.Err()) 47 } 48 49 want := Outputs{ 50 "boop": { 51 Sensitive: false, 52 Type: json.RawMessage(`"number"`), 53 Value: json.RawMessage(`1234`), 54 }, 55 "beep": { 56 Sensitive: true, 57 Type: json.RawMessage(`"string"`), 58 }, 59 "blorp": { 60 Sensitive: true, 61 Type: json.RawMessage(`["object",{"a":["object",{"b":["object",{"c":"string"}]}]}]`), 62 }, 63 "honk": { 64 Sensitive: false, 65 Type: json.RawMessage(`["map","bool"]`), 66 Value: json.RawMessage(`null`), 67 }, 68 } 69 70 if !cmp.Equal(want, got) { 71 t.Fatalf("unexpected result\n%s", cmp.Diff(want, got)) 72 } 73 } 74 75 func TestOutputsFromChanges(t *testing.T) { 76 root := addrs.RootModuleInstance 77 num, err := plans.NewDynamicValue(cty.NumberIntVal(1234), cty.Number) 78 if err != nil { 79 t.Fatalf("unexpected error creating dynamic value: %v", err) 80 } 81 str, err := plans.NewDynamicValue(cty.StringVal("1234"), cty.String) 82 if err != nil { 83 t.Fatalf("unexpected error creating dynamic value: %v", err) 84 } 85 86 got := OutputsFromChanges([]*plans.OutputChangeSrc{ 87 // Unchanged output "boop", value 1234 88 { 89 Addr: root.OutputValue("boop"), 90 ChangeSrc: plans.ChangeSrc{ 91 Action: plans.NoOp, 92 Before: num, 93 After: num, 94 }, 95 Sensitive: false, 96 }, 97 // New output "beep", value 1234 98 { 99 Addr: root.OutputValue("beep"), 100 ChangeSrc: plans.ChangeSrc{ 101 Action: plans.Create, 102 Before: nil, 103 After: num, 104 }, 105 Sensitive: false, 106 }, 107 // Deleted output "blorp", prior value 1234 108 { 109 Addr: root.OutputValue("blorp"), 110 ChangeSrc: plans.ChangeSrc{ 111 Action: plans.Delete, 112 Before: num, 113 After: nil, 114 }, 115 Sensitive: false, 116 }, 117 // Updated output "honk", prior value 1234, new value "1234" 118 { 119 Addr: root.OutputValue("honk"), 120 ChangeSrc: plans.ChangeSrc{ 121 Action: plans.Update, 122 Before: num, 123 After: str, 124 }, 125 Sensitive: false, 126 }, 127 // New sensitive output "secret", value "1234" 128 { 129 Addr: root.OutputValue("secret"), 130 ChangeSrc: plans.ChangeSrc{ 131 Action: plans.Create, 132 Before: nil, 133 After: str, 134 }, 135 Sensitive: true, 136 }, 137 }) 138 139 want := Outputs{ 140 "boop": { 141 Action: "noop", 142 Sensitive: false, 143 }, 144 "beep": { 145 Action: "create", 146 Sensitive: false, 147 }, 148 "blorp": { 149 Action: "delete", 150 Sensitive: false, 151 }, 152 "honk": { 153 Action: "update", 154 Sensitive: false, 155 }, 156 "secret": { 157 Action: "create", 158 Sensitive: true, 159 }, 160 } 161 162 if !cmp.Equal(want, got) { 163 t.Fatalf("unexpected result\n%s", cmp.Diff(want, got)) 164 } 165 } 166 167 func TestOutputs_String(t *testing.T) { 168 outputs := Outputs{ 169 "boop": { 170 Sensitive: false, 171 Type: json.RawMessage(`"number"`), 172 Value: json.RawMessage(`1234`), 173 }, 174 "beep": { 175 Sensitive: true, 176 Type: json.RawMessage(`"string"`), 177 Value: json.RawMessage(`"horse-battery"`), 178 }, 179 } 180 if got, want := outputs.String(), "Outputs: 2"; got != want { 181 t.Fatalf("unexpected value\n got: %q\nwant: %q", got, want) 182 } 183 }