diff --git a/internal/addrs/module_call.go b/internal/addrs/module_call.go index 162b05a6f6be..95a8fb603da8 100644 --- a/internal/addrs/module_call.go +++ b/internal/addrs/module_call.go @@ -210,3 +210,28 @@ func (co ModuleCallInstanceOutput) AbsOutputValue(caller ModuleInstance) AbsOutp moduleAddr := co.Call.ModuleInstance(caller) return moduleAddr.OutputValue(co.Name) } + +type AbsModuleCallOutput struct { + Call AbsModuleCall + Name string +} + +func (c AbsModuleCall) Output(name string) AbsModuleCallOutput { + return AbsModuleCallOutput{ + Call: c, + Name: name, + } +} + +func (m AbsModuleCallOutput) ConfigOutputValue() ConfigOutputValue { + return ConfigOutputValue{ + Module: m.Call.StaticModule(), + OutputValue: OutputValue{ + Name: m.Name, + }, + } +} + +func (co AbsModuleCallOutput) String() string { + return fmt.Sprintf("%s.%s", co.Call.String(), co.Name) +} diff --git a/internal/addrs/module_call_test.go b/internal/addrs/module_call_test.go new file mode 100644 index 000000000000..69c287e62e0a --- /dev/null +++ b/internal/addrs/module_call_test.go @@ -0,0 +1,88 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package addrs + +import ( + "testing" +) + +func TestAbsModuleCallOutput(t *testing.T) { + testCases := map[string]struct { + input AbsModuleCall + expected string + }{ + "simple": { + input: AbsModuleCall{ + Module: ModuleInstance{}, + Call: ModuleCall{ + Name: "hello", + }, + }, + expected: "module.hello.foo", + }, + "nested": { + input: AbsModuleCall{ + Module: ModuleInstance{ + ModuleInstanceStep{ + Name: "child", + InstanceKey: NoKey, + }, + }, + Call: ModuleCall{ + Name: "hello", + }, + }, + expected: "module.child.module.hello.foo", + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + output := tc.input.Output("foo") + if output.String() != tc.expected { + t.Errorf("expected %s, got %s", tc.expected, output.String()) + } + }) + } +} + +func TestAbsModuleCallOutput_ConfigOutputValue(t *testing.T) { + testCases := map[string]struct { + input AbsModuleCall + expected string + }{ + "simple": { + input: AbsModuleCall{ + Module: ModuleInstance{}, + Call: ModuleCall{ + Name: "hello", + }, + }, + expected: "module.hello.output.foo", + }, + "nested": { + input: AbsModuleCall{ + Module: ModuleInstance{ + ModuleInstanceStep{ + Name: "child", + InstanceKey: NoKey, + }, + }, + Call: ModuleCall{ + Name: "hello", + }, + }, + expected: "module.child.module.hello.output.foo", + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + output := tc.input.Output("foo").ConfigOutputValue() + if output.String() != tc.expected { + t.Errorf("expected %s, got %s", tc.expected, output.String()) + } + }) + } +}