Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fheinecke committed Nov 26, 2024
1 parent 0042f04 commit c0b1c39
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 6 deletions.
25 changes: 19 additions & 6 deletions tools/env-loader/cmd/env-loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"log"
"maps"
"os"
"slices"

"github.com/alecthomas/kingpin/v2"
Expand All @@ -30,6 +31,9 @@ import (

const EnvVarPrefix = "ENV_LOADER_"

// This is a package-level var to assist with capturing stdout in tests
var outputPrinter = fmt.Print

type config struct {
EnvironmentsDirectory string
Environment string
Expand All @@ -38,7 +42,7 @@ type config struct {
Writer string
}

func parseCLI() *config {
func parseCLI(args []string) *config {
c := &config{}

kingpin.Flag("environments-directory", "Path to the directory containing all environments, defaulting to the repo root").
Expand Down Expand Up @@ -68,12 +72,12 @@ func parseCLI() *config {
Default("dotenv").
EnumVar(&c.Writer, slices.Collect(maps.Keys(writers.FromName))...)

kingpin.Parse()
kingpin.CommandLine.Parse(args)

return c
}

func run(c *config) error {
func getRequestedEnvValues(c *config) (map[string]string, error) {
// Load in values
var envValues map[string]string
var err error
Expand All @@ -84,7 +88,7 @@ func run(c *config) error {
}

if err != nil {
return trace.Wrap(err, "failed to load all environment values")
return nil, trace.Wrap(err, "failed to load all environment values")
}

// Filter out values not requested
Expand All @@ -94,6 +98,15 @@ func run(c *config) error {
})
}

return envValues, nil
}

func run(c *config) error {
envValues, err := getRequestedEnvValues(c)
if err != nil {
return trace.Wrap(err, "failed to get requested environment values")
}

// Build the output string
writer := writers.FromName[c.Writer]
envValueOutput, err := writer.FormatEnvironmentValues(envValues)
Expand All @@ -102,12 +115,12 @@ func run(c *config) error {
}

// Write it to stdout
fmt.Print(envValueOutput)
outputPrinter(envValueOutput)
return nil
}

func main() {
c := parseCLI()
c := parseCLI(os.Args[1:])

err := run(c)
if err != nil {
Expand Down
135 changes: 135 additions & 0 deletions tools/env-loader/cmd/env-loader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package main

import (
"bytes"
"fmt"
"path/filepath"
"slices"
"testing"

"github.com/alecthomas/kingpin/v2"
"github.com/stretchr/testify/require"
)

func TestParseCli(t *testing.T) {
parseCLI([]string{})

flags := kingpin.CommandLine.Model().Flags
flagEnvVars := make([]string, 0, len(flags))
for _, flag := range flags {
if flag.Envar != "" {
flagEnvVars = append(flagEnvVars, flag.Envar)
}
}

uniqueFlagEnvVars := slices.Compact(slices.Clone(flagEnvVars))

require.ElementsMatch(t, flagEnvVars, uniqueFlagEnvVars, "not all flag env vars are unique")
}

func TestGetRequestedEnvValues(t *testing.T) {
tests := []struct {
desc string
c *config
expectedValues map[string]string
}{
{
desc: "specific values",
c: &config{
EnvironmentsDirectory: filepath.Join("..", "pkg", "testdata", "repos", "basic repo", ".environments"),
Environment: "env1",
ValueSets: []string{
"testing1",
},
Values: []string{
"setLevel",
"envLevelCommon1",
},
},
expectedValues: map[string]string{
"setLevel": "set level",
"envLevelCommon1": "env level",
},
},
{
desc: "full value set",
c: &config{
EnvironmentsDirectory: filepath.Join("..", "pkg", "testdata", "repos", "basic repo", ".environments"),
Environment: "env1",
ValueSets: []string{
"testing1",
},
},
expectedValues: map[string]string{
"setLevel": "set level",
"setLevelCommon": "testing1 level",
"envLevelCommon1": "env level",
"envLevelCommon2": "set level",
"topLevelCommon1": "top level",
"topLevelCommon2": "env level",
},
},
{
desc: "specific env",
c: &config{
EnvironmentsDirectory: filepath.Join("..", "pkg", "testdata", "repos", "basic repo", ".environments"),
Environment: "env1",
},
expectedValues: map[string]string{
"envLevelCommon1": "env level",
"envLevelCommon2": "env level",
"topLevelCommon1": "top level",
"topLevelCommon2": "env level",
},
},
}

for _, test := range tests {
actualValues, err := getRequestedEnvValues(test.c)
require.NoError(t, err)
require.EqualValues(t, actualValues, test.expectedValues)
}
}

func TestRun(t *testing.T) {
tests := []struct {
desc string
c *config
expectedOutput string
}{
{
desc: "specific values",
c: &config{
EnvironmentsDirectory: filepath.Join("..", "pkg", "testdata", "repos", "basic repo", ".environments"),
Environment: "env1",
ValueSets: []string{
"testing1",
},
Values: []string{
"setLevel",
"envLevelCommon1",
},
Writer: "dotenv",
},
expectedOutput: "envLevelCommon1=env level\nsetLevel=set level\n",
},
}

for _, test := range tests {
// Setup to capture stdout
var output bytes.Buffer
var writtenLength int
var capturedErr error
outputPrinter = func(a ...any) (n int, err error) {
writtenLength, capturedErr = fmt.Fprint(&output, a...)
return writtenLength, capturedErr
}

err := run(test.c)

require.NoError(t, err)
require.NoError(t, capturedErr)
require.Equal(t, writtenLength, len(test.expectedOutput))
require.Equal(t, output.String(), test.expectedOutput)
}
}
11 changes: 11 additions & 0 deletions tools/env-loader/pkg/envloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ func ensureGitFSObjectsExist(t *testing.T) {
return os.WriteFile(gitPath, nil, 0400)
})

ensureGitFSObjectExist(t, "git repo with submodule", "directory", createGitFile)
ensureGitFSObjectExist(t, filepath.Join("git repo with submodule", "submodule"), "file", func(gitPath string) error {
// This path doesn't (currently) actually need to be created
return os.WriteFile(gitPath, []byte("gitdir: ../.git/modules/submodule\n"), 0400)
})

ensureGitFSObjectExist(t, "nested repos", "directory", createGitFile)
ensureGitFSObjectExist(t, filepath.Join("nested repos", "subdirectory"), "directory", createGitFile)
}
Expand Down Expand Up @@ -101,6 +107,11 @@ func TestFindGitRepoRoot(t *testing.T) {
workingDirectory: filepath.Join("nested repos", "subdirectory"),
expectedRoot: filepath.Join("nested repos", "subdirectory"),
},
{
desc: "from submodule",
workingDirectory: filepath.Join("git repo with submodule", "submodule"),
expectedRoot: filepath.Join("git repo with submodule", "submodule"),
},
}

reposDirectory := getTestDataDir(t, "repos")
Expand Down
Empty file.

0 comments on commit c0b1c39

Please sign in to comment.