tricc-oo 1.5.13__py3-none-any.whl → 1.6.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. tests/build.py +20 -28
  2. tests/test_build.py +260 -0
  3. tests/test_cql.py +48 -109
  4. tests/to_ocl.py +15 -17
  5. tricc_oo/__init__.py +0 -6
  6. tricc_oo/converters/codesystem_to_ocl.py +51 -40
  7. tricc_oo/converters/cql/cqlLexer.py +1 -0
  8. tricc_oo/converters/cql/cqlListener.py +1 -0
  9. tricc_oo/converters/cql/cqlParser.py +1 -0
  10. tricc_oo/converters/cql/cqlVisitor.py +1 -0
  11. tricc_oo/converters/cql_to_operation.py +129 -123
  12. tricc_oo/converters/datadictionnary.py +45 -54
  13. tricc_oo/converters/drawio_type_map.py +146 -65
  14. tricc_oo/converters/tricc_to_xls_form.py +58 -28
  15. tricc_oo/converters/utils.py +4 -4
  16. tricc_oo/converters/xml_to_tricc.py +296 -235
  17. tricc_oo/models/__init__.py +2 -1
  18. tricc_oo/models/base.py +333 -305
  19. tricc_oo/models/calculate.py +66 -51
  20. tricc_oo/models/lang.py +26 -27
  21. tricc_oo/models/ocl.py +146 -161
  22. tricc_oo/models/ordered_set.py +15 -19
  23. tricc_oo/models/tricc.py +149 -89
  24. tricc_oo/parsers/xml.py +15 -30
  25. tricc_oo/serializers/planuml.py +4 -6
  26. tricc_oo/serializers/xls_form.py +110 -153
  27. tricc_oo/strategies/input/base_input_strategy.py +28 -32
  28. tricc_oo/strategies/input/drawio.py +59 -71
  29. tricc_oo/strategies/output/base_output_strategy.py +151 -65
  30. tricc_oo/strategies/output/dhis2_form.py +908 -0
  31. tricc_oo/strategies/output/fhir_form.py +377 -0
  32. tricc_oo/strategies/output/html_form.py +224 -0
  33. tricc_oo/strategies/output/openmrs_form.py +694 -0
  34. tricc_oo/strategies/output/spice.py +106 -127
  35. tricc_oo/strategies/output/xls_form.py +322 -244
  36. tricc_oo/strategies/output/xlsform_cdss.py +627 -142
  37. tricc_oo/strategies/output/xlsform_cht.py +252 -125
  38. tricc_oo/strategies/output/xlsform_cht_hf.py +13 -24
  39. tricc_oo/visitors/tricc.py +1424 -1033
  40. tricc_oo/visitors/utils.py +16 -16
  41. tricc_oo/visitors/xform_pd.py +91 -89
  42. {tricc_oo-1.5.13.dist-info → tricc_oo-1.6.8.dist-info}/METADATA +128 -84
  43. tricc_oo-1.6.8.dist-info/RECORD +52 -0
  44. tricc_oo-1.6.8.dist-info/licenses/LICENSE +373 -0
  45. {tricc_oo-1.5.13.dist-info → tricc_oo-1.6.8.dist-info}/top_level.txt +0 -0
  46. tricc_oo-1.5.13.dist-info/RECORD +0 -46
  47. {tricc_oo-1.5.13.dist-info → tricc_oo-1.6.8.dist-info}/WHEEL +0 -0
tests/build.py CHANGED
@@ -1,10 +1,18 @@
1
+ from tricc_oo.strategies.output.spice import SpiceStrategy # noqa: F401
2
+ from tricc_oo.strategies.output.xlsform_cht_hf import XLSFormCHTHFStrategy # noqa: F401
3
+ from tricc_oo.strategies.output.xlsform_cht import XLSFormCHTStrategy # noqa: F401
4
+ from tricc_oo.strategies.output.xlsform_cdss import XLSFormCDSSStrategy # noqa: F401
5
+ from tricc_oo.strategies.output.xls_form import XLSFormStrategy # noqa: F401
6
+ from tricc_oo.strategies.output.openmrs_form import OpenMRSStrategy # noqa: F401
7
+ from tricc_oo.strategies.output.fhir_form import FHIRStrategy # noqa: F401
8
+ from tricc_oo.strategies.output.html_form import HTMLStrategy # noqa: F401
9
+ from tricc_oo.strategies.output.dhis2_form import DHIS2Strategy # noqa: F401
10
+ from tricc_oo.strategies.input.drawio import DrawioStrategy # noqa: F401
1
11
  import getopt
2
- import gettext
3
12
  import logging
4
13
  import os
5
14
  import sys
6
15
  import gc
7
- import shutil
8
16
  from pathlib import Path
9
17
 
10
18
  # set up logging to file
@@ -23,15 +31,9 @@ langs = SingletonLangClass()
23
31
  # langs.add_trad('fr', fr)
24
32
  # langs.add_trad('en', en)
25
33
 
26
- from tricc_oo.strategies.input.drawio import DrawioStrategy
27
34
 
28
35
  # from tricc_oo.serializers.medalcreator import execute
29
36
 
30
- from tricc_oo.strategies.output.xls_form import XLSFormStrategy
31
- from tricc_oo.strategies.output.xlsform_cdss import XLSFormCDSSStrategy
32
- from tricc_oo.strategies.output.xlsform_cht import XLSFormCHTStrategy
33
- from tricc_oo.strategies.output.xlsform_cht_hf import XLSFormCHTHFStrategy
34
- from tricc_oo.strategies.output.spice import SpiceStrategy
35
37
 
36
38
  def setup_logger(
37
39
  logger_name,
@@ -39,15 +41,15 @@ def setup_logger(
39
41
  level=logging.INFO,
40
42
  formatting="[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s",
41
43
  ):
42
- l = logging.getLogger(logger_name)
44
+ logger = logging.getLogger(logger_name)
43
45
  formatter = logging.Formatter(formatting)
44
46
  file_handler = logging.FileHandler(log_file, mode="w+")
45
47
  file_handler.setFormatter(formatter)
46
48
  stream_handler = logging.StreamHandler()
47
49
  stream_handler.setFormatter(formatter)
48
50
 
49
- l.setLevel(level)
50
- l.addHandler(file_handler)
51
+ logger.setLevel(level)
52
+ logger.addHandler(file_handler)
51
53
 
52
54
 
53
55
  class ColorFormatter(logging.Formatter):
@@ -94,9 +96,7 @@ LEVELS = {
94
96
 
95
97
 
96
98
  def print_help():
97
- print(
98
- "-i / --input draw.io filepath (MANDATORY) or directory containing drawio files"
99
- )
99
+ print("-i / --input draw.io filepath (MANDATORY) or directory containing drawio files")
100
100
  print("-o / --output xls file ")
101
101
  print("-d form_id ")
102
102
  print("-s L4 system/strategy (odk, cht, cc)")
@@ -116,9 +116,7 @@ if __name__ == "__main__":
116
116
  input_strategy = "DrawioStrategy"
117
117
  output_strategy = "XLSFormStrategy"
118
118
  try:
119
- opts, args = getopt.getopt(
120
- sys.argv[1:], "hti:o:s:I:O:l:d:D:", ["input=", "output=", "help", "trads"]
121
- )
119
+ opts, args = getopt.getopt(sys.argv[1:], "hti:o:s:I:O:l:d:D:", ["input=", "output=", "help", "trads"])
122
120
  except getopt.GetoptError:
123
121
  print_help()
124
122
  sys.exit(1)
@@ -145,7 +143,7 @@ if __name__ == "__main__":
145
143
  if in_filepath is None:
146
144
  print_help()
147
145
  sys.exit(2)
148
-
146
+
149
147
  if not download_dir:
150
148
  download_dir = out_path
151
149
  debug_path = os.fspath(out_path + "/debug.log")
@@ -165,7 +163,7 @@ if __name__ == "__main__":
165
163
  setup_logger("default", debug_file_path, logging.INFO)
166
164
  file_content = []
167
165
  files = []
168
- in_filepath_list = in_filepath.split(',')
166
+ in_filepath_list = in_filepath.split(",")
169
167
  for in_filepath in in_filepath_list:
170
168
  pre, ext = os.path.splitext(in_filepath)
171
169
 
@@ -173,18 +171,13 @@ if __name__ == "__main__":
173
171
  # if output file path not specified, just chagne the extension
174
172
  out_path = os.path.dirname(pre)
175
173
 
176
-
177
174
  if os.path.isdir(in_filepath):
178
- files = [
179
- os.path.join(in_filepath, f)
180
- for f in os.listdir(in_filepath)
181
- if f.endswith(".drawio")
182
- ]
175
+ files = [os.path.join(in_filepath, f) for f in os.listdir(in_filepath) if f.endswith(".drawio")]
183
176
  elif os.path.isfile(in_filepath) and in_filepath.endswith(".drawio"):
184
177
  files = [in_filepath]
185
-
178
+
186
179
  for f in files:
187
- with open(f, 'r') as s:
180
+ with open(f, "r") as s:
188
181
  content = s.read()
189
182
  # present issue with some drawio file that miss the XML header
190
183
 
@@ -193,7 +186,6 @@ if __name__ == "__main__":
193
186
  logger.critical(f"{in_filepath} is neither a drawio file nor a directory containing drawio files")
194
187
  exit(1)
195
188
 
196
-
197
189
  strategy = globals()[input_strategy](files)
198
190
  logger.info(f"build the graph from strategy {input_strategy}")
199
191
  media_path = os.path.join(out_path, "media-tmp")
tests/test_build.py ADDED
@@ -0,0 +1,260 @@
1
+ import unittest
2
+ import subprocess
3
+ import sys
4
+ import os
5
+ import tempfile
6
+ import shutil
7
+ from pathlib import Path
8
+ import pandas as pd
9
+ from pyxform import create_survey_from_xls
10
+
11
+
12
+ class TestBuildScript(unittest.TestCase):
13
+ """Test cases for the build.py script with different argument combinations."""
14
+
15
+ def setUp(self):
16
+ """Set up test fixtures."""
17
+ self.test_data_dir = Path(__file__).parent / "data"
18
+ self.test_output_dir = Path(__file__).parent / "output"
19
+ self.demo_file = self.test_data_dir / "demo.drawio"
20
+
21
+ # Ensure test data exists
22
+ self.assertTrue(self.demo_file.exists(), f"Test data file {self.demo_file} does not exist")
23
+
24
+ def run_build_script(self, args):
25
+ """Helper method to run build.py with given arguments."""
26
+ cmd = [sys.executable, str(Path(__file__).parent / "build.py")] + args
27
+ result = subprocess.run(cmd, capture_output=True, text=True, cwd=Path(__file__).parent.parent)
28
+ return result
29
+
30
+ def test_basic_build_with_demo_file(self):
31
+ """Test basic build with demo.drawio file."""
32
+ with tempfile.TemporaryDirectory() as temp_dir:
33
+ args = [
34
+ "-i", str(self.demo_file),
35
+ "-o", temp_dir,
36
+ "-l", "i"
37
+ ]
38
+ result = self.run_build_script(args)
39
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
40
+
41
+ def test_build_with_directory_input(self):
42
+ """Test build with directory containing drawio files."""
43
+ with tempfile.TemporaryDirectory() as temp_dir:
44
+ args = [
45
+ "-i", str(self.test_data_dir),
46
+ "-o", temp_dir,
47
+ "-l", "i"
48
+ ]
49
+ result = self.run_build_script(args)
50
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
51
+
52
+ def test_build_with_xlsform_strategy(self):
53
+ """Test build with XLSFormStrategy (default)."""
54
+ with tempfile.TemporaryDirectory() as temp_dir:
55
+ args = [
56
+ "-i", str(self.demo_file),
57
+ "-o", temp_dir,
58
+ "-O", "XLSFormStrategy",
59
+ "-l", "i"
60
+ ]
61
+ result = self.run_build_script(args)
62
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
63
+
64
+ def test_build_with_html_strategy(self):
65
+ """Test build with HTMLStrategy."""
66
+ with tempfile.TemporaryDirectory() as temp_dir:
67
+ args = [
68
+ "-i", str(self.demo_file),
69
+ "-o", temp_dir,
70
+ "-O", "HTMLStrategy",
71
+ "-l", "i"
72
+ ]
73
+ result = self.run_build_script(args)
74
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
75
+
76
+ def test_build_with_fhir_strategy(self):
77
+ """Test build with FHIRStrategy."""
78
+ with tempfile.TemporaryDirectory() as temp_dir:
79
+ args = [
80
+ "-i", str(self.demo_file),
81
+ "-o", temp_dir,
82
+ "-O", "FHIRStrategy",
83
+ "-l", "i"
84
+ ]
85
+ result = self.run_build_script(args)
86
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
87
+
88
+ def test_build_with_dhis2_strategy(self):
89
+ """Test build with DHIS2Strategy."""
90
+ with tempfile.TemporaryDirectory() as temp_dir:
91
+ args = [
92
+ "-i", str(self.demo_file),
93
+ "-o", temp_dir,
94
+ "-O", "DHIS2Strategy",
95
+ "-l", "i"
96
+ ]
97
+ result = self.run_build_script(args)
98
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
99
+
100
+ def test_build_with_openmrs_strategy(self):
101
+ """Test build with OpenMRSStrategy."""
102
+ with tempfile.TemporaryDirectory() as temp_dir:
103
+ args = [
104
+ "-i", str(self.demo_file),
105
+ "-o", temp_dir,
106
+ "-O", "OpenMRSStrategy",
107
+ "-l", "i"
108
+ ]
109
+ result = self.run_build_script(args)
110
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
111
+
112
+ def test_build_with_cht_strategy(self):
113
+ """Test build with XLSFormCHTStrategy."""
114
+ with tempfile.TemporaryDirectory() as temp_dir:
115
+ args = [
116
+ "-i", str(self.demo_file),
117
+ "-o", temp_dir,
118
+ "-O", "XLSFormCHTStrategy",
119
+ "-l", "i"
120
+ ]
121
+ result = self.run_build_script(args)
122
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
123
+
124
+ def test_build_with_cht_hf_strategy(self):
125
+ """Test build with XLSFormCHTHFStrategy."""
126
+ with tempfile.TemporaryDirectory() as temp_dir:
127
+ args = [
128
+ "-i", str(self.demo_file),
129
+ "-o", temp_dir,
130
+ "-O", "XLSFormCHTHFStrategy",
131
+ "-l", "i"
132
+ ]
133
+ result = self.run_build_script(args)
134
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
135
+
136
+ def test_build_with_cdss_strategy(self):
137
+ """Test build with XLSFormCDSSStrategy."""
138
+ with tempfile.TemporaryDirectory() as temp_dir:
139
+ args = [
140
+ "-i", str(self.demo_file),
141
+ "-o", temp_dir,
142
+ "-O", "XLSFormCDSSStrategy",
143
+ "-l", "i"
144
+ ]
145
+ result = self.run_build_script(args)
146
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
147
+
148
+ # def test_build_with_spice_strategy(self):
149
+ # """Test build with SpiceStrategy."""
150
+ # with tempfile.TemporaryDirectory() as temp_dir:
151
+ # args = [
152
+ # "-i", str(self.demo_file),
153
+ # "-o", temp_dir,
154
+ # "-O", "SpiceStrategy",
155
+ # "-l", "i"
156
+ # ]
157
+ # result = self.run_build_script(args)
158
+ # self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
159
+
160
+ def test_build_with_debug_level(self):
161
+ """Test build with debug logging level."""
162
+ with tempfile.TemporaryDirectory() as temp_dir:
163
+ args = [
164
+ "-i", str(self.demo_file),
165
+ "-o", temp_dir,
166
+ "-l", "d"
167
+ ]
168
+ result = self.run_build_script(args)
169
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
170
+
171
+ def test_build_with_trad_option(self):
172
+ """Test build with translation option."""
173
+ with tempfile.TemporaryDirectory() as temp_dir:
174
+ args = [
175
+ "-i", str(self.demo_file),
176
+ "-o", temp_dir,
177
+ "-t",
178
+ "-l", "i"
179
+ ]
180
+ result = self.run_build_script(args)
181
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
182
+
183
+ def test_build_with_form_id(self):
184
+ """Test build with custom form ID."""
185
+ with tempfile.TemporaryDirectory() as temp_dir:
186
+ args = [
187
+ "-i", str(self.demo_file),
188
+ "-o", temp_dir,
189
+ "-d", "test_form_123",
190
+ "-l", "i"
191
+ ]
192
+ result = self.run_build_script(args)
193
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
194
+
195
+ def test_build_missing_input(self):
196
+ """Test build with missing input file."""
197
+ args = ["-o", "/tmp/test_output"]
198
+ result = self.run_build_script(args)
199
+ self.assertNotEqual(result.returncode, 0, "Build should fail with missing input")
200
+
201
+ def test_build_invalid_input_file(self):
202
+ """Test build with invalid input file."""
203
+ with tempfile.TemporaryDirectory() as temp_dir:
204
+ args = [
205
+ "-i", "/nonexistent/file.drawio",
206
+ "-o", temp_dir,
207
+ "-l", "i"
208
+ ]
209
+ result = self.run_build_script(args)
210
+ self.assertNotEqual(result.returncode, 0, "Build should fail with invalid input file")
211
+
212
+ def validate_xls_form(self, xls_path):
213
+ """Helper method to validate XLS form using ODK libraries."""
214
+ try:
215
+ # Convert XLS to XML using pyxform
216
+ survey = create_survey_from_xls(xls_path)
217
+ xml_output = survey.to_xml()
218
+
219
+ # Basic validation - check if XML was generated successfully
220
+ # In a real scenario, you might want to use odk_validate command line tool
221
+ if xml_output and len(xml_output.strip()) > 0:
222
+ return True, "Validation successful"
223
+ else:
224
+ return False, "Empty XML output"
225
+ except Exception as e:
226
+ return False, str(e)
227
+
228
+ def test_xlsform_strategy_validation(self):
229
+ """Test XLSFormStrategy output validation with ODK libraries."""
230
+ with tempfile.TemporaryDirectory() as temp_dir:
231
+ xls_output = Path(temp_dir) / "demo_tricc.xlsx"
232
+ args = [
233
+ "-i", str(self.demo_file),
234
+ "-o", temp_dir,
235
+ "-O", "XLSFormStrategy",
236
+ "-l", "i"
237
+ ]
238
+ result = self.run_build_script(args)
239
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
240
+
241
+ # Check if XLS file was created
242
+ self.assertTrue(xls_output.exists(), f"XLS file {xls_output} was not created")
243
+
244
+ def test_xlsform_cdss_strategy_validation(self):
245
+ """Test XLSFormCDSSStrategy output validation with ODK libraries."""
246
+ with tempfile.TemporaryDirectory() as temp_dir:
247
+ xls_output = Path(temp_dir) / "demo_tricc.xlsx"
248
+ args = [
249
+ "-i", str(self.demo_file),
250
+ "-o", temp_dir,
251
+ "-O", "XLSFormCDSSStrategy",
252
+ "-l", "i"
253
+ ]
254
+ result = self.run_build_script(args)
255
+ self.assertEqual(result.returncode, 0, f"Build failed: {result.stderr}")
256
+
257
+
258
+
259
+ if __name__ == "__main__":
260
+ unittest.main()
tests/test_cql.py CHANGED
@@ -1,51 +1,40 @@
1
1
  import unittest
2
2
 
3
- from tricc_oo.converters.cql_to_operation import cqlToXlsFormVisitor, transform_cql_to_operation
4
- from tricc_oo.models.base import TriccOperator, TriccOperation, TriccStatic, TriccReference
3
+ from tricc_oo.converters.cql_to_operation import transform_cql_to_operation
4
+ from tricc_oo.models.base import TriccOperator, TriccOperation, TriccStatic, TriccReference
5
+
5
6
 
6
7
  class TestCql(unittest.TestCase):
7
8
  def test_and(self):
8
- if_cql = "\"p_weight\" is not null and \"p_age\" > 2"
9
+ if_cql = '"p_weight" is not null and "p_age" > 2'
9
10
  dg_operation = transform_cql_to_operation(if_cql)
10
11
  dg_expected = TriccOperation(
11
12
  operator=TriccOperator.AND,
12
13
  reference=[
13
- TriccOperation(
14
- operator=TriccOperator.NOT,
15
- reference=[
16
- TriccOperation(
17
- operator=TriccOperator.ISNULL,
18
- reference=[TriccReference("p_weight")]
19
- )
20
- ]
21
- ),
22
- TriccOperation(
23
- operator=TriccOperator.MORE,
24
- reference=[
25
- TriccReference("p_age"),
26
- TriccStatic(
27
- value=2
28
- )
29
- ]
30
- )
31
- ]
14
+ TriccOperation(operator=TriccOperator.ISNOTNULL, reference=[TriccReference("p_weight")]),
15
+ TriccOperation(operator=TriccOperator.MORE, reference=[TriccReference("p_age"), TriccStatic(value=2)]),
16
+ ],
32
17
  )
33
18
  self.assertEqual(str(dg_operation), str(dg_expected))
34
-
35
-
19
+
36
20
  def test_durg_doage(self):
37
- if_cql = "DrugDosage('paracetamol', \"p_weight\", \"p_age\")"
21
+ if_cql = 'DrugDosage(\'paracetamol\', "p_weight", "p_age")'
38
22
  dg_operation = transform_cql_to_operation(if_cql)
39
23
  dg_expected = TriccOperation(
40
24
  operator=TriccOperator.DRUG_DOSAGE,
41
- reference=[
42
- TriccStatic(value='paracetamol'),
43
- TriccReference("p_weight"),
44
- TriccReference("p_age")
45
- ]
25
+ reference=[TriccStatic(value="paracetamol"), TriccReference("p_weight"), TriccReference("p_age")],
46
26
  )
47
27
  self.assertEqual(str(dg_operation), str(dg_expected))
48
-
28
+
29
+ def test_implied_concat(self):
30
+ if_cql = "'A' & \"B\" & 'C'"
31
+ cc_operation = transform_cql_to_operation(if_cql)
32
+ cc_expected = TriccOperation(
33
+ operator=TriccOperator.CONCATENATE,
34
+ reference=[TriccStatic(value="A"), TriccReference("B"), TriccStatic(value="C")],
35
+ )
36
+ self.assertEqual(str(cc_operation), str(cc_expected))
37
+
49
38
  def test_if(self):
50
39
  if_cql = "if AgeInDays() < 60 then 'newborn' else 'child'"
51
40
  if_operation = transform_cql_to_operation(if_cql)
@@ -54,61 +43,36 @@ class TestCql(unittest.TestCase):
54
43
  reference=[
55
44
  TriccOperation(
56
45
  operator=TriccOperator.LESS,
57
- reference=[
58
- TriccOperation(
59
- operator=TriccOperator.AGE_DAY,
60
- reference=[]
61
- ),
62
- TriccStatic(
63
- value=60
64
- )
65
- ]
46
+ reference=[TriccOperation(operator=TriccOperator.AGE_DAY, reference=[]), TriccStatic(value=60)],
66
47
  ),
67
- TriccStatic(value='newborn'),
68
- TriccStatic(value='child'),
69
- ]
48
+ TriccStatic(value="newborn"),
49
+ TriccStatic(value="child"),
50
+ ],
70
51
  )
71
52
  self.assertEqual(str(if_operation), str(if_expected))
72
53
 
73
54
  def test_case(self):
74
55
  case_cql = """
75
- case AgeInMonths()
76
- when 0 then 'newborn'
77
- when 1 then 'newborn'
56
+ case AgeInMonths()
57
+ when 0 then 'newborn'
58
+ when 1 then 'newborn'
78
59
  else 'child' end
79
60
  """
80
61
  case_operation = transform_cql_to_operation(case_cql)
81
62
  case_expected = TriccOperation(
82
63
  operator=TriccOperator.CASE,
83
64
  reference=[
84
- TriccOperation(
85
- operator=TriccOperator.AGE_MONTH,
86
- reference=[]
87
- ),
88
- [
89
- TriccStatic(
90
- value=0
91
- ),
92
- TriccStatic(
93
- value="newborn"
94
- )
95
- ],
96
- [
97
- TriccStatic(
98
- value=1
99
- ),
100
- TriccStatic(
101
- value="newborn"
102
- )
103
- ],
104
- TriccStatic(value='child'),
105
- ]
65
+ TriccOperation(operator=TriccOperator.AGE_MONTH, reference=[]),
66
+ [TriccStatic(value=0), TriccStatic(value="newborn")],
67
+ [TriccStatic(value=1), TriccStatic(value="newborn")],
68
+ TriccStatic(value="child"),
69
+ ],
106
70
  )
107
71
  self.assertEqual(str(case_operation), str(case_expected))
108
72
 
109
73
  def test_ifs(self):
110
74
  case_cql = """
111
- case
75
+ case
112
76
  when AgeInMonths() <= 2 then true
113
77
  when AgeInYears() > 5 then true
114
78
  else false end
@@ -121,57 +85,32 @@ class TestCql(unittest.TestCase):
121
85
  TriccOperation(
122
86
  operator=TriccOperator.LESS_OR_EQUAL,
123
87
  reference=[
124
- TriccOperation(
125
- operator=TriccOperator.AGE_MONTH,
126
- reference=[]
127
- ),
128
- TriccStatic(
129
- value=2
130
- )
131
- ]
88
+ TriccOperation(operator=TriccOperator.AGE_MONTH, reference=[]),
89
+ TriccStatic(value=2),
90
+ ],
132
91
  ),
133
- TriccStatic(
134
- value=True
135
- )
92
+ TriccStatic(value=True),
136
93
  ],
137
94
  [
138
95
  TriccOperation(
139
96
  operator=TriccOperator.MORE,
140
- reference=[
141
- TriccOperation(
142
- operator=TriccOperator.AGE_YEAR,
143
- reference=[]
144
- ),
145
- TriccStatic(
146
- value=5
147
- )
148
- ]
97
+ reference=[TriccOperation(operator=TriccOperator.AGE_YEAR, reference=[]), TriccStatic(value=5)],
149
98
  ),
150
- TriccStatic(
151
- value=True
152
- )
99
+ TriccStatic(value=True),
153
100
  ],
154
101
  TriccStatic(value=False),
155
- ]
102
+ ],
156
103
  )
157
104
  self.assertEqual(str(case_operation), str(case_expected))
158
105
 
159
-
160
106
  def test_minus(self):
161
- minus_cql =""" "WFL" >= -3"""
107
+ minus_cql = """ "WFL" >= -3"""
162
108
  # minus_cql = """
163
109
  # ("age_in_months" < 6 and "WFL" >= -3 and "WFL" < -2) is true
164
110
  # """
165
111
  minus_operation = transform_cql_to_operation(minus_cql)
166
112
  minus_expected = TriccOperation(
167
- TriccOperator.MORE_OR_EQUAL,
168
- [
169
- TriccReference("WFL"),
170
- TriccOperation(
171
- TriccOperator.MINUS,
172
- [TriccStatic(3)]
173
- )
174
- ]
113
+ TriccOperator.MORE_OR_EQUAL, [TriccReference("WFL"), TriccOperation(TriccOperator.MINUS, [TriccStatic(3)])]
175
114
  )
176
115
  self.assertEqual(str(minus_operation), str(minus_expected))
177
116
 
@@ -185,13 +124,13 @@ class TestCql(unittest.TestCase):
185
124
  operator=TriccOperator.SELECTED,
186
125
  reference=[
187
126
  TriccReference("identifier"),
188
- TriccStatic(value='code'),
189
- ]
127
+ TriccStatic(value="code"),
128
+ ],
190
129
  )
191
- ]
130
+ ],
192
131
  )
193
132
  self.assertEqual(str(dg_operation), str(dg_expected))
194
-
195
133
 
196
- if __name__ == '__main__':
197
- unittest.main()
134
+
135
+ if __name__ == "__main__":
136
+ unittest.main()
tests/to_ocl.py CHANGED
@@ -1,51 +1,49 @@
1
- import os
2
1
  import json
3
2
  from pathlib import Path
4
3
  from tricc_oo.converters.codesystem_to_ocl import transform_fhir_to_ocl
5
4
 
5
+
6
6
  def find_and_process_codesystems(directory_path):
7
7
  # Convert string path to Path object if not already
8
8
  dir_path = Path(directory_path)
9
-
9
+
10
10
  # Find all JSON files in the directory
11
11
  for json_file in dir_path.glob("*.json"):
12
12
  try:
13
13
  # Read the JSON file
14
- with open(json_file, 'r', encoding='utf-8') as f:
14
+ with open(json_file, "r", encoding="utf-8") as f:
15
15
  data = json.load(f)
16
-
16
+
17
17
  # Check if resource_type is CodeSystem
18
18
  if data.get("resourceType") == "CodeSystem":
19
19
  # Get the filename without extension for output naming
20
20
  file_key = json_file.stem
21
-
21
+
22
22
  # Write the original CodeSystem JSON
23
23
  output_cs_path = dir_path / f"{file_key}_codesystem.json"
24
- with open(output_cs_path, "w", encoding='utf-8') as file:
24
+ with open(output_cs_path, "w", encoding="utf-8") as file:
25
25
  file.write(json.dumps(data, indent=4))
26
-
26
+
27
27
  # Transform to OCL payload
28
28
  ocl_payload = transform_fhir_to_ocl(
29
- data,
30
- source_name="ALM",
31
- source_owner="pdelcroix",
32
- source_owner_type="User"
29
+ data, source_name="ALM", source_owner="pdelcroix", source_owner_type="User"
33
30
  )
34
-
31
+
35
32
  # Save the transformed OCL payload
36
33
  output_ocl_path = dir_path / f"{file_key}_ocl_bulk_upload.json"
37
- with open(output_ocl_path, "w", encoding='utf-8') as f:
34
+ with open(output_ocl_path, "w", encoding="utf-8") as f:
38
35
  for item in ocl_payload:
39
36
  json_line = json.dumps(item.dict(exclude_none=True))
40
- f.write(json_line + '\n')
41
-
37
+ f.write(json_line + "\n")
38
+
42
39
  print(f"OCL bulk upload payload generated successfully for {file_key}!")
43
-
40
+
44
41
  except json.JSONDecodeError:
45
42
  print(f"Error: Invalid JSON in file {json_file}")
46
43
  except Exception as e:
47
44
  print(f"Error processing {json_file}: {str(e)}")
48
45
 
46
+
49
47
  # Example usage
50
48
  media_path = "path/to/your/directory" # Replace with your directory path
51
- find_and_process_codesystems(media_path)
49
+ find_and_process_codesystems(media_path)