Skip to content

Commit

Permalink
refactor: add comparisons pkg for reused helpers
Browse files Browse the repository at this point in the history
This commit moves the helper functions from
provider.go to a new comparisons package. This
package will be used by provider, tests, and
resources. The refactoring will assist with
splitting resources into resource specific
packages.

The previous helper functions have been deprecated
and will be removed in a future commit.

Signed-off-by: Marques Johansson <[email protected]>
  • Loading branch information
displague authored and ctreatma committed Jul 11, 2024
1 parent f148bf5 commit 2f8c345
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
12 changes: 12 additions & 0 deletions equinix/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ func configureProvider(ctx context.Context, d *schema.ResourceData, p *schema.Pr
return &config, nil
}

// stringsFound returns true if all strings in source are found in target
// Deprecated: stringsFound is shared between provider, tests, and resources
// and is being relocated for package refactoring.
// Use github.com/equinix/terraform-provider-equinix/internal/comparisons.Subsets
func stringsFound(source []string, target []string) bool {
for i := range source {
if !slices.Contains(target, source[i]) {
Expand All @@ -202,6 +206,10 @@ func stringsFound(source []string, target []string) bool {
return true
}

// isEmpty returns true if the value is nil or zero
// Deprecated: isEmpty is shared between provider, tests, and resources
// and is being relocated for package refactoring.
// Use github.com/equinix/terraform-provider-equinix/internal/comparisons.IsEmpty
func isEmpty(v interface{}) bool {
switch v := v.(type) {
case int:
Expand All @@ -219,6 +227,10 @@ func isEmpty(v interface{}) bool {
}
}

// slicesMatch returns true if all strings in s1 are found in s2
// Deprecated: slicesMatch is shared between provider, tests, and resources
// and is being relocated for package refactoring.
// Use github.com/equinix/terraform-provider-equinix/internal/comparisons.SlicesMatch
func slicesMatch(s1, s2 []string) bool {
if len(s1) != len(s2) {
return false
Expand Down
4 changes: 4 additions & 0 deletions equinix/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ func TestProvider(t *testing.T) {
}
}

// Deprecated test moved to internal/comparissons/comparisons_test.go
func TestProvider_stringsFound(t *testing.T) {
// given
needles := []string{"key1", "key5"}
Expand All @@ -81,6 +82,7 @@ func TestProvider_stringsFound(t *testing.T) {
assert.True(t, result, "Given strings were found")
}

// Deprecated test moved to internal/comparissons/comparisons_test.go
func TestProvider_stringsFound_negative(t *testing.T) {
// given
needles := []string{"key1", "key6"}
Expand All @@ -91,6 +93,7 @@ func TestProvider_stringsFound_negative(t *testing.T) {
assert.False(t, result, "Given strings were found")
}

// Deprecated test moved to internal/comparissons/comparisons_test.go
func TestProvider_isEmpty(t *testing.T) {
// given
input := []interface{}{
Expand Down Expand Up @@ -134,6 +137,7 @@ func TestProvider_setSchemaValueIfNotEmpty(t *testing.T) {
assert.False(t, ok, "Key was not set")
}

// Deprecated test moved to internal/comparissons/comparisons_test.go
func TestProvider_slicesMatch(t *testing.T) {
// given
input := [][][]string{
Expand Down
67 changes: 67 additions & 0 deletions internal/comparisons/comparisons.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package comparisons

import (
"cmp"
"slices"
"strings"
)

// isEmpty returns true if the given value is empty
func IsEmpty(v interface{}) bool {
switch v := v.(type) {
case int:
return v == 0
case *int:
return v == nil || *v == 0
case string:
return v == ""
case *string:
return v == nil || *v == ""
case nil:
return true
default:
return false
}
}

// Subsets returns true if the first slice is a subset of the second slice
func Subsets[T cmp.Ordered](s1, s2 []T) bool {
// Iterate over the first slice
for _, e := range s1 {
// If the element is not in the second slice, return false
if !slices.Contains(s2, e) {
return false
}
}

return true
}

// comparisons.SlicesMatch returns true if the two slices contain the same elements, regardless of order
func SlicesMatch[T cmp.Ordered](s1, s2 []T) bool {
if len(s1) != len(s2) {
return false
}

// Create copies of the slices to avoid mutating the input slices
s1Copy := append([]T(nil), s1...)
s2Copy := append([]T(nil), s2...)

// Sort the slices
slices.Sort(s1Copy)
slices.Sort(s2Copy)

return slices.Equal(s1Copy, s2Copy)
}

// caseInsensitiveLess is a comparison function for sorting strings case-insensitively
func caseInsensitiveLess(s1, s2 string) int {
switch {
case strings.ToLower(s1) == strings.ToLower(s2):
return 0
case strings.ToLower(s1) < strings.ToLower(s2):
return -1
default:
return 1
}
}
89 changes: 89 additions & 0 deletions internal/comparisons/comparisons_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package comparisons_test

import (
"testing"

"github.com/equinix/terraform-provider-equinix/internal/comparisons"
"github.com/stretchr/testify/assert"
)

func TestSubsets(t *testing.T) {
// given
needles := []string{"key1", "key5"}
hay := []string{"key1", "key2", "Key3", "key4", "key5"}
// when
result := comparisons.Subsets(needles, hay)
// then
assert.True(t, result, "Given strings were found")
}

func TestSubsets_negative(t *testing.T) {
// given
needles := []string{"key1", "key6"}
hay := []string{"key1", "key2", "Key3", "key4", "key5"}
// when
result := comparisons.Subsets(hay, needles)
// then
assert.False(t, result, "Given strings were found")
}

func TestIsEmpty(t *testing.T) {
// given
input := []interface{}{
"test",
"",
nil,
123,
0,
43.43,
}
expected := []bool{
false,
true,
true,
false,
true,
false,
true,
}
// when then
for i := range input {
assert.Equal(t, expected[i], comparisons.IsEmpty(input[i]), "Input %v produces expected result %v", input[i], expected[i])
}
}

func TestSlicesMatch(t *testing.T) {
// given
input := [][][]string{
{
{"DC", "SV", "FR"},
{"FR", "SV", "DC"},
},
{
{"SV"},
{},
},
{
{"DC", "DC", "DC"},
{"DC", "SV", "DC"},
},
{
{}, {},
},
}
expected := []bool{
true,
false,
false,
true,
}
// when
results := make([]bool, len(expected))
for i := range input {
results[i] = comparisons.SlicesMatch(input[i][0], input[i][1])
}
// then
for i := range expected {
assert.Equal(t, expected[i], results[i])
}
}

0 comments on commit 2f8c345

Please sign in to comment.