Skip to content

Commit befafb8

Browse files
committed
+generate DynamoDB data generate_dynamo_data.py
1 parent b8ebea2 commit befafb8

6 files changed

Lines changed: 130 additions & 1614 deletions

File tree

tests/e2e/data/dynamoDB/AUTO_RSV_SB_006.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
{
4040
"NHS_NUMBER": "5000000006",
4141
"ATTRIBUTE_TYPE": "RSV",
42-
"LAST_SUCCESSFUL_DATE": "<<DATE_LAST_WEEK>>"
42+
"LAST_SUCCESSFUL_DATE": "<<DATE_DAY_-7>>"
4343
}
4444
]
4545
}

tests/e2e/data/dynamoDB/AUTO_RSV_SB_007.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
{
4040
"NHS_NUMBER": "5000000007",
4141
"ATTRIBUTE_TYPE": "RSV",
42-
"LAST_SUCCESSFUL_DATE": "<<DATE_LAST_WEEK>>"
42+
"LAST_SUCCESSFUL_DATE": "<<DATE_DAY_-7>>"
4343
}
4444
]
4545
}

tests/e2e/data/dynamoDB/AUTO_RSV_SB_012.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
{
3030
"NHS_NUMBER": "5000000012",
3131
"ATTRIBUTE_TYPE": "RSV",
32-
"LAST_SUCCESSFUL_DATE": "<<DATE_LAST_WEEK>>"
32+
"LAST_SUCCESSFUL_DATE": "<<DATE_DAY_-7>>"
3333
}
3434
]
3535
}

tests/e2e/data/dynamoDB/AUTO_RSV_SB_013.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
{
4040
"NHS_NUMBER": "50000000014",
4141
"ATTRIBUTE_TYPE": "RSV",
42-
"LAST_SUCCESSFUL_DATE": "<<DATE_LAST_WEEK>>"
42+
"LAST_SUCCESSFUL_DATE": "<<DATE_DAY_-7>>"
4343
}
4444
]
4545
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import json
2+
import logging
3+
import os
4+
import re
5+
from datetime import datetime, timedelta
6+
from pathlib import Path
7+
from typing import Any
8+
9+
# Constants
10+
OUTPUT_ROOT = "out"
11+
DATE_FORMAT = "%Y%m%d"
12+
VAR_PATTERN = re.compile(r"<<([^<>]+)>>")
13+
14+
# Configure logging
15+
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
16+
17+
18+
class DateVariableResolver:
19+
"""Handles the logic for parsing and evaluating date-based variables."""
20+
21+
def __init__(self, today: datetime = None):
22+
self.today = today or datetime.today()
23+
24+
def resolve(self, token: str) -> str:
25+
logging.debug(f"Resolving variable: {token}")
26+
parts = token.split("_")
27+
if len(parts) < 3 or parts[0].upper() != "DATE":
28+
raise ValueError(f"Unsupported variable format: {token}")
29+
30+
_, unit, value = parts[0], parts[1].lower(), parts[2]
31+
32+
try:
33+
offset = int(value)
34+
except ValueError:
35+
raise ValueError(f"Invalid offset value: {value}")
36+
37+
if unit == "day":
38+
return (self.today + timedelta(days=offset)).strftime(DATE_FORMAT)
39+
if unit == "week":
40+
return (self.today + timedelta(weeks=offset)).strftime(DATE_FORMAT)
41+
if unit == "year":
42+
return (self.today.replace(year=self.today.year + offset)).strftime(DATE_FORMAT)
43+
if unit == "age":
44+
try:
45+
birth_date = self.today.replace(year=self.today.year - offset)
46+
except ValueError:
47+
# Handle February 29th
48+
birth_date = self.today.replace(month=2, day=28, year=self.today.year - offset)
49+
return birth_date.strftime(DATE_FORMAT)
50+
raise ValueError(f"Unsupported calculation unit: {unit}")
51+
52+
53+
class JsonTestDataProcessor:
54+
"""Processes JSON test files by resolving placeholders in 'data' arrays."""
55+
56+
def __init__(self, input_dir: Path, output_dir: Path, resolver: DateVariableResolver):
57+
self.input_dir = input_dir
58+
self.output_dir = output_dir
59+
self.resolver = resolver
60+
61+
def resolve_placeholders(self, obj: Any) -> Any:
62+
if isinstance(obj, dict):
63+
return {k: self.resolve_placeholders(v) for k, v in obj.items()}
64+
if isinstance(obj, list):
65+
return [self.resolve_placeholders(item) for item in obj]
66+
if isinstance(obj, str):
67+
return VAR_PATTERN.sub(self._replace_token, obj)
68+
return obj
69+
70+
def _replace_token(self, match: re.Match) -> str:
71+
token = match.group(1)
72+
try:
73+
return self.resolver.resolve(token)
74+
except Exception as e:
75+
logging.warning(f"Failed to resolve variable {token}: {e}")
76+
return match.group(0)
77+
78+
def process_file(self, file_path: Path):
79+
logging.info(f"Processing file: {file_path}")
80+
try:
81+
with open(file_path) as f:
82+
content = json.load(f)
83+
except Exception as e:
84+
logging.exception(f"Failed to read {file_path}: {e}")
85+
return
86+
87+
try:
88+
resolved = self.resolve_placeholders(content)
89+
except Exception as e:
90+
logging.exception(f"Failed to resolve placeholders: {e}")
91+
return
92+
93+
if "data" not in resolved:
94+
logging.error(f"Missing 'data' key in {file_path}")
95+
return
96+
97+
relative_path = file_path.relative_to(self.input_dir)
98+
output_path = self.output_dir / relative_path
99+
output_path.parent.mkdir(parents=True, exist_ok=True)
100+
101+
try:
102+
with open(output_path, "w") as f:
103+
json.dump(resolved["data"], f, indent=2)
104+
logging.info(f"Written resolved file: {output_path}")
105+
except Exception as e:
106+
logging.exception(f"Failed to write output: {e}")
107+
108+
109+
def main():
110+
input_dir = Path()
111+
output_dir = Path(OUTPUT_ROOT)
112+
resolver = DateVariableResolver()
113+
114+
processor = JsonTestDataProcessor(input_dir, output_dir, resolver)
115+
116+
logging.info(f"Scanning for JSON files in {input_dir}")
117+
for root, _, files in os.walk(input_dir):
118+
for file in files:
119+
if file.endswith(".json"):
120+
processor.process_file(Path(root) / file)
121+
else:
122+
logging.debug(f"Skipping non-JSON file: {file}")
123+
124+
125+
if __name__ == "__main__":
126+
main()

0 commit comments

Comments
 (0)