Skip to content

Commit 7007a0b

Browse files
caroottkMutagene
authored andcommitted
add cmd tool metadata and tests
1 parent 0fd5be9 commit 7007a0b

8 files changed

Lines changed: 353 additions & 19 deletions

File tree

src/CWL/CWL.fs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ module CWLProcessingUnits =
1616
?baseCommand: string [],
1717
?requirements: Requirement [],
1818
?hints: Requirement [],
19-
?inputs: Input []
19+
?inputs: Input [],
20+
?metadata: DynamicObj
2021
) =
2122
inherit DynamicObj ()
2223

@@ -27,6 +28,7 @@ module CWLProcessingUnits =
2728
let mutable _requirements: Requirement [] option = requirements
2829
let mutable _hints: Requirement [] option = hints
2930
let mutable _inputs: Input [] option = inputs
31+
let mutable _metadata: DynamicObj option = metadata
3032

3133
member this.CWLVersion
3234
with get() = _cwlVersion
@@ -56,14 +58,19 @@ module CWLProcessingUnits =
5658
with get() = _inputs
5759
and set(inputs) = _inputs <- inputs
5860

61+
member this.Metadata
62+
with get() = _metadata
63+
and set(metadata) = _metadata <- metadata
64+
5965
type CWLWorkflowDescription(
6066
cwlVersion: string,
6167
cls: Class,
6268
steps: WorkflowStep [],
6369
inputs: Input [],
6470
outputs: Output [],
6571
?requirements: Requirement [],
66-
?hints: Requirement []
72+
?hints: Requirement [],
73+
?metadata: DynamicObj
6774
) =
6875
inherit DynamicObj()
6976

@@ -74,6 +81,7 @@ module CWLProcessingUnits =
7481
let mutable _outputs: Output [] = outputs
7582
let mutable _requirements: Requirement [] option = requirements
7683
let mutable _hints: Requirement [] option = hints
84+
let mutable _metadata: DynamicObj option = metadata
7785

7886
member this.CWLVersion
7987
with get() = _cwlVersion
@@ -101,4 +109,8 @@ module CWLProcessingUnits =
101109

102110
member this.Hints
103111
with get() = _hints
104-
and set(hints) = _hints <- hints
112+
and set(hints) = _hints <- hints
113+
114+
member this.Metadata
115+
with get() = _metadata
116+
and set(metadata) = _metadata <- metadata

src/CWL/Decode.fs

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ open WorkflowSteps
1212
open DynamicObj
1313

1414
module Decode =
15+
16+
let rec overflowDecoder (dynObj: DynamicObj) (dict: System.Collections.Generic.Dictionary<string,YAMLElement>) =
17+
for e in dict do
18+
match e.Value with
19+
| YAMLElement.Object [YAMLElement.Value v] ->
20+
DynObj.setValue dynObj e.Key v.Value
21+
| YAMLElement.Object [YAMLElement.Sequence s] ->
22+
let newDynObj = new DynamicObj ()
23+
(s |> List.map ((Decode.object (fun get -> (get.Overflow.FieldList []))) >> overflowDecoder newDynObj))
24+
|> List.iter (fun x ->
25+
DynObj.setValue
26+
dynObj
27+
e.Key
28+
x
29+
)
30+
dynObj
1531

1632
let outputBindingGlobDecoder: (YAMLiciousTypes.YAMLElement -> OutputBinding) =
1733
Decode.object (fun get ->
@@ -317,6 +333,35 @@ module Decode =
317333
CommandLineTool,
318334
outputs
319335
)
336+
let metadata =
337+
let md = new DynamicObj ()
338+
yamlCWL
339+
|> Decode.object (fun get ->
340+
overflowDecoder
341+
md
342+
(
343+
get.Overflow.FieldList [
344+
"inputs";
345+
"outputs";
346+
"class";
347+
"id";
348+
"label";
349+
"doc";
350+
"requirements";
351+
"hints";
352+
"cwlVersion";
353+
"baseCommand";
354+
"arguments";
355+
"stdin";
356+
"stderr";
357+
"stdout";
358+
"successCodes";
359+
"temporaryFailCodes";
360+
"permanentFailCodes"
361+
]
362+
)
363+
) |> ignore
364+
md
320365
if inputs.IsSome then
321366
description.Inputs <- inputs
322367
if requirements.IsSome then
@@ -325,6 +370,8 @@ module Decode =
325370
description.Hints <- hints
326371
if baseCommand.IsSome then
327372
description.BaseCommand <- baseCommand
373+
if metadata.Properties.Count > 0 then
374+
description.Metadata <- Some metadata
328375
description
329376

330377
let stringOptionFieldDecoder field : (YAMLiciousTypes.YAMLElement -> string option) =
@@ -399,19 +446,3 @@ module Decode =
399446
steps
400447
)
401448

402-
let rec overflowDecoder (dynObj: DynamicObj) (dict: System.Collections.Generic.Dictionary<string,YAMLElement>) =
403-
for e in dict do
404-
match e.Value with
405-
| YAMLElement.Object [YAMLElement.Value v] ->
406-
DynObj.setValue dynObj e.Key v.Value
407-
| YAMLElement.Object [YAMLElement.Sequence s] ->
408-
let newDynObj = new DynamicObj ()
409-
(s |> List.map ((Decode.object (fun get -> (get.Overflow.FieldList []))) >> overflowDecoder newDynObj))
410-
|> List.iter (fun x ->
411-
DynObj.setValue
412-
dynObj
413-
e.Key
414-
x
415-
)
416-
dynObj
417-

tests/CWL/ARCtrl.CWL.Tests.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88
<ItemGroup>
99
<Compile Include="CWLObject.Tests.fs" />
10+
<Compile Include="CWLObjectMetadata.Tests.fs" />
1011
<Compile Include="Outputs.Tests.fs" />
1112
<Compile Include="Inputs.Tests.fs" />
1213
<Compile Include="Requirements.Tests.fs" />

tests/CWL/CWLObject.Tests.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,10 @@ let testCWLToolDescription =
164164
$"Expected: {expected}\nActual: {actual}"
165165
]
166166
]
167+
testCase "Metadata" <| fun _ ->
168+
let expected = None
169+
let actual = decodeCWLToolDescription.Metadata
170+
Expect.isTrue
171+
(expected = actual)
172+
$"Expected: {expected}\nActual: {actual}"
167173
]
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
module Tests.CWLObjectMetadata
2+
3+
open ARCtrl.CWL
4+
open ARCtrl.CWL.CWLTypes
5+
open ARCtrl.CWL.Requirements
6+
open ARCtrl.CWL.Inputs
7+
open ARCtrl.CWL.Outputs
8+
open DynamicObj
9+
open YAMLicious
10+
open TestingUtils
11+
12+
let decodeCWLToolDescription =
13+
TestObjects.CWL.CommandLineToolMetadata.cwl
14+
|> Decode.decodeCommandLineTool
15+
16+
let testCWLToolDescriptionMetadata =
17+
testList "CWLToolDescription" [
18+
testCase "Class" <| fun _ ->
19+
let expected = Class.CommandLineTool
20+
let actual = decodeCWLToolDescription.Class
21+
Expect.isTrue
22+
(expected = actual)
23+
$"Expected: {expected}\nActual: {actual}"
24+
testCase "CWLVersion" <| fun _ ->
25+
let expected = "v1.2"
26+
let actual = decodeCWLToolDescription.CWLVersion
27+
Expect.isTrue
28+
(expected = actual)
29+
$"Expected: {expected}\nActual: {actual}"
30+
testCase "baseCommand" <| fun _ ->
31+
let expected = Some [|"dotnet"; "fsi"; "script.fsx"|]
32+
let actual = decodeCWLToolDescription.BaseCommand
33+
Expect.isTrue
34+
(expected = actual)
35+
$"Expected: {expected}\nActual: {actual}"
36+
testList "Hints" [
37+
let hintsItem = decodeCWLToolDescription.Hints
38+
testCase "DockerRequirement" <| fun _ ->
39+
let expected = DockerRequirement {DockerPull = Some "mcr.microsoft.com/dotnet/sdk:6.0"; DockerFile = None; DockerImageId = None}
40+
let actual = hintsItem.Value.[0]
41+
Expect.isTrue
42+
(expected = actual)
43+
$"Expected: {expected}\nActual: {actual}"
44+
]
45+
testList "Requirements" [
46+
let requirementsItem = decodeCWLToolDescription.Requirements
47+
testCase "InitialWorkDirRequirement" <| fun _ ->
48+
let expected = InitialWorkDirRequirement [|Dirent {Entry = "$include: script.fsx"; Entryname = Some "script.fsx"; Writable = None }|]
49+
let actual = requirementsItem.Value.[0]
50+
Expect.isTrue
51+
(expected = actual)
52+
$"Expected: {expected}\nActual: {actual}"
53+
testCase "EnvVarRequirement" <| fun _ ->
54+
let expected = EnvVarRequirement [|{EnvName = "DOTNET_NOLOGO"; EnvValue = "true"}|]
55+
let actual = requirementsItem.Value.[1]
56+
Expect.isTrue
57+
(expected = actual)
58+
$"Expected: {expected}\nActual: {actual}"
59+
testCase "NetworkAccessRequirement" <| fun _ ->
60+
let expected = NetworkAccessRequirement
61+
let actual = requirementsItem.Value.[2]
62+
Expect.isTrue
63+
(expected = actual)
64+
$"Expected: {expected}\nActual: {actual}"
65+
]
66+
testList "Inputs" [
67+
let inputsItem = decodeCWLToolDescription.Inputs.Value
68+
testCase "Length" <| fun _ ->
69+
let expected = 2
70+
let actual = inputsItem.Length
71+
Expect.isTrue
72+
(expected = actual)
73+
$"Expected: {expected}\nActual: {actual}"
74+
testList "File" [
75+
let fileItem = inputsItem.[0]
76+
testCase "Name" <| fun _ ->
77+
let expected = "firstArg"
78+
let actual = fileItem.Name
79+
Expect.isTrue
80+
("firstArg" = fileItem.Name)
81+
"Name of input is not 'firstArg'"
82+
testCase "Type" <| fun _ ->
83+
let expected = File (FileInstance())
84+
let actual = fileItem.Type.Value
85+
Expect.isTrue
86+
(expected = actual)
87+
$"Expected: {expected}\nActual: {actual}"
88+
testCase "InputBinding" <| fun _ ->
89+
let expected = Some {Position = Some 1; Prefix = None; ItemSeparator = None; Separate = None}
90+
let actual = fileItem.InputBinding
91+
Expect.isTrue
92+
(expected = actual)
93+
$"Expected: {expected}\nActual: {actual}"
94+
]
95+
testList "String" [
96+
let stringItem = inputsItem.[1]
97+
testCase "Name" <| fun _ ->
98+
let expected = "secondArg"
99+
let actual = stringItem.Name
100+
Expect.isTrue
101+
(expected = actual)
102+
$"Expected: {expected}\nActual: {actual}"
103+
testCase "Type" <| fun _ ->
104+
let expected = String
105+
let actual = stringItem.Type.Value
106+
Expect.isTrue
107+
(expected = actual)
108+
$"Expected: {expected}\nActual: {actual}"
109+
testCase "InputBinding" <| fun _ ->
110+
let expected = Some {Position = Some 2; Prefix = None; ItemSeparator = None; Separate = None}
111+
let actual = stringItem.InputBinding
112+
Expect.isTrue
113+
(expected = actual)
114+
$"Expected: {expected}\nActual: {actual}"
115+
]
116+
]
117+
testList "Outputs" [
118+
let outputsItem = decodeCWLToolDescription.Outputs
119+
testCase "Length" <| fun _ ->
120+
let expected = 2
121+
let actual = outputsItem.Length
122+
Expect.isTrue
123+
(expected = actual)
124+
$"Expected: {expected}\nActual: {actual}"
125+
testList "Directory" [
126+
let directoryItem = outputsItem.[0]
127+
testCase "Name" <| fun _ ->
128+
let expected = "output"
129+
let actual = directoryItem.Name
130+
Expect.isTrue
131+
(expected = actual)
132+
$"Expected: {expected}\nActual: {actual}"
133+
testCase "Type" <| fun _ ->
134+
let expected = Directory (DirectoryInstance())
135+
let actual = directoryItem.Type.Value
136+
Expect.isTrue
137+
(expected = actual)
138+
$"Expected: {expected}\nActual: {actual}"
139+
testCase "OutputBinding" <| fun _ ->
140+
let expected = Some {Glob = Some "$(runtime.outdir)/.nuget"}
141+
let actual = directoryItem.OutputBinding
142+
Expect.isTrue
143+
(expected = actual)
144+
$"Expected: {expected}\nActual: {actual}"
145+
]
146+
testList "File" [
147+
let fileItem = outputsItem.[1]
148+
testCase "Name" <| fun _ ->
149+
let expected = "output2"
150+
let actual = fileItem.Name
151+
Expect.isTrue
152+
(expected = actual)
153+
$"Expected: {expected}\nActual: {actual}"
154+
testCase "Type" <| fun _ ->
155+
let expected = File (FileInstance())
156+
let actual = fileItem.Type.Value
157+
Expect.isTrue
158+
(expected = actual)
159+
$"Expected: {expected}\nActual: {actual}"
160+
testCase "OutputBinding" <| fun _ ->
161+
let expected = Some {Glob = Some "$(runtime.outdir)/*.csv"}
162+
let actual = fileItem.OutputBinding
163+
Expect.isTrue
164+
(expected = actual)
165+
$"Expected: {expected}\nActual: {actual}"
166+
]
167+
]
168+
testCase "Metadata" <| fun _ ->
169+
let expected = TestObjects.CWL.CommandLineToolMetadata.expectedMetadataString
170+
let actual = decodeCWLToolDescription.Metadata.Value |> DynObj.format
171+
Expect.isTrue
172+
(expected = actual)
173+
$"Expected: {expected}\nActual: {actual}"
174+
]

tests/CWL/Main.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ open Fable.Pyxpecto
44

55
let all = testSequenced <| testList "CWL" [
66
Tests.CWLObject.testCWLToolDescription
7+
Tests.CWLObjectMetadata.testCWLToolDescriptionMetadata
78
Tests.Outputs.testOutput
89
Tests.Inputs.testInput
910
Tests.Requirements.testRequirement

0 commit comments

Comments
 (0)