Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add structs #8

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
17 changes: 17 additions & 0 deletions tests/test_common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import unittest

from wdlgen import ParameterMeta


class TestParamMeta(unittest.TestCase):
def test_quote_sanitise(self):
meta = ParameterMeta(foo='"bar"').get_string()
self.assertEqual('foo: "\\"bar\\""', meta)

def test_nl_sanitise(self):
meta = ParameterMeta(foo="bar\nbaz").get_string()
self.assertEqual('foo: "bar\\nbaz"', meta)

def test_backslackquote_sanitise(self):
meta = ParameterMeta(foo='bar\\"').get_string()
self.assertEqual('foo: "bar\\\\\\""', meta)
20 changes: 20 additions & 0 deletions tests/test_struct_generation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import unittest

from wdlgen import WdlType, String, Int
from wdlgen.struct import Struct


class TestStructs(unittest.TestCase):
def test_spec_example_1(self):
s = Struct("Name")
s.add_field(String, "myString")
s.add_field(Int, "myInt")

self.assertEqual(
"""\
struct Name {
String myString
Int myInt
}""",
s.get_string(),
)
56 changes: 39 additions & 17 deletions tests/test_task_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
WorkflowScatter,
Meta,
ParameterMeta,
Int,
)
from wdlgen.struct import Struct


class TestTaskGeneration(unittest.TestCase):
Expand Down Expand Up @@ -209,26 +211,20 @@ def test_commandarg_nospace(self):
self.assertEqual("arg=argVal", t.get_string())

def test_commandarg_flag(self):
t = Task.Command.CommandInput.from_fields(
name="my_value",
true="--arg"
)
self.assertEqual("~{if (my_value) then \"--arg\" else \"\"}", t.get_string())
t = Task.Command.CommandInput.from_fields(name="my_value", true="--arg")
self.assertEqual('~{if (my_value) then "--arg" else ""}', t.get_string())

def test_commandarg_flag_false(self):
t = Task.Command.CommandInput.from_fields(
name="my_value",
false="--arg"
)
self.assertEqual("~{if (my_value) then \"\" else \"--arg\"}", t.get_string())
t = Task.Command.CommandInput.from_fields(name="my_value", false="--arg")
self.assertEqual('~{if (my_value) then "" else "--arg"}', t.get_string())

def test_commandinp_array_inp(self):
t = Task.Command.CommandInput.from_fields(
name="my_array",
separator=" ",
default=[]
name="my_array", separator=" ", default=[]
)
self.assertEqual(
'~{sep(" ", if defined(my_array) then my_array else [])}', t.get_string()
)
self.assertEqual("~{sep(\" \", if defined(my_array) then my_array else [])}", t.get_string())


class TestWorkflowGeneration(unittest.TestCase):
Expand Down Expand Up @@ -328,9 +324,7 @@ def test_parameter_meta_dict(self):
w = Task(
"param_meta_obj",
parameter_meta=ParameterMeta(
obj_value={
"help": "This is help text", "scalar": 96
}
obj_value={"help": "This is help text", "scalar": 96}
),
)

Expand Down Expand Up @@ -381,3 +375,31 @@ def test_meta_string(self):
}"""
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_workflow_only)


class TestTaskWithExtra(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
s = Struct("Name")
s.add_field(String, "myString")
s.add_field(Int, "myInt")

cls.struct = s

def test_post_import_struct(self):

t = Task("hello")
t.inputs.extend([Input(String, "inp1"), Input(Int, "inp2")])

t.pre_statements.append(self.struct)
t.noninput_declarations.append("Name value = object { inp1: inp1, inp2: inp2 }")

t.command = Task.Command("cat ~{write_json(value)}")

t.outputs.append(
Output(
WdlType.parse_type("Array[String]"), "matches", "read_string(stdout())"
)
)

print(t.get_string())
22 changes: 11 additions & 11 deletions tests/test_workflow_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def test_parameter_meta_scalar(self):
test: 42
}
}"""
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[4:])
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_workflow_only)

def test_parameter_meta_string(self):
Expand All @@ -26,7 +26,7 @@ def test_parameter_meta_string(self):
other: "string value"
}
}"""
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[4:])
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_workflow_only)

def test_parameter_meta_bool(self):
Expand All @@ -41,7 +41,7 @@ def test_parameter_meta_bool(self):
neg: false
}
}"""
derived_task_only = "".join(w.get_string().splitlines(keepends=True)[4:])
derived_task_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_task_only)

def test_parameter_meta_obj(self):
Expand All @@ -60,16 +60,14 @@ def test_parameter_meta_obj(self):
obj_value: {help: "This is help text", scalar: 96}
}
}"""
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[4:])
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_workflow_only)

def test_parameter_meta_dict(self):
w = Workflow(
"param_meta_obj",
parameter_meta=ParameterMeta(
obj_value={
"help": "This is help text", "scalar": 96
}
obj_value={"help": "This is help text", "scalar": 96}
),
)

Expand All @@ -79,9 +77,10 @@ def test_parameter_meta_dict(self):
obj_value: {help: "This is help text", scalar: 96}
}
}"""
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[4:])
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_workflow_only)


class TestWorkflowMetaGeneration(unittest.TestCase):
def test_meta_scalar(self):
w = Workflow("meta_scalar", meta=Meta(arbitrary_scalar=42))
Expand All @@ -92,7 +91,7 @@ def test_meta_scalar(self):
arbitrary_scalar: 42
}
}"""
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[4:])
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_workflow_only)

def test_meta_string(self):
Expand All @@ -104,7 +103,7 @@ def test_meta_string(self):
author: "illusional"
}
}"""
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[4:])
derived_workflow_only = "".join(w.get_string().splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_workflow_only)

def test_meta_bool(self):
Expand All @@ -117,5 +116,6 @@ def test_meta_bool(self):
neg: false
}
}"""
derived_task_only = "".join(w.get_string().splitlines(keepends=True)[4:])
result = w.get_string()
derived_task_only = "".join(result.splitlines(keepends=True)[2:])
self.assertEqual(expected, derived_task_only)
17 changes: 10 additions & 7 deletions wdlgen/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ def __init__(self, condition, value_if_true, value_if_false):
self.value_if_true = value_if_true
self.value_if_false = value_if_false

def get_string(self):
return (
def get_string(self, indent=0):
tb = indent * " "
return tb + (
f"if {self.condition} then {self.value_if_true} else {self.value_if_false}"
)

Expand All @@ -31,16 +32,17 @@ def __init__(

self.format = "{type} {name}{def_w_equals}"

def get_string(self):
def get_string(self, indent=0):
if self.type is None:
raise Exception(
f"Could not convert wdlgen.Input ('{self.name}') to string because type was null"
)

tb = indent * " "
wd = self.type.get_string()
if isinstance(wd, list):
return self.get_string_from_type(wd[0])
return self.get_string_from_type(wd)
return tb + self.get_string_from_type(wd[0])
return tb + self.get_string_from_type(wd)

def get_string_from_type(self, wdtype):
expression = self.expression
Expand Down Expand Up @@ -72,8 +74,9 @@ def __init__(self, data_type: WdlType, name: str, expression: str = None):
self.name = name
self.expression = expression

def get_string(self):
f = "{type} {name}{def_w_equals}"
def get_string(self, indent=0):
tb = indent * " "
f = tb + "{type} {name}{def_w_equals}"
if isinstance(self.type, list):
return [
f.format(
Expand Down
30 changes: 30 additions & 0 deletions wdlgen/struct.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from typing import List, Optional

from wdlgen import WdlBase, WdlType


class StructField(WdlBase):
def __init__(self, type_: WdlType, name: str):
self.type_ = type_
self.name = name

def get_string(self, indent=0):
ind = indent * " "
return f"{ind}{self.type_.get_string()} {self.name}"


class Struct(WdlBase):
def __init__(self, name: str, fields: Optional[List[StructField]] = None):
self.name = name
self.fields = fields or []

def add_field(self, type_: WdlType, name: str):
self.fields.append(StructField(type_, name))

def get_string(self, indent=0):
tb = indent * " "
fields = "\n".join((f.get_string(indent=indent + 1)) for f in self.fields)
return f"""\
{tb}struct {self.name} {{
{fields}
{tb}}}"""
Loading