1
+ /*
2
+ * Copyright 2013-2024, 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.script
18
+
19
+ import nextflow.Session
20
+ import spock.lang.Specification
21
+
22
+ /**
23
+ * Tests for ProcessEntryHandler parameter mapping functionality
24
+ *
25
+ * @author Paolo Di Tommaso <[email protected] >
26
+ */
27
+ class ProcessEntryHandlerTest extends Specification {
28
+
29
+ def ' should parse complex parameters with dot notation' () {
30
+ given :
31
+ def session = Mock (Session )
32
+ def script = Mock (BaseScript )
33
+ def meta = Mock (ScriptMeta )
34
+ def handler = new ProcessEntryHandler (script, session, meta)
35
+
36
+ when :
37
+ def result = handler. parseComplexParameters([
38
+ ' meta.id' : ' SAMPLE_001' ,
39
+ ' meta.name' : ' TestSample' ,
40
+ ' meta.other' : ' some-value' ,
41
+ ' fasta' : ' /path/to/file.fa'
42
+ ])
43
+
44
+ then :
45
+ result. meta instanceof Map
46
+ result. meta. id == ' SAMPLE_001'
47
+ result. meta. name == ' TestSample'
48
+ result. meta. other == ' some-value'
49
+ result. fasta == ' /path/to/file.fa'
50
+ }
51
+
52
+ def ' should parse nested dot notation parameters' () {
53
+ given :
54
+ def session = Mock (Session )
55
+ def script = Mock (BaseScript )
56
+ def meta = Mock (ScriptMeta )
57
+ def handler = new ProcessEntryHandler (script, session, meta)
58
+
59
+ when :
60
+ def result = handler. parseComplexParameters([
61
+ ' meta.sample.id' : ' 123' ,
62
+ ' meta.sample.name' : ' test' ,
63
+ ' meta.config.quality' : ' high' ,
64
+ ' output.dir' : ' /results'
65
+ ])
66
+
67
+ then :
68
+ result. meta instanceof Map
69
+ result. meta. sample instanceof Map
70
+ result. meta. sample. id == ' 123'
71
+ result. meta. sample. name == ' test'
72
+ result. meta. config instanceof Map
73
+ result. meta. config. quality == ' high'
74
+ result. output instanceof Map
75
+ result. output. dir == ' /results'
76
+ }
77
+
78
+ def ' should handle simple parameters without dots' () {
79
+ given :
80
+ def session = Mock (Session )
81
+ def script = Mock (BaseScript )
82
+ def meta = Mock (ScriptMeta )
83
+ def handler = new ProcessEntryHandler (script, session, meta)
84
+
85
+ when :
86
+ def result = handler. parseComplexParameters([
87
+ ' sampleId' : ' SAMPLE_001' ,
88
+ ' threads' : ' 4' ,
89
+ ' dataFile' : ' /path/to/data.txt'
90
+ ])
91
+
92
+ then :
93
+ result. sampleId == ' SAMPLE_001'
94
+ result. threads == ' 4'
95
+ result. dataFile == ' /path/to/data.txt'
96
+ }
97
+
98
+ def ' should get value for val input type' () {
99
+ given :
100
+ def session = Mock (Session )
101
+ def script = Mock (BaseScript )
102
+ def meta = Mock (ScriptMeta )
103
+ def handler = new ProcessEntryHandler (script, session, meta)
104
+
105
+ when :
106
+ def complexParams = [
107
+ ' meta' : [id : ' SAMPLE_001' , name : ' TestSample' ],
108
+ ' sampleId' : ' SIMPLE_001'
109
+ ]
110
+ def valInput = [type : ' val' , name : ' meta' ]
111
+ def simpleInput = [type : ' val' , name : ' sampleId' ]
112
+
113
+ then :
114
+ handler. getValueForInput(valInput, complexParams) == [id : ' SAMPLE_001' , name : ' TestSample' ]
115
+ handler. getValueForInput(simpleInput, complexParams) == ' SIMPLE_001'
116
+ }
117
+
118
+ def ' should get value for path input type' () {
119
+ given :
120
+ def session = Mock (Session )
121
+ def script = Mock (BaseScript )
122
+ def meta = Mock (ScriptMeta )
123
+ def handler = new ProcessEntryHandler (script, session, meta)
124
+
125
+ when :
126
+ def complexParams = [
127
+ ' fasta' : ' /path/to/file.fa' ,
128
+ ' dataFile' : ' data.txt'
129
+ ]
130
+ def pathInput = [type : ' path' , name : ' fasta' ]
131
+ def fileInput = [type : ' file' , name : ' dataFile' ]
132
+
133
+ then :
134
+ def fastaResult = handler. getValueForInput(pathInput, complexParams)
135
+ def fileResult = handler. getValueForInput(fileInput, complexParams)
136
+
137
+ // Should convert string paths to Path objects (mocked here)
138
+ fastaResult. toString(). contains(' file.fa' )
139
+ fileResult. toString(). contains(' data.txt' )
140
+ }
141
+
142
+ def ' should throw exception for missing required parameter' () {
143
+ given :
144
+ def session = Mock (Session )
145
+ def script = Mock (BaseScript )
146
+ def meta = Mock (ScriptMeta )
147
+ def handler = new ProcessEntryHandler (script, session, meta)
148
+
149
+ when :
150
+ def complexParams = [
151
+ ' meta' : [id : ' SAMPLE_001' ]
152
+ ]
153
+ def missingInput = [type : ' val' , name : ' missing' ]
154
+ handler. getValueForInput(missingInput, complexParams)
155
+
156
+ then :
157
+ thrown(IllegalArgumentException )
158
+ }
159
+
160
+ def ' should map tuple input structure correctly' () {
161
+ given :
162
+ def session = Mock (Session ) {
163
+ getParams() >> [
164
+ ' meta.id' : ' SAMPLE_001' ,
165
+ ' meta.name' : ' TestSample' ,
166
+ ' meta.other' : ' some-value' ,
167
+ ' fasta' : ' /path/to/file.fa'
168
+ ]
169
+ }
170
+ def script = Mock (BaseScript )
171
+ def meta = Mock (ScriptMeta )
172
+ def processDef = Mock (ProcessDef )
173
+ def handler = new ProcessEntryHandler (script, session, meta)
174
+
175
+ when :
176
+ // Mock input structures for tuple val(meta), path(fasta)
177
+ def inputStructures = [
178
+ [
179
+ type : ' tuple' ,
180
+ elements : [
181
+ [type : ' val' , name : ' meta' ],
182
+ [type : ' path' , name : ' fasta' ]
183
+ ]
184
+ ]
185
+ ]
186
+
187
+ // Test the parameter mapping logic manually
188
+ def complexParams = handler. parseComplexParameters(session. getParams())
189
+ def tupleInput = inputStructures[0 ]
190
+ def tupleElements = []
191
+
192
+ for ( def element : tupleInput. elements ) {
193
+ def value = handler. getValueForInput(element, complexParams)
194
+ tupleElements. add(value)
195
+ }
196
+
197
+ then :
198
+ complexParams. meta instanceof Map
199
+ complexParams. meta. id == ' SAMPLE_001'
200
+ complexParams. meta. name == ' TestSample'
201
+ complexParams. meta. other == ' some-value'
202
+ complexParams. fasta == ' /path/to/file.fa'
203
+
204
+ tupleElements. size() == 2
205
+ tupleElements[0 ] instanceof Map // meta as map
206
+ tupleElements[0 ]. id == ' SAMPLE_001'
207
+ tupleElements[0 ]. name == ' TestSample'
208
+ tupleElements[0 ]. other == ' some-value'
209
+ // tupleElements[1] should be a Path object (mocked)
210
+ tupleElements[1 ]. toString(). contains(' file.fa' )
211
+ }
212
+ }
0 commit comments