Skip to content

Commit dae7b19

Browse files
committed
Add tests for static types mgiration
1 parent c0023ce commit dae7b19

File tree

2 files changed

+243
-2
lines changed

2 files changed

+243
-2
lines changed

src/main/java/nextflow/lsp/services/script/ProcessConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ private Parameter typedInput(MethodCallExpression call, List<Statement> stagers)
121121

122122
if( "env".equals(qualifier) ) {
123123
var param = nextParam(ClassHelper.STRING_TYPE);
124-
var envName = constX(param.getName());
125-
var envValue = lastArg(call);
124+
var envName = lastArg(call);
125+
var envValue = constX(param.getName());
126126
var stager = stmt(callThisX("env", args(envName, envValue)));
127127
stagers.add(stager);
128128
return param;
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/*
2+
* Copyright 2024-2025, Seqera Labs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package nextflow.lsp.services.script
18+
19+
import nextflow.lsp.services.LanguageServerConfiguration
20+
import spock.lang.Specification
21+
22+
import static nextflow.lsp.TestUtils.*
23+
import static nextflow.lsp.util.JsonUtils.*
24+
25+
/**
26+
*
27+
* @author Ben Sherman <[email protected]>
28+
*/
29+
class ConvertScriptStaticTypesTest extends Specification {
30+
31+
boolean check(ScriptService service, String before, String after) {
32+
def uri = getUri('main.nf')
33+
open(service, uri, wrapInProcess(before))
34+
def response = service.executeCommand('nextflow.server.convertScriptToTyped', [asJson(uri)], LanguageServerConfiguration.defaults())
35+
def newText = response.applyEdit.getChanges()[uri][0].getNewText()
36+
assert newText == wrapInProcess(after).strip()
37+
return true
38+
}
39+
40+
String wrapInProcess(String section) {
41+
"""\
42+
process test {
43+
${section.strip()}
44+
45+
script:
46+
true
47+
}
48+
""".stripIndent()
49+
}
50+
51+
boolean checkInputs(ScriptService service, String beforeInput, String afterInput, String stage=null) {
52+
def before = """\
53+
input:
54+
${beforeInput}
55+
"""
56+
57+
def after = stage != null
58+
?
59+
"""\
60+
input:
61+
${afterInput}
62+
63+
stage:
64+
${stage}
65+
"""
66+
:
67+
"""\
68+
input:
69+
${afterInput}
70+
"""
71+
72+
return check(service, before, after)
73+
}
74+
75+
boolean checkOutputs(ScriptService service, String beforeOutput, String afterOutput, String topic=null) {
76+
def before = """\
77+
output:
78+
${beforeOutput}
79+
"""
80+
81+
def after = afterOutput != null && topic != null
82+
?
83+
"""\
84+
output:
85+
${afterOutput}
86+
87+
topic:
88+
${topic}
89+
"""
90+
: afterOutput != null
91+
?
92+
"""\
93+
output:
94+
${afterOutput}
95+
"""
96+
:
97+
"""\
98+
topic:
99+
${topic}
100+
"""
101+
102+
return check(service, before, after)
103+
}
104+
105+
def 'should convert val inputs' () {
106+
given:
107+
def service = getScriptService()
108+
109+
expect:
110+
checkInputs(service, 'val id', 'id')
111+
}
112+
113+
def 'should convert path inputs' () {
114+
given:
115+
def service = getScriptService()
116+
117+
expect:
118+
checkInputs(service, INPUT, TYPED_INPUT, STAGE)
119+
120+
where:
121+
INPUT | TYPED_INPUT | STAGE
122+
'path fastq' | 'fastq: Path' | null
123+
"path 'file.txt'" | '$in1: Path' | "stageAs 'file.txt', \$in1"
124+
"path fastq, stageAs: 'file.txt'" | 'fastq: Path' | "stageAs 'file.txt', fastq"
125+
"path fastq, arity: '1'" | 'fastq: Path' | null
126+
"path fastq, arity: '0..*'" | 'fastq: Set<Path>' | null
127+
"path fastq, arity: '2'" | 'fastq: Set<Path>' | null
128+
}
129+
130+
def 'should convert env inputs' () {
131+
given:
132+
def service = getScriptService()
133+
134+
expect:
135+
checkInputs(service, "env 'FOO'", '$in1: String', "env 'FOO', \$in1")
136+
}
137+
138+
def 'should convert stdin inputs' () {
139+
given:
140+
def service = getScriptService()
141+
142+
expect:
143+
checkInputs(service, 'stdin', '$in1: String', 'stdin $in1')
144+
}
145+
146+
def 'should convert tuple inputs' () {
147+
given:
148+
def service = getScriptService()
149+
150+
expect:
151+
checkInputs(service, INPUT, TYPED_INPUT, STAGE)
152+
153+
where:
154+
INPUT | TYPED_INPUT | STAGE
155+
'tuple val(id), path(fastq)' | '(id, fastq): Tuple<?, Path>' | null
156+
"tuple val(id), path('file.txt')" | '(id, $in1): Tuple<?, Path>' | "stageAs 'file.txt', \$in1"
157+
}
158+
159+
def 'should convert each inputs as val or path' () {
160+
given:
161+
def service = getScriptService()
162+
163+
expect:
164+
checkInputs(service, 'each method', 'method')
165+
checkInputs(service, 'each path(index)', 'index: Path')
166+
checkInputs(service, "each path('file.txt')", '$in1: Path', "stageAs 'file.txt', \$in1")
167+
}
168+
169+
def 'should convert val outputs' () {
170+
given:
171+
def service = getScriptService()
172+
173+
expect:
174+
checkOutputs(service, OUTPUT, TYPED_OUTPUT)
175+
176+
where:
177+
OUTPUT | TYPED_OUTPUT
178+
"val '1'" | "'1'"
179+
"val '1', emit: id" | "id = '1'"
180+
}
181+
182+
def 'should convert path outputs' () {
183+
given:
184+
def service = getScriptService()
185+
186+
expect:
187+
checkOutputs(service, OUTPUT, TYPED_OUTPUT, TOPIC)
188+
189+
where:
190+
OUTPUT | TYPED_OUTPUT | TOPIC
191+
"path 'output.txt'" | "file('output.txt')" | null
192+
"path 'output.txt', emit: txt" | "txt = file('output.txt')" | null
193+
"path 'output.txt', topic: txt" | null | "file('output.txt') >> 'txt'"
194+
// "path 'output.txt', hidden: true" | "file('output.txt', hidden: true)" | null
195+
"path 'output.txt', optional: true" | "file('output.txt', optional: true)" | null
196+
"path '*.txt', arity: '1'" | "file('*.txt')" | null
197+
// "path '*.txt', arity: '1..*'" | "files('*.txt')" | null
198+
// "path '*.txt', arity: '0..*'" | "files('*.txt', optional: true)" | null
199+
// "path '-'" | "stdout()" | null
200+
}
201+
202+
def 'should convert env outputs' () {
203+
given:
204+
def service = getScriptService()
205+
206+
expect:
207+
checkOutputs(service, "env 'FOO'", "env('FOO')")
208+
}
209+
210+
def 'should convert eval outputs' () {
211+
given:
212+
def service = getScriptService()
213+
214+
expect:
215+
checkOutputs(service, "eval 'bash --version'", "eval('bash --version')")
216+
}
217+
218+
def 'should convert stdout outputs' () {
219+
given:
220+
def service = getScriptService()
221+
222+
expect:
223+
checkOutputs(service, 'stdout', 'stdout()')
224+
}
225+
226+
def 'should convert tuple outputs' () {
227+
given:
228+
def service = getScriptService()
229+
230+
expect:
231+
checkOutputs(service, OUTPUT, TYPED_OUTPUT)
232+
233+
where:
234+
OUTPUT | TYPED_OUTPUT
235+
"tuple val('id'), path('*.fastq')" | "tuple('id', file('*.fastq'))"
236+
"tuple stdout(), val('id')" | "tuple(stdout(), 'id')"
237+
"tuple val('x'), val('y'), emit: xy" | "xy = tuple('x', 'y')"
238+
"tuple stdout(), env('BAR'), emit: bar" | "bar = tuple(stdout(), env('BAR'))"
239+
}
240+
241+
}

0 commit comments

Comments
 (0)