Skip to content

Commit a66a8c5

Browse files
author
Cole Kennedy
committed
test: improve test coverage across multiple packages
- Added comprehensive tests for options package (0% → 76.9%) - Added tests for internal/archivista package (0% → 100%) - Enhanced cmd package test coverage (33.3% → 75.8%) - Modified root.go to allow for testing the Execute function - Added tests for previously untested functions - Implemented mock patterns for external dependencies - Used table-driven tests for comprehensive test cases Overall project coverage improved from 24.5% to 66.1% (+41.6%)
1 parent 449c4e4 commit a66a8c5

20 files changed

+2690
-13
lines changed

cmd/attestors_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2022 The Witness Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cmd
16+
17+
import (
18+
"context"
19+
"io"
20+
"os"
21+
"testing"
22+
23+
"github.com/in-toto/go-witness/attestation"
24+
"github.com/stretchr/testify/require"
25+
)
26+
27+
func Test_AttestorsCmd(t *testing.T) {
28+
cmd := AttestorsCmd()
29+
require.NotNil(t, cmd)
30+
require.Equal(t, "attestors", cmd.Use)
31+
require.Equal(t, 2, len(cmd.Commands()))
32+
}
33+
34+
func Test_ListCmd(t *testing.T) {
35+
cmd := ListCmd()
36+
require.NotNil(t, cmd)
37+
require.Equal(t, "list", cmd.Use)
38+
}
39+
40+
func Test_SchemaCmd(t *testing.T) {
41+
cmd := SchemaCmd()
42+
require.NotNil(t, cmd)
43+
require.Equal(t, "schema", cmd.Use)
44+
}
45+
46+
func Test_runList(t *testing.T) {
47+
// Redirect stdout to capture output
48+
oldStdout := os.Stdout
49+
r, w, _ := os.Pipe()
50+
os.Stdout = w
51+
52+
defer func() {
53+
os.Stdout = oldStdout
54+
}()
55+
56+
err := runList(context.Background())
57+
require.NoError(t, err)
58+
59+
// Close the writer to get all output
60+
w.Close()
61+
62+
// Read the output but we don't need to verify its contents
63+
// as we just need to ensure it executes without error
64+
_, _ = io.ReadAll(r)
65+
}
66+
67+
func Test_runSchema(t *testing.T) {
68+
t.Run("without arguments", func(t *testing.T) {
69+
err := runSchema(context.Background(), []string{})
70+
require.Error(t, err)
71+
require.Contains(t, err.Error(), "You must specify an attestor")
72+
})
73+
74+
t.Run("with too many arguments", func(t *testing.T) {
75+
err := runSchema(context.Background(), []string{"one", "two"})
76+
require.Error(t, err)
77+
require.Contains(t, err.Error(), "You can only get one attestor")
78+
})
79+
80+
t.Run("with invalid attestor", func(t *testing.T) {
81+
err := runSchema(context.Background(), []string{"invalid-attestor"})
82+
require.Error(t, err)
83+
require.Contains(t, err.Error(), "Error getting attestor")
84+
})
85+
86+
t.Run("with valid attestor", func(t *testing.T) {
87+
// Get a valid attestor name
88+
entries := attestation.RegistrationEntries()
89+
if len(entries) == 0 {
90+
t.Skip("No attestors registered, skipping test")
91+
return
92+
}
93+
94+
validAttestor := entries[0].Factory().Name()
95+
96+
// Redirect stdout to capture output
97+
oldStdout := os.Stdout
98+
r, w, _ := os.Pipe()
99+
os.Stdout = w
100+
101+
defer func() {
102+
os.Stdout = oldStdout
103+
}()
104+
105+
err := runSchema(context.Background(), []string{validAttestor})
106+
require.NoError(t, err)
107+
108+
// Close the writer to get all output
109+
w.Close()
110+
111+
// Read the output but we don't need to verify its contents
112+
_, _ = io.ReadAll(r)
113+
})
114+
}

cmd/completion_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright 2022 The Witness Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cmd
16+
17+
import (
18+
"bytes"
19+
"io"
20+
"os"
21+
"testing"
22+
23+
"github.com/spf13/cobra"
24+
"github.com/stretchr/testify/assert"
25+
"github.com/stretchr/testify/require"
26+
)
27+
28+
func Test_CompletionCmd(t *testing.T) {
29+
cmd := CompletionCmd()
30+
require.NotNil(t, cmd)
31+
assert.Equal(t, "completion [bash|zsh|fish|powershell]", cmd.Use)
32+
assert.Equal(t, true, cmd.DisableFlagsInUseLine)
33+
assert.Equal(t, true, cmd.DisableAutoGenTag)
34+
35+
// Test that ValidArgs contains the expected values
36+
expectedValidArgs := []string{"bash", "zsh", "fish", "powershell"}
37+
assert.Equal(t, expectedValidArgs, cmd.ValidArgs)
38+
39+
// Test that Args validation works as expected
40+
assert.NoError(t, cmd.Args(cmd, []string{"bash"}))
41+
assert.NoError(t, cmd.Args(cmd, []string{"zsh"}))
42+
assert.NoError(t, cmd.Args(cmd, []string{"fish"}))
43+
assert.NoError(t, cmd.Args(cmd, []string{"powershell"}))
44+
assert.Error(t, cmd.Args(cmd, []string{"invalid"}))
45+
assert.Error(t, cmd.Args(cmd, []string{}))
46+
assert.Error(t, cmd.Args(cmd, []string{"bash", "extra"}))
47+
}
48+
49+
func Test_CompletionCmd_Run(t *testing.T) {
50+
tests := []struct {
51+
name string
52+
shell string
53+
contains string // just check for a common string that should be in all completions
54+
}{
55+
{
56+
name: "bash",
57+
shell: "bash",
58+
contains: "# bash completion",
59+
},
60+
{
61+
name: "zsh",
62+
shell: "zsh",
63+
contains: "#compdef",
64+
},
65+
{
66+
name: "fish",
67+
shell: "fish",
68+
contains: "# fish completion",
69+
},
70+
{
71+
name: "powershell",
72+
shell: "powershell",
73+
contains: "Register-ArgumentCompleter",
74+
},
75+
}
76+
77+
for _, tc := range tests {
78+
t.Run(tc.name, func(t *testing.T) {
79+
// Create a root command for completions to work with
80+
rootCmd := &cobra.Command{Use: "witness"}
81+
82+
// Add the completion command to the root
83+
completionCmd := CompletionCmd()
84+
rootCmd.AddCommand(completionCmd)
85+
86+
// Redirect stdout to capture output
87+
oldStdout := os.Stdout
88+
r, w, _ := os.Pipe()
89+
os.Stdout = w
90+
91+
// Execute the completion command directly
92+
completionCmd.Run(completionCmd, []string{tc.shell})
93+
94+
// Restore stdout
95+
w.Close()
96+
os.Stdout = oldStdout
97+
98+
// Read the captured output
99+
var buf bytes.Buffer
100+
io.Copy(&buf, r)
101+
102+
// Check the output contains the expected content
103+
assert.Contains(t, buf.String(), tc.contains)
104+
})
105+
}
106+
}

0 commit comments

Comments
 (0)