Skip to content

Commit 3926fbd

Browse files
Revert of revert with downgrade to Go1.19 (exercism#102)
* Bring changes back except go 1.20 test changes * Downgrade to Go 1.19 * Make output of test added after 1.20 to match output of 1.19 * Update setup-go
1 parent 76c4635 commit 3926fbd

File tree

17 files changed

+388
-173
lines changed

17 files changed

+388
-173
lines changed

Diff for: .github/workflows/test.yml

+34-36
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,53 @@ name: Run linter and tests
33
on: [push, pull_request, workflow_dispatch]
44

55
jobs:
6-
76
lint:
87
runs-on: ubuntu-latest
98
steps:
10-
- name: Install Go
11-
uses: actions/setup-go@b22fbbc2921299758641fab08929b4ac52b32923
12-
with:
13-
go-version: 1.18.x
14-
- name: Checkout code
15-
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
16-
- name: Run linters
17-
uses: golangci/golangci-lint-action@v3
18-
with:
19-
version: v1.51
9+
- name: Install Go
10+
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9
11+
with:
12+
go-version: 1.19.x
13+
- name: Checkout code
14+
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
15+
- name: Run linters
16+
uses: golangci/golangci-lint-action@v3
17+
with:
18+
version: v1.51
2019

2120
test:
2221
strategy:
2322
matrix:
24-
go-version: [1.18.x]
2523
platform: [ubuntu-latest, windows-latest]
2624
runs-on: ${{ matrix.platform }}
2725
steps:
28-
- name: Install Go
29-
if: success()
30-
uses: actions/setup-go@b22fbbc2921299758641fab08929b4ac52b32923
31-
with:
32-
go-version: 1.18.x
33-
- name: Checkout code
34-
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
35-
- name: Run tests
36-
run: go test ./... -v -covermode=count
26+
- name: Install Go
27+
if: success()
28+
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9
29+
with:
30+
go-version: 1.19.x
31+
- name: Checkout code
32+
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
33+
- name: Run tests
34+
run: go test ./... -v -covermode=count
3735

3836
coverage:
3937
runs-on: ubuntu-latest
4038
steps:
41-
- name: Install Go
42-
if: success()
43-
uses: actions/setup-go@b22fbbc2921299758641fab08929b4ac52b32923
44-
with:
45-
go-version: 1.18.x
46-
- name: Checkout code
47-
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
48-
- name: Calc coverage
49-
run: |
50-
go test ./... -v -covermode=count -coverprofile=coverage.out
51-
- name: Convert coverage.out to coverage.lcov
52-
uses: jandelgado/gcov2lcov-action@c680c0f7c7442485f1749eb2a13e54a686e76eb5
53-
- name: Coveralls
54-
uses: coverallsapp/github-action@9ba913c152ae4be1327bfb9085dc806cedb44057
55-
with:
39+
- name: Install Go
40+
if: success()
41+
uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9
42+
with:
43+
go-version: 1.19.x
44+
- name: Checkout code
45+
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
46+
- name: Calc coverage
47+
run: |
48+
go test ./... -v -covermode=count -coverprofile=coverage.out
49+
- name: Convert coverage.out to coverage.lcov
50+
uses: jandelgado/gcov2lcov-action@c680c0f7c7442485f1749eb2a13e54a686e76eb5
51+
- name: Coveralls
52+
uses: coverallsapp/github-action@9ba913c152ae4be1327bfb9085dc806cedb44057
53+
with:
5654
github-token: ${{ secrets.github_token }}
5755
path-to-lcov: coverage.lcov

Diff for: Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.18-alpine3.15
1+
FROM golang:1.19.7-alpine3.17
22

33
# add addtional packages needed for the race detector to work
44
RUN apk add --update build-base make

Diff for: README.md

+8
Original file line numberDiff line numberDiff line change
@@ -225,5 +225,13 @@ Otherwise no task ids will be set at all.
225225

226226
Finding the task id is robust again other comments before or after or in the same line as the `testRunnerTaskID` comment, see the [conditionals-with-task-ids test file][task-id-comments-examples] for examples.
227227

228+
## Known limitations
229+
230+
Besides what is mentioned in the open issues, the test runner has the following limitations currently.
231+
232+
- The test runner assumes all test functions `func Test...` can be found in one file.
233+
- The `cases_test.go` file is ignored when extracting the code for the test.
234+
- Sub-tests need to follow a certain format, see details above.
235+
228236
[task-id]: https://exercism.org/docs/building/tooling/test-runners/interface#h-task-id
229237
[task-id-comments-examples]: https://github.com/exercism/go-test-runner/tree/main/testrunner/testdata/concept/conditionals-with-task-ids

Diff for: external-packages/go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
module external_packages
22

3-
go 1.16
3+
go 1.18
44

55
require (
66
golang.org/x/exp v0.0.0-20221006183845-316c7553db56
7-
golang.org/x/text v0.3.7
7+
golang.org/x/text v0.7.0
88
)

Diff for: external-packages/go.sum

+2-25
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,4 @@
1-
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
2-
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
3-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4-
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
51
golang.org/x/exp v0.0.0-20221006183845-316c7553db56 h1:BrYbdKcCNjLyrN6aKqXy4hPw9qGI8IATkj4EWv9Q+kQ=
62
golang.org/x/exp v0.0.0-20221006183845-316c7553db56/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
7-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
8-
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
9-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
10-
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
11-
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
12-
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
13-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
14-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
15-
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
16-
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
17-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
18-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
19-
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
20-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
21-
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
22-
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
23-
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
24-
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
25-
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
26-
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
27-
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
3+
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
4+
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=

Diff for: go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/exercism/go-test-runner
22

3-
go 1.18
3+
go 1.19
44

55
require (
66
github.com/davecgh/go-spew v1.1.1 // indirect

Diff for: integration_test.go

+24-20
Original file line numberDiff line numberDiff line change
@@ -54,42 +54,46 @@ func TestIntegration(t *testing.T) {
5454
{
5555
// This test case covers the case the code under test does not compile,
5656
// i.e. "go build ." would fail.
57-
inputDir: "./testrunner/testdata/practice/broken",
58-
expected: "./testrunner/testdata/expected/broken.json",
57+
inputDir: filepath.Join("testrunner", "testdata", "practice", "broken"),
58+
expected: filepath.Join("testrunner", "testdata", "expected", "broken.json"),
5959
},
6060
{
6161
// This test case covers the case that the test code does not compile,
6262
// i.e. "go build ." would succeed but "go test" returns compilation errors.
63-
inputDir: "./testrunner/testdata/practice/missing_func",
64-
expected: "./testrunner/testdata/expected/missing_func.json",
63+
inputDir: filepath.Join("testrunner", "testdata", "practice", "missing_func"),
64+
expected: filepath.Join("testrunner", "testdata", "expected", "missing_func.json"),
6565
},
6666
{
67-
inputDir: "./testrunner/testdata/practice/broken_import",
68-
expected: "./testrunner/testdata/expected/broken_import.json",
67+
inputDir: filepath.Join("testrunner", "testdata", "practice", "broken_import"),
68+
expected: filepath.Join("testrunner", "testdata", "expected", "broken_import.json"),
6969
},
7070
{
71-
inputDir: "./testrunner/testdata/practice/passing",
72-
expected: "./testrunner/testdata/expected/passing.json",
71+
inputDir: filepath.Join("testrunner", "testdata", "practice", "passing"),
72+
expected: filepath.Join("testrunner", "testdata", "expected", "passing.json"),
7373
},
7474
{
75-
inputDir: "./testrunner/testdata/practice/pkg_level_error",
76-
expected: "./testrunner/testdata/expected/pkg_level_error.json",
75+
inputDir: filepath.Join("testrunner", "testdata", "practice", "pkg_level_error"),
76+
expected: filepath.Join("testrunner", "testdata", "expected", "pkg_level_error.json"),
7777
},
7878
{
79-
inputDir: "./testrunner/testdata/practice/failing",
80-
expected: "./testrunner/testdata/expected/failing.json",
79+
inputDir: filepath.Join("testrunner", "testdata", "practice", "failing"),
80+
expected: filepath.Join("testrunner", "testdata", "expected", "failing.json"),
8181
},
8282
{
83-
inputDir: "./testrunner/testdata/concept/auto_assigned_task_ids",
84-
expected: "./testrunner/testdata/expected/auto_assigned_task_ids.json",
83+
inputDir: filepath.Join("testrunner", "testdata", "concept", "auto_assigned_task_ids"),
84+
expected: filepath.Join("testrunner", "testdata", "expected", "auto_assigned_task_ids.json"),
8585
},
8686
{
87-
inputDir: "./testrunner/testdata/concept/explicit_task_ids",
88-
expected: "./testrunner/testdata/expected/explicit_task_ids.json",
87+
inputDir: filepath.Join("testrunner", "testdata", "concept", "explicit_task_ids"),
88+
expected: filepath.Join("testrunner", "testdata", "expected", "explicit_task_ids.json"),
8989
},
9090
{
91-
inputDir: "./testrunner/testdata/concept/missing_task_ids",
92-
expected: "./testrunner/testdata/expected/missing_task_ids.json",
91+
inputDir: filepath.Join("testrunner", "testdata", "concept", "missing_task_ids"),
92+
expected: filepath.Join("testrunner", "testdata", "expected", "missing_task_ids.json"),
93+
},
94+
{
95+
inputDir: filepath.Join("testrunner", "testdata", "concept", "non_executed_tests"),
96+
expected: filepath.Join("testrunner", "testdata", "expected", "non_executed_tests.json"),
9397
},
9498
}
9599

@@ -106,7 +110,7 @@ func TestIntegration(t *testing.T) {
106110

107111
for _, tt := range tests {
108112
t.Run(tt.inputDir, func(t *testing.T) {
109-
err := os.RemoveAll("./outdir")
113+
err := os.RemoveAll("outdir")
110114
require.NoError(t, err, "failed to clean up output directory")
111115

112116
var stdout, stderr bytes.Buffer
@@ -119,7 +123,7 @@ func TestIntegration(t *testing.T) {
119123
err = cmd.Run()
120124
require.NoErrorf(t, err, "failed to execute test runner: %s %s", stdout.String(), stderr.String())
121125

122-
resultBytes, err := os.ReadFile("./outdir/results.json")
126+
resultBytes, err := os.ReadFile(filepath.Join("outdir", "results.json"))
123127
require.NoError(t, err, "failed to read results")
124128

125129
result := sanitizeResult(string(resultBytes), []string{goExe, currentDir, goRoot})

Diff for: main.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"fmt"
5-
"io/ioutil"
65
"log"
76
"os"
87
"path/filepath"
@@ -23,7 +22,7 @@ func main() {
2322

2423
report := testrunner.Execute(input_dir)
2524
results := filepath.Join(output_dir, "results.json")
26-
err := ioutil.WriteFile(results, report, 0644)
25+
err := os.WriteFile(results, report, 0644)
2726
if err != nil {
2827
log.Fatalf("Failed to write results.json: %s", err)
2928
}

Diff for: main_test.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@ import (
44
"fmt"
55
"os"
66
"os/exec"
7+
"path/filepath"
78
"strings"
89
"testing"
910
)
1011

1112
func ExampleMain() {
12-
os.Args = []string{"path", "testrunner/testdata/practice/passing", "outdir"}
13+
os.Args = []string{
14+
"path",
15+
filepath.Join("testrunner", "testdata", "practice", "passing"),
16+
"outdir",
17+
}
1318
main()
1419
// Output:
1520
}
@@ -79,9 +84,9 @@ func TestCheckArgs(t *testing.T) {
7984
{
8085
name: "broken output_dir",
8186
input_dir: "testrunner",
82-
output_dir: "/tmp/broken/rmme",
87+
output_dir: filepath.Join("/", "tmp", "broken", "rmme"),
8388
ok: false,
84-
msg: "output_dir /tmp/broken/rmme does not exist, mkdir failed:",
89+
msg: "output_dir " + filepath.Join("/", "tmp", "broken", "rmme") + " does not exist, mkdir failed:",
8590
},
8691
}
8792
for _, tt := range tests {

Diff for: testrunner/ast.go

+32-8
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,49 @@ type subTestAstInfo struct {
2929
rangeAstIdx int
3030
}
3131

32-
// return the code of the "test" function from a file
33-
func getFuncCodeAndTaskID(test string, fstr string) (string, uint64) {
32+
type rootLevelTest struct {
33+
name string
34+
fileName string
35+
code string
36+
taskID uint64
37+
}
38+
39+
// FindAllRootLevelTests parses the test file and extracts the name,
40+
// test code and task id for each top level test (parent test) in the file.
41+
func FindAllRootLevelTests(fileName string) []rootLevelTest {
42+
defer handleASTPanic()
43+
tests := []rootLevelTest{}
3444
fset := token.NewFileSet()
3545
ppc := parser.ParseComments
36-
file, err := parser.ParseFile(fset, fstr, nil, ppc)
46+
file, err := parser.ParseFile(fset, fileName, nil, ppc)
3747
if err != nil {
38-
log.Printf("warning: '%s' not parsed from '%s': %s", test, fstr, err)
39-
return "", 0
48+
log.Printf("error: not able to parse '%s': %s", fileName, err)
49+
return nil
4050
}
4151
for _, d := range file.Decls {
42-
if f, ok := d.(*ast.FuncDecl); ok && f.Name.Name == test {
52+
if f, ok := d.(*ast.FuncDecl); ok && strings.HasPrefix(f.Name.Name, "Test") {
4353
taskID := findTaskID(f.Doc)
4454
fun := &printer.CommentedNode{Node: f, Comments: file.Comments}
4555
var buf bytes.Buffer
4656
printer.Fprint(&buf, fset, fun)
47-
return buf.String(), taskID
57+
58+
tests = append(tests, rootLevelTest{
59+
name: f.Name.Name,
60+
fileName: fileName,
61+
code: buf.String(),
62+
taskID: taskID,
63+
})
4864
}
4965
}
50-
return "", 0
66+
return tests
67+
}
68+
69+
func ConvertToMapByTestName(tests []rootLevelTest) map[string]rootLevelTest {
70+
result := map[string]rootLevelTest{}
71+
for i := range tests {
72+
result[tests[i].name] = tests[i]
73+
}
74+
return result
5175
}
5276

5377
var taskIDFormat = regexp.MustCompile(`testRunnerTaskID=([0-9]+)`)

Diff for: testrunner/ast_test.go

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package testrunner
22

33
import (
4+
"path/filepath"
45
"testing"
56
)
67

@@ -14,25 +15,23 @@ func TestGetFuncCode(t *testing.T) {
1415
{
1516
name: "valid call",
1617
testName: "TestNonSubtest",
17-
testFile: "testdata/concept/conditionals/conditionals_test.go",
18+
testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_test.go"),
1819
code: "func TestNonSubtest(t *testing.T) {\n\t// comments should be included\n\tfmt.Println(\"the whole block\")\n\tfmt.Println(\"should be returned\")\n}",
19-
}, {
20-
name: "missing test",
21-
testName: "TestNothing",
22-
testFile: "testdata/concept/conditionals/conditionals_test.go",
23-
code: "",
24-
}, {
20+
},
21+
{
2522
name: "invalid test file",
2623
testName: "TestNonSubtest",
27-
testFile: "testdata/concept/conditionals/conditionals_missing.go",
24+
testFile: filepath.Join("testdata", "concept", "conditionals", "conditionals_missing.go"),
2825
code: "",
2926
},
3027
}
3128
for _, tt := range tests {
3229
t.Run(tt.name, func(t *testing.T) {
33-
if code, _ := getFuncCodeAndTaskID(tt.testName, tt.testFile); code != tt.code {
34-
t.Errorf("getFuncCode(%v, %v) = %v; want %v",
35-
tt.testName, tt.testFile, code, tt.code)
30+
rootLevelTests := FindAllRootLevelTests(tt.testFile)
31+
rootLevelTestsMap := ConvertToMapByTestName(rootLevelTests)
32+
if rootLevelTestsMap[tt.testName].code != tt.code {
33+
t.Errorf("FindAllRootLevelTests for %s did not return correct code, got %v; want %v",
34+
tt.testFile, rootLevelTestsMap[tt.testName].code, tt.code)
3635
}
3736
})
3837
}

0 commit comments

Comments
 (0)