Skip to content

Commit

Permalink
add cmd tool metadata and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
caroott authored and kMutagene committed Oct 21, 2024
1 parent 0fd5be9 commit 7007a0b
Show file tree
Hide file tree
Showing 8 changed files with 353 additions and 19 deletions.
18 changes: 15 additions & 3 deletions src/CWL/CWL.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ module CWLProcessingUnits =
?baseCommand: string [],
?requirements: Requirement [],
?hints: Requirement [],
?inputs: Input []
?inputs: Input [],
?metadata: DynamicObj
) =
inherit DynamicObj ()

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

member this.CWLVersion
with get() = _cwlVersion
Expand Down Expand Up @@ -56,14 +58,19 @@ module CWLProcessingUnits =
with get() = _inputs
and set(inputs) = _inputs <- inputs

member this.Metadata
with get() = _metadata
and set(metadata) = _metadata <- metadata

type CWLWorkflowDescription(
cwlVersion: string,
cls: Class,
steps: WorkflowStep [],
inputs: Input [],
outputs: Output [],
?requirements: Requirement [],
?hints: Requirement []
?hints: Requirement [],
?metadata: DynamicObj
) =
inherit DynamicObj()

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

member this.CWLVersion
with get() = _cwlVersion
Expand Down Expand Up @@ -101,4 +109,8 @@ module CWLProcessingUnits =

member this.Hints
with get() = _hints
and set(hints) = _hints <- hints
and set(hints) = _hints <- hints

member this.Metadata
with get() = _metadata
and set(metadata) = _metadata <- metadata
63 changes: 47 additions & 16 deletions src/CWL/Decode.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ open WorkflowSteps
open DynamicObj

module Decode =

let rec overflowDecoder (dynObj: DynamicObj) (dict: System.Collections.Generic.Dictionary<string,YAMLElement>) =
for e in dict do
match e.Value with
| YAMLElement.Object [YAMLElement.Value v] ->
DynObj.setValue dynObj e.Key v.Value
| YAMLElement.Object [YAMLElement.Sequence s] ->
let newDynObj = new DynamicObj ()
(s |> List.map ((Decode.object (fun get -> (get.Overflow.FieldList []))) >> overflowDecoder newDynObj))
|> List.iter (fun x ->
DynObj.setValue
dynObj
e.Key
x
)
dynObj

let outputBindingGlobDecoder: (YAMLiciousTypes.YAMLElement -> OutputBinding) =
Decode.object (fun get ->
Expand Down Expand Up @@ -317,6 +333,35 @@ module Decode =
CommandLineTool,
outputs
)
let metadata =
let md = new DynamicObj ()
yamlCWL
|> Decode.object (fun get ->
overflowDecoder
md
(
get.Overflow.FieldList [
"inputs";
"outputs";
"class";
"id";
"label";
"doc";
"requirements";
"hints";
"cwlVersion";
"baseCommand";
"arguments";
"stdin";
"stderr";
"stdout";
"successCodes";
"temporaryFailCodes";
"permanentFailCodes"
]
)
) |> ignore
md
if inputs.IsSome then
description.Inputs <- inputs
if requirements.IsSome then
Expand All @@ -325,6 +370,8 @@ module Decode =
description.Hints <- hints
if baseCommand.IsSome then
description.BaseCommand <- baseCommand
if metadata.Properties.Count > 0 then
description.Metadata <- Some metadata
description

let stringOptionFieldDecoder field : (YAMLiciousTypes.YAMLElement -> string option) =
Expand Down Expand Up @@ -399,19 +446,3 @@ module Decode =
steps
)

let rec overflowDecoder (dynObj: DynamicObj) (dict: System.Collections.Generic.Dictionary<string,YAMLElement>) =
for e in dict do
match e.Value with
| YAMLElement.Object [YAMLElement.Value v] ->
DynObj.setValue dynObj e.Key v.Value
| YAMLElement.Object [YAMLElement.Sequence s] ->
let newDynObj = new DynamicObj ()
(s |> List.map ((Decode.object (fun get -> (get.Overflow.FieldList []))) >> overflowDecoder newDynObj))
|> List.iter (fun x ->
DynObj.setValue
dynObj
e.Key
x
)
dynObj

1 change: 1 addition & 0 deletions tests/CWL/ARCtrl.CWL.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="CWLObject.Tests.fs" />
<Compile Include="CWLObjectMetadata.Tests.fs" />
<Compile Include="Outputs.Tests.fs" />
<Compile Include="Inputs.Tests.fs" />
<Compile Include="Requirements.Tests.fs" />
Expand Down
6 changes: 6 additions & 0 deletions tests/CWL/CWLObject.Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,10 @@ let testCWLToolDescription =
$"Expected: {expected}\nActual: {actual}"
]
]
testCase "Metadata" <| fun _ ->
let expected = None
let actual = decodeCWLToolDescription.Metadata
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
174 changes: 174 additions & 0 deletions tests/CWL/CWLObjectMetadata.Tests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
module Tests.CWLObjectMetadata

open ARCtrl.CWL
open ARCtrl.CWL.CWLTypes
open ARCtrl.CWL.Requirements
open ARCtrl.CWL.Inputs
open ARCtrl.CWL.Outputs
open DynamicObj
open YAMLicious
open TestingUtils

let decodeCWLToolDescription =
TestObjects.CWL.CommandLineToolMetadata.cwl
|> Decode.decodeCommandLineTool

let testCWLToolDescriptionMetadata =
testList "CWLToolDescription" [
testCase "Class" <| fun _ ->
let expected = Class.CommandLineTool
let actual = decodeCWLToolDescription.Class
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "CWLVersion" <| fun _ ->
let expected = "v1.2"
let actual = decodeCWLToolDescription.CWLVersion
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "baseCommand" <| fun _ ->
let expected = Some [|"dotnet"; "fsi"; "script.fsx"|]
let actual = decodeCWLToolDescription.BaseCommand
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testList "Hints" [
let hintsItem = decodeCWLToolDescription.Hints
testCase "DockerRequirement" <| fun _ ->
let expected = DockerRequirement {DockerPull = Some "mcr.microsoft.com/dotnet/sdk:6.0"; DockerFile = None; DockerImageId = None}
let actual = hintsItem.Value.[0]
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
testList "Requirements" [
let requirementsItem = decodeCWLToolDescription.Requirements
testCase "InitialWorkDirRequirement" <| fun _ ->
let expected = InitialWorkDirRequirement [|Dirent {Entry = "$include: script.fsx"; Entryname = Some "script.fsx"; Writable = None }|]
let actual = requirementsItem.Value.[0]
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "EnvVarRequirement" <| fun _ ->
let expected = EnvVarRequirement [|{EnvName = "DOTNET_NOLOGO"; EnvValue = "true"}|]
let actual = requirementsItem.Value.[1]
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "NetworkAccessRequirement" <| fun _ ->
let expected = NetworkAccessRequirement
let actual = requirementsItem.Value.[2]
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
testList "Inputs" [
let inputsItem = decodeCWLToolDescription.Inputs.Value
testCase "Length" <| fun _ ->
let expected = 2
let actual = inputsItem.Length
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testList "File" [
let fileItem = inputsItem.[0]
testCase "Name" <| fun _ ->
let expected = "firstArg"
let actual = fileItem.Name
Expect.isTrue
("firstArg" = fileItem.Name)
"Name of input is not 'firstArg'"
testCase "Type" <| fun _ ->
let expected = File (FileInstance())
let actual = fileItem.Type.Value
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "InputBinding" <| fun _ ->
let expected = Some {Position = Some 1; Prefix = None; ItemSeparator = None; Separate = None}
let actual = fileItem.InputBinding
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
testList "String" [
let stringItem = inputsItem.[1]
testCase "Name" <| fun _ ->
let expected = "secondArg"
let actual = stringItem.Name
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "Type" <| fun _ ->
let expected = String
let actual = stringItem.Type.Value
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "InputBinding" <| fun _ ->
let expected = Some {Position = Some 2; Prefix = None; ItemSeparator = None; Separate = None}
let actual = stringItem.InputBinding
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
]
testList "Outputs" [
let outputsItem = decodeCWLToolDescription.Outputs
testCase "Length" <| fun _ ->
let expected = 2
let actual = outputsItem.Length
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testList "Directory" [
let directoryItem = outputsItem.[0]
testCase "Name" <| fun _ ->
let expected = "output"
let actual = directoryItem.Name
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "Type" <| fun _ ->
let expected = Directory (DirectoryInstance())
let actual = directoryItem.Type.Value
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "OutputBinding" <| fun _ ->
let expected = Some {Glob = Some "$(runtime.outdir)/.nuget"}
let actual = directoryItem.OutputBinding
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
testList "File" [
let fileItem = outputsItem.[1]
testCase "Name" <| fun _ ->
let expected = "output2"
let actual = fileItem.Name
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "Type" <| fun _ ->
let expected = File (FileInstance())
let actual = fileItem.Type.Value
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
testCase "OutputBinding" <| fun _ ->
let expected = Some {Glob = Some "$(runtime.outdir)/*.csv"}
let actual = fileItem.OutputBinding
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
]
testCase "Metadata" <| fun _ ->
let expected = TestObjects.CWL.CommandLineToolMetadata.expectedMetadataString
let actual = decodeCWLToolDescription.Metadata.Value |> DynObj.format
Expect.isTrue
(expected = actual)
$"Expected: {expected}\nActual: {actual}"
]
1 change: 1 addition & 0 deletions tests/CWL/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ open Fable.Pyxpecto

let all = testSequenced <| testList "CWL" [
Tests.CWLObject.testCWLToolDescription
Tests.CWLObjectMetadata.testCWLToolDescriptionMetadata
Tests.Outputs.testOutput
Tests.Inputs.testInput
Tests.Requirements.testRequirement
Expand Down
Loading

0 comments on commit 7007a0b

Please sign in to comment.