github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/views/show_test.go (about) 1 package views 2 3 import ( 4 "encoding/json" 5 "strings" 6 "testing" 7 8 "github.com/hashicorp/terraform/internal/addrs" 9 "github.com/hashicorp/terraform/internal/command/arguments" 10 "github.com/hashicorp/terraform/internal/configs/configschema" 11 "github.com/hashicorp/terraform/internal/initwd" 12 "github.com/hashicorp/terraform/internal/plans" 13 "github.com/hashicorp/terraform/internal/states" 14 "github.com/hashicorp/terraform/internal/states/statefile" 15 "github.com/hashicorp/terraform/internal/terminal" 16 "github.com/hashicorp/terraform/internal/terraform" 17 18 "github.com/zclconf/go-cty/cty" 19 ) 20 21 func TestShowHuman(t *testing.T) { 22 testCases := map[string]struct { 23 plan *plans.Plan 24 stateFile *statefile.File 25 schemas *terraform.Schemas 26 wantExact bool 27 wantString string 28 }{ 29 "plan file": { 30 testPlan(t), 31 nil, 32 testSchemas(), 33 false, 34 "# test_resource.foo will be created", 35 }, 36 "statefile": { 37 nil, 38 &statefile.File{ 39 Serial: 0, 40 Lineage: "fake-for-testing", 41 State: testState(), 42 }, 43 testSchemas(), 44 false, 45 "# test_resource.foo:", 46 }, 47 "empty statefile": { 48 nil, 49 &statefile.File{ 50 Serial: 0, 51 Lineage: "fake-for-testing", 52 State: states.NewState(), 53 }, 54 testSchemas(), 55 true, 56 "The state file is empty. No resources are represented.\n", 57 }, 58 "nothing": { 59 nil, 60 nil, 61 nil, 62 true, 63 "No state.\n", 64 }, 65 } 66 for name, testCase := range testCases { 67 t.Run(name, func(t *testing.T) { 68 streams, done := terminal.StreamsForTesting(t) 69 view := NewView(streams) 70 view.Configure(&arguments.View{NoColor: true}) 71 v := NewShow(arguments.ViewHuman, view) 72 73 code := v.Display(nil, testCase.plan, testCase.stateFile, testCase.schemas) 74 if code != 0 { 75 t.Errorf("expected 0 return code, got %d", code) 76 } 77 78 output := done(t) 79 got := output.Stdout() 80 want := testCase.wantString 81 if (testCase.wantExact && got != want) || (!testCase.wantExact && !strings.Contains(got, want)) { 82 t.Fatalf("unexpected output\ngot: %s\nwant: %s", got, want) 83 } 84 }) 85 } 86 } 87 88 func TestShowJSON(t *testing.T) { 89 testCases := map[string]struct { 90 plan *plans.Plan 91 stateFile *statefile.File 92 }{ 93 "plan file": { 94 testPlan(t), 95 nil, 96 }, 97 "statefile": { 98 nil, 99 &statefile.File{ 100 Serial: 0, 101 Lineage: "fake-for-testing", 102 State: testState(), 103 }, 104 }, 105 "empty statefile": { 106 nil, 107 &statefile.File{ 108 Serial: 0, 109 Lineage: "fake-for-testing", 110 State: states.NewState(), 111 }, 112 }, 113 "nothing": { 114 nil, 115 nil, 116 }, 117 } 118 119 config, _, configCleanup := initwd.MustLoadConfigForTests(t, "./testdata/show") 120 defer configCleanup() 121 122 for name, testCase := range testCases { 123 t.Run(name, func(t *testing.T) { 124 streams, done := terminal.StreamsForTesting(t) 125 view := NewView(streams) 126 view.Configure(&arguments.View{NoColor: true}) 127 v := NewShow(arguments.ViewJSON, view) 128 129 schemas := &terraform.Schemas{ 130 Providers: map[addrs.Provider]*terraform.ProviderSchema{ 131 addrs.NewDefaultProvider("test"): { 132 ResourceTypes: map[string]*configschema.Block{ 133 "test_resource": { 134 Attributes: map[string]*configschema.Attribute{ 135 "id": {Type: cty.String, Optional: true, Computed: true}, 136 "foo": {Type: cty.String, Optional: true}, 137 }, 138 }, 139 }, 140 }, 141 }, 142 } 143 144 code := v.Display(config, testCase.plan, testCase.stateFile, schemas) 145 146 if code != 0 { 147 t.Errorf("expected 0 return code, got %d", code) 148 } 149 150 // Make sure the result looks like JSON; we comprehensively test 151 // the structure of this output in the command package tests. 152 var result map[string]interface{} 153 got := done(t).All() 154 t.Logf("output: %s", got) 155 if err := json.Unmarshal([]byte(got), &result); err != nil { 156 t.Fatal(err) 157 } 158 }) 159 } 160 } 161 162 // testState returns a test State structure. 163 func testState() *states.State { 164 return states.BuildState(func(s *states.SyncState) { 165 s.SetResourceInstanceCurrent( 166 addrs.Resource{ 167 Mode: addrs.ManagedResourceMode, 168 Type: "test_resource", 169 Name: "foo", 170 }.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance), 171 &states.ResourceInstanceObjectSrc{ 172 AttrsJSON: []byte(`{"id":"bar","foo":"value"}`), 173 Status: states.ObjectReady, 174 }, 175 addrs.AbsProviderConfig{ 176 Provider: addrs.NewDefaultProvider("test"), 177 Module: addrs.RootModule, 178 }, 179 ) 180 // DeepCopy is used here to ensure our synthetic state matches exactly 181 // with a state that will have been copied during the command 182 // operation, and all fields have been copied correctly. 183 }).DeepCopy() 184 }