blob: e469b54a0e74eb4117a6523517b862dd50cf9235 [file] [edit]
// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package planning
import (
"bufio"
"fmt"
"math"
"strings"
"github.com/opentofu/opentofu/internal/addrs"
"github.com/opentofu/opentofu/internal/engine/internal/execgraph"
)
func newExecGraphBuilderForTesting() *execGraphBuilder {
var placeholderDeposedKey uint32
return &execGraphBuilder{
lower: execgraph.NewBuilder(),
makeDeposedKey: func(_ addrs.AbsResourceInstance) addrs.DeposedKey {
// For testing purposes we just allocate sequential integers
// so that we have predictable keys to include in the expected
// output of each test.
placeholderDeposedKey++
return addrs.DeposedKey(fmt.Sprintf("%08x", placeholderDeposedKey))
},
}
}
// stripCommonLeadingTabs is a helper for tests that include constant strings
// for comparison with the result of a [Graph.DebugRepr] call, so that we can
// write the constant strings indentation to fit well with the surrounding
// context while ignoring the extra leading tabs that causes.
//
// This only considers tabs -- ignoring any other kind of whitespace -- because
// this is narrowly focused only on test code indentation and we always indent
// code using tabs.
func stripCommonLeadingTabs(s string) string {
// We work in two passes here: first we scan over and find the smallest
// number of leading tabs that all of the lines of the string have in
// common, and then we do a second pass to build a new string with that
// many leading tabs removed from each line.
sc := bufio.NewScanner(strings.NewReader(s))
sc.Split(bufio.ScanLines)
minTabCount := math.MaxInt
for sc.Scan() {
line := sc.Text()
trimmed := strings.TrimLeft(line, "\t")
if len(strings.TrimSpace(trimmed)) == 0 {
continue // empty lines and lines containing only whitespace are ignored
}
tabCount := len(line) - len(trimmed)
if tabCount < minTabCount {
minTabCount = tabCount
}
}
// (No error check because strings.Reader reads cannot fail)
if minTabCount == math.MaxInt {
// If minTabCount is still the max then that suggests we didn't have
// any non-empty lines at all, and so there's nothing useful we can do
// here.
return ""
}
trimmedPrefix := strings.Repeat("\t", minTabCount)
var buf strings.Builder
sc = bufio.NewScanner(strings.NewReader(s))
sc.Split(bufio.ScanLines)
for sc.Scan() {
// No error check because strings.Builder writes cannot fail.
buf.WriteString(strings.TrimPrefix(sc.Text(), trimmedPrefix))
buf.WriteByte('\n')
}
// (No error check because strings.Reader reads cannot fail)
return buf.String()
}