Skip to content

Commit 43d3023

Browse files
authored
Allows to run tests by suite or by name (#321)
* Allows to run tests by suite or by name * fixes tests
1 parent 4dfffaa commit 43d3023

File tree

6 files changed

+82
-11
lines changed

6 files changed

+82
-11
lines changed

protocol/types.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,8 @@ type
10791079

10801080
RunTestParams* = object
10811081
entryPoints*: seq[string]
1082+
suiteName*: string #Optional, if provided, only run tests in the suite. Takes precedence over testName
1083+
testNames*: seq[string] #Optional, if provided, only run the specific tests
10821084

10831085
RunTestProjectResult* = object
10841086
suites*: seq[RunTestSuiteResult]

routes.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,8 @@ proc runTests*(
867867
if nimPath.isNone:
868868
error "Nim path not found when running tests"
869869
return RunTestProjectResult()
870-
await runTests(params.entryPoints, nimPath.get())
870+
let suiteName = if params.suiteName == "": none(string) else: some(params.suiteName)
871+
await runTests(params.entryPoints, nimPath.get(), suiteName, params.testNames)
871872

872873
#Notifications
873874
proc initialized*(ls: LanguageServer, _: JsonNode): Future[void] {.async.} =

testrunner.nim

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import std/[os, strscans, tables, enumerate, strutils, xmlparser, xmltree]
1+
import std/[os, strscans, tables, enumerate, strutils, xmlparser, xmltree, options, strformat]
22
import chronos, chronos/asyncproc
33
import protocol/types
44
import ls
@@ -77,19 +77,31 @@ proc parseTestSuite*(node: XmlNode): RunTestSuiteResult =
7777
proc parseTestResults*(xmlContent: string): RunTestProjectResult =
7878
let xml = parseXml(xmlContent)
7979
for suiteNode in xml.findAll("testsuite"):
80-
result.suites.add(parseTestSuite(suiteNode))
80+
let suite = parseTestSuite(suiteNode)
81+
# echo suite.name, " ", suite.testResults.len
82+
if suite.testResults.len > 0:
83+
result.suites.add(suite)
8184

82-
proc runTests*(entryPoints: seq[string], nimPath: string): Future[RunTestProjectResult] {.async.} =
85+
proc runTests*(entryPoints: seq[string], nimPath: string, suiteName: Option[string], testNames: seq[string]): Future[RunTestProjectResult] {.async.} =
8386
#For now only one entry point is supported
8487
assert entryPoints.len == 1
8588
let entryPoint = entryPoints[0]
8689
let resultFile = (getTempDir() / "result.xml").absolutePath
8790
if not fileExists(entryPoint):
8891
error "Entry point does not exist", entryPoint = entryPoint
8992
return RunTestProjectResult()
93+
94+
95+
var args = @["c", "-r", entryPoints[0], fmt"--xml:{resultFile}"]
96+
if suiteName.isSome:
97+
args.add(fmt"{suiteName.get()}::")
98+
else:
99+
for testName in testNames:
100+
args.add(testName)
101+
90102
let process = await startProcess(
91103
nimPath,
92-
arguments = @["c", "-r", entryPoints[0], "--xml:" & resultFile],
104+
arguments = args,
93105
options = {UsePath},
94106
stderrHandle = AsyncProcess.Pipe,
95107
stdoutHandle = AsyncProcess.Pipe,
@@ -102,6 +114,7 @@ proc runTests*(entryPoints: seq[string], nimPath: string): Future[RunTestProject
102114
else:
103115
assert fileExists(resultFile)
104116
let xmlContent = readFile(resultFile)
117+
# echo "XML CONTENT: ", xmlContent
105118
result = parseTestResults(xmlContent)
106119
except Exception as e:
107120
let processOutput = string.fromBytes(process.stdoutStream.read().await)

tests/projects/testrunner/tests/sampletests.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest2
22

33
suite "Sample Tests":
4-
test "Sample Test":
4+
test "Sample Test alone":
55
check(1 == 1)
66

77
test "Global test":

tests/textensions.nim

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ suite "Nimlangserver extensions":
9595
let testProjectInfo = tests.projectInfo
9696
check testProjectInfo.suites.len == 3
9797
check testProjectInfo.suites["Sample Tests"].tests.len == 1
98-
check testProjectInfo.suites["Sample Tests"].tests[0].name == "Sample Test"
98+
check testProjectInfo.suites["Sample Tests"].tests[0].name == "Sample Test alone"
9999
check testProjectInfo.suites["Sample Tests"].tests[0].file == "sampletests.nim"
100100
check testProjectInfo.suites["Sample Tests"].tests[0].line == 4
101101

@@ -119,4 +119,59 @@ suite "Nimlangserver extensions":
119119
check runTestsRes.suites[0].failures == 0
120120
check runTestsRes.suites[0].errors == 0
121121
check runTestsRes.suites[0].skipped == 0
122-
check runTestsRes.suites[0].time > 0.0 and runTestsRes.suites[0].time < 1.0
122+
check runTestsRes.suites[0].time > 0.0 and runTestsRes.suites[0].time < 1.0
123+
124+
test "calling extension/runTest with a suite name should run the tests in the suite":
125+
let initParams =
126+
InitializeParams %* {
127+
"processId": %getCurrentProcessId(),
128+
"rootUri": fixtureUri("projects/testrunner/"),
129+
"capabilities":
130+
{"window": {"workDoneProgress": true}, "workspace": {"configuration": true}},
131+
}
132+
let initializeResult = waitFor client.initialize(initParams)
133+
134+
let suiteName = "Sample Suite"
135+
let runTestsParams = RunTestParams(entryPoints: @["tests/projects/testrunner/tests/sampletests.nim".absolutePath], suiteName: suiteName)
136+
let runTestsRes = client.call("extension/runTests", jsonutils.toJson(runTestsParams)).waitFor().jsonTo(
137+
RunTestProjectResult
138+
)
139+
check runTestsRes.suites.len == 1
140+
check runTestsRes.suites[0].name == suiteName
141+
check runTestsRes.suites[0].tests == 3
142+
143+
test "calling extension/runTest with a test name should run the tests in the suite":
144+
let initParams =
145+
InitializeParams %* {
146+
"processId": %getCurrentProcessId(),
147+
"rootUri": fixtureUri("projects/testrunner/"),
148+
"capabilities":
149+
{"window": {"workDoneProgress": true}, "workspace": {"configuration": true}},
150+
}
151+
152+
let initializeResult = waitFor client.initialize(initParams)
153+
154+
let testName = "Sample Test"
155+
let runTestsParams = RunTestParams(entryPoints: @["tests/projects/testrunner/tests/sampletests.nim".absolutePath], testNames: @[testName])
156+
let runTestsRes = client.call("extension/runTests", jsonutils.toJson(runTestsParams)).waitFor().jsonTo(RunTestProjectResult)
157+
158+
check runTestsRes.suites.len == 1
159+
check runTestsRes.suites[0].tests == 1
160+
check runTestsRes.suites[0].testResults[0].name == testName
161+
162+
test "calling extension/runTest with multiple test names should run the tests in the suite":
163+
let initParams =
164+
InitializeParams %* {
165+
"processId": %getCurrentProcessId(),
166+
"rootUri": fixtureUri("projects/testrunner/"),
167+
"capabilities":
168+
{"window": {"workDoneProgress": true}, "workspace": {"configuration": true}},
169+
}
170+
let initializeResult = waitFor client.initialize(initParams)
171+
172+
let testNames = @["Sample Test", "Sample Test 2"]
173+
let runTestsParams = RunTestParams(entryPoints: @["tests/projects/testrunner/tests/sampletests.nim".absolutePath], testNames: testNames)
174+
let runTestsRes = client.call("extension/runTests", jsonutils.toJson(runTestsParams)).waitFor().jsonTo(RunTestProjectResult)
175+
176+
check runTestsRes.suites.len == 1
177+
check runTestsRes.suites[0].tests == 2

tests/ttestrunner.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import unittest
2-
import std/[os, osproc, strscans, tables, sequtils, enumerate, strutils]
2+
import std/[os, osproc, strscans, tables, sequtils, enumerate, strutils, options]
33
import testhelpers
44
import testrunner
55
import chronos
@@ -27,7 +27,7 @@ suite "Test Parser":
2727
let testProjectInfo = extractTestInfo(listTestsOutput)
2828
check testProjectInfo.suites.len == 3
2929
check testProjectInfo.suites["Sample Tests"].tests.len == 1
30-
check testProjectInfo.suites["Sample Tests"].tests[0].name == "Sample Test"
30+
check testProjectInfo.suites["Sample Tests"].tests[0].name == "Sample Test alone"
3131
check testProjectInfo.suites["Sample Tests"].tests[0].file == "sampletests.nim"
3232
check testProjectInfo.suites["Sample Tests"].tests[0].line == 4
3333
check testProjectInfo.suites["Sample Suite"].tests.len == 3
@@ -36,7 +36,7 @@ suite "Test Parser":
3636
suite "Test Runner":
3737
test "should be able to run tests and retrieve results":
3838
let entryPoint = getCurrentDir() / "tests" / "projects" / "testrunner" / "tests" / "sampletests.nim"
39-
let testProjectResult = waitFor runTests(@[entryPoint], "nim")
39+
let testProjectResult = waitFor runTests(@[entryPoint], "nim", none(string), @[])
4040
check testProjectResult.suites.len == 4
4141
check testProjectResult.suites[0].name == "Sample Tests"
4242
check testProjectResult.suites[0].tests == 1

0 commit comments

Comments
 (0)