diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index baa674c..eaae1a4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,6 +7,15 @@ on: - main jobs: + tests: + name: "Tests" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 + with: + go-version: '1.21' + - run: . scripts/test integration-tests: name: "Integration tests" runs-on: ubuntu-latest diff --git a/go.mod b/go.mod index 40572b4..1b28fe2 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,9 @@ module v go 1.21.1 + +require ( + golang.org/x/sys v0.4.0 // indirect + golang.org/x/tools v0.5.1-0.20230111220935-a7f7db3f17fc // indirect + golang.org/x/tools/cmd/cover v0.1.0-deprecated // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..efba48e --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/tools v0.5.1-0.20230111220935-a7f7db3f17fc h1:zRn9MzwG18RZhyanShCfUwJTcobvqw8fOjjROFN9jtM= +golang.org/x/tools v0.5.1-0.20230111220935-a7f7db3f17fc/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= +golang.org/x/tools/cmd/cover v0.1.0-deprecated h1:Rwy+mWYz6loAF+LnG1jHG/JWMHRMMC2/1XX3Ejkx9lA= +golang.org/x/tools/cmd/cover v0.1.0-deprecated/go.mod h1:hMDiIvlpN1NoVgmjLjUJE9tMHyxHjFX7RuQ+rW12mSA= diff --git a/scripts/test b/scripts/test new file mode 100644 index 0000000..607b7a6 --- /dev/null +++ b/scripts/test @@ -0,0 +1,4 @@ +#!/bin/bash + +go get golang.org/x/tools/cmd/cover +go test -cover -v diff --git a/state_test.go b/state_test.go new file mode 100644 index 0000000..9b205e7 --- /dev/null +++ b/state_test.go @@ -0,0 +1,67 @@ +package main + +import ( + "encoding/json" + "io/ioutil" + "os" + "path" + "testing" +) + +// If an override is provided via V_ROOT, it's used as state path. +func TestGetStatePathUsesEnvVRootOverride(t *testing.T) { + MOCK_ROOT_PATH := "/overriden_path_to_state" + os.Setenv("V_ROOT", MOCK_ROOT_PATH) + defer os.Unsetenv("V_ROOT") + if statePath := GetStatePath(); statePath != MOCK_ROOT_PATH { + t.Errorf("Did not find expected state path %s, found %s instead.", MOCK_ROOT_PATH, statePath) + } +} + +// If no override is provided via V_ROOT, $HOME/.v is used. +func TestGetStatePathUsesHomeDefaultIfNoOverride(t *testing.T) { + home, _ := os.UserHomeDir() + + expected := path.Join(home, ".v") + if statePath := GetStatePath(); statePath != expected { + t.Errorf("Did not find expected state path %s, found %s instead.", expected, statePath) + } +} + +// State is read from the state path and returned by ReadState. +func TestReadStateReadsStateAtPath(t *testing.T) { + tempFolder, _ := os.MkdirTemp("", "v_test") + defer os.RemoveAll(tempFolder) + os.Setenv("V_ROOT", tempFolder) + defer os.Unsetenv("V_ROOT") + + mockState := State{GlobalVersion: "1.0.0"} + statePath := GetStatePath("state.json") + stateData, _ := json.Marshal(mockState) + ioutil.WriteFile(statePath, stateData, 0750) + + readState := ReadState() + + if readState != mockState { + t.Errorf("Did not find expected state. %v != %v", mockState, readState) + } +} + +func TestWriteStateWritesAtPath(t *testing.T) { + tempFolder, _ := os.MkdirTemp("", "v_test") + defer os.RemoveAll(tempFolder) + os.Setenv("V_ROOT", tempFolder) + defer os.Unsetenv("V_ROOT") + + mockState := State{GlobalVersion: "2.0.0"} + WriteState(mockState.GlobalVersion) + + statePath := GetStatePath("state.json") + readState := State{} + bytes, _ := ioutil.ReadFile(statePath) + json.Unmarshal(bytes, &readState) + + if readState != mockState { + t.Errorf("Did not find expected state. %v != %v", mockState, readState) + } +}