|
1 | 1 | package main
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
4 | 5 | "flag"
|
5 | 6 | "fmt"
|
6 | 7 | "os"
|
7 | 8 | "path/filepath"
|
8 | 9 | "strings"
|
9 | 10 | "testing"
|
10 | 11 |
|
| 12 | + "github.com/hexops/autogold/v2" |
11 | 13 | "github.com/stretchr/testify/require"
|
| 14 | + "golang.org/x/exp/slices" |
12 | 15 |
|
13 | 16 | "github.com/sourcegraph/scip/bindings/go/scip"
|
14 | 17 | "github.com/sourcegraph/scip/bindings/go/scip/testutil"
|
@@ -101,3 +104,115 @@ func TestSCIPSnapshots(t *testing.T) {
|
101 | 104 | return snapshots
|
102 | 105 | })
|
103 | 106 | }
|
| 107 | + |
| 108 | +func unwrap[T any](v T, err error) func(*testing.T) T { |
| 109 | + return func(t *testing.T) T { |
| 110 | + require.NoError(t, err) |
| 111 | + return v |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +func TestSCIPTests(t *testing.T) { |
| 116 | + cwd := unwrap(os.Getwd())(t) |
| 117 | + testDir := filepath.Join(cwd, "tests", "test_cmd") |
| 118 | + testPaths := unwrap(os.ReadDir(testDir))(t) |
| 119 | + require.Truef(t, len(testPaths) >= 1, "Expected at least one test case in directory: %v", testDir) |
| 120 | + |
| 121 | + os.Setenv("NO_COLOR", "1") |
| 122 | + t.Cleanup(func() { |
| 123 | + os.Unsetenv("NO_COLOR") |
| 124 | + }) |
| 125 | + |
| 126 | + type TestCase struct { |
| 127 | + dir string |
| 128 | + passOutput autogold.Value |
| 129 | + failOutput autogold.Value |
| 130 | + } |
| 131 | + |
| 132 | + // To update the snapshot values, run 'go test ./cmd/scip -update'. |
| 133 | + testCases := []TestCase{ |
| 134 | + {"roles", |
| 135 | + autogold.Expect("✓ passes.repro (3 assertions)\n"), |
| 136 | + autogold.Expect(`✗ fails-wrong-role.repro |
| 137 | + Failure - row: 0, column: 13 |
| 138 | + Expected: 'reference reprolang repro_manager roles 1.0.0 fails-wrong-role.repro/hello().' |
| 139 | + Actual: |
| 140 | + - 'definition reprolang repro_manager roles 1.0.0 fails-wrong-role.repro/hello().'✗ fails-wrong-symbol.repro |
| 141 | + Failure - row: 0, column: 13 |
| 142 | + Expected: 'definition reprolang repro_manager roles 1.0.0 fails-wrong-role.repro/hello2().' |
| 143 | + Actual: |
| 144 | + - 'definition reprolang repro_manager roles 1.0.0 fails-wrong-symbol.repro/hello().'`), |
| 145 | + }, |
| 146 | + {"ranges", |
| 147 | + autogold.Expect("✓ passes.repro (3 assertions)\n"), |
| 148 | + autogold.Expect(`✗ fails.repro |
| 149 | + Failure - row: 0, column: 10 |
| 150 | + Expected: 'definition passes.repro/hello().' |
| 151 | + Actual: |
| 152 | + - No attributes found`), |
| 153 | + }, |
| 154 | + {"diagnostics", |
| 155 | + autogold.Expect("✓ passes.repro (2 assertions)\n"), |
| 156 | + autogold.Expect(`✗ fails-incorrect-diagnostic.repro |
| 157 | + Failure - row: 0, column: 11 |
| 158 | + Expected: 'diagnostic Warning:' |
| 159 | + 'THIS IS NOT CORRECT' |
| 160 | + Actual: |
| 161 | + - 'definition reprolang repro_manager diagnostics 1.0.0 fails-incorrect-diagnostic.repro/deprecatedMethod.' |
| 162 | + - 'diagnostic Warning' |
| 163 | + 'deprecated identifier'✗ fails-no-diagnostic.repro |
| 164 | + Failure - row: 0, column: 11 |
| 165 | + Expected: 'diagnostic Warning:' |
| 166 | + 'deprecated identifier' |
| 167 | + Actual: |
| 168 | + - 'definition reprolang repro_manager diagnostics 1.0.0 fails-no-diagnostic.repro/hello().'`), |
| 169 | + }, |
| 170 | + } |
| 171 | + |
| 172 | + for _, testPath := range testPaths { |
| 173 | + require.Truef(t, slices.ContainsFunc(testCases, func(testCase TestCase) bool { |
| 174 | + return testCase.dir == testPath.Name() |
| 175 | + }), "Missing entry in testOutputs for %q", testPath.Name()) |
| 176 | + } |
| 177 | + |
| 178 | + for _, testCase := range testCases { |
| 179 | + var dirEntry os.DirEntry |
| 180 | + require.Truef(t, slices.ContainsFunc(testPaths, func(entry os.DirEntry) bool { |
| 181 | + if entry.Name() == testCase.dir { |
| 182 | + dirEntry = entry |
| 183 | + return true |
| 184 | + } |
| 185 | + return false |
| 186 | + }), "Stale entry in testOutputs for %q; did you rename or remove the directory", testCase.dir) |
| 187 | + |
| 188 | + subtestDir := filepath.Join(testDir, dirEntry.Name()) |
| 189 | + require.Truef(t, dirEntry.IsDir(), "not a directory: %q", subtestDir) |
| 190 | + |
| 191 | + t.Run(testCase.dir, func(t *testing.T) { |
| 192 | + sources := unwrap(scip.NewSourcesFromDirectory(subtestDir))(t) |
| 193 | + index := unwrap(repro.Index("file:/"+subtestDir, dirEntry.Name(), sources, []*repro.Dependency{}))(t) |
| 194 | + |
| 195 | + var passFiles, failFiles []string |
| 196 | + testFiles := unwrap(os.ReadDir(subtestDir))(t) |
| 197 | + for _, testFile := range testFiles { |
| 198 | + if strings.HasPrefix(testFile.Name(), "passes") { |
| 199 | + passFiles = append(passFiles, testFile.Name()) |
| 200 | + } else if strings.HasPrefix(testFile.Name(), "fails") { |
| 201 | + failFiles = append(failFiles, testFile.Name()) |
| 202 | + } else { |
| 203 | + t.Fatalf("Test files must start with 'passes' or 'fails'. Received %v", testFile.Name()) |
| 204 | + } |
| 205 | + } |
| 206 | + |
| 207 | + var passOutput bytes.Buffer |
| 208 | + err := testMain(subtestDir, passFiles, index, "#", &passOutput) |
| 209 | + require.NoError(t, err) |
| 210 | + testCase.passOutput.Equal(t, passOutput.String()) |
| 211 | + |
| 212 | + var failOutput bytes.Buffer |
| 213 | + err = testMain(subtestDir, failFiles, index, "#", &failOutput) |
| 214 | + require.Error(t, err) |
| 215 | + testCase.failOutput.Equal(t, failOutput.String()) |
| 216 | + }) |
| 217 | + } |
| 218 | +} |
0 commit comments