13#include <catch2/catch_test_macros.hpp>
23TEST_CASE(
"test_data_generator::ct generates valid CT dataset",
"[data_generator][ct]") {
26 SECTION(
"has required patient module attributes") {
32 SECTION(
"has required study module attributes") {
37 SECTION(
"has required series module attributes") {
43 SECTION(
"has required SOP common attributes") {
49 SECTION(
"has pixel data") {
53 SECTION(
"respects provided study UID") {
54 std::string custom_study_uid =
"1.2.3.4.5.6.7.8.9";
60TEST_CASE(
"test_data_generator::mr generates valid MR dataset",
"[data_generator][mr]") {
69TEST_CASE(
"test_data_generator::xa generates valid XA dataset",
"[data_generator][xa]") {
75 SECTION(
"has XA SOP Class UID") {
80 SECTION(
"has XA-specific attributes") {
84 REQUIRE(ds.contains(positioner_primary_angle));
85 REQUIRE(ds.contains(kvp));
88 SECTION(
"has larger image dimensions than CT/MR") {
95 REQUIRE(rows.has_value());
96 REQUIRE(cols.has_value());
97 CHECK(rows.value() == 512);
98 CHECK(cols.value() == 512);
102TEST_CASE(
"test_data_generator::us generates valid US dataset",
"[data_generator][us]") {
108 SECTION(
"has US SOP Class UID") {
113 SECTION(
"has 8-bit pixel data") {
115 REQUIRE(bits_allocated.has_value());
116 CHECK(bits_allocated.value() == 8);
124TEST_CASE(
"test_data_generator::xa_cine generates valid multi-frame XA dataset",
"[data_generator][xa][multiframe]") {
125 constexpr uint32_t num_frames = 15;
128 SECTION(
"has Number of Frames attribute") {
134 SECTION(
"has XA-specific cine attributes") {
138 REQUIRE(ds.contains(cine_rate));
139 REQUIRE(ds.contains(frame_time));
142 SECTION(
"has appropriately sized pixel data") {
144 REQUIRE(pixel_elem !=
nullptr);
147 size_t expected_size = 512 * 512 * 2 * num_frames;
148 CHECK(pixel_elem->length() == expected_size);
152TEST_CASE(
"test_data_generator::us_cine generates valid multi-frame US dataset",
"[data_generator][us][multiframe]") {
153 constexpr uint32_t num_frames = 30;
156 SECTION(
"has US Multi-frame SOP Class") {
161 SECTION(
"has Number of Frames attribute") {
167 SECTION(
"has 8-bit pixel data with multiple frames") {
169 REQUIRE(pixel_elem !=
nullptr);
172 size_t expected_size = 640 * 480 * 1 * num_frames;
173 CHECK(pixel_elem->length() == expected_size);
177TEST_CASE(
"test_data_generator::enhanced_ct generates valid Enhanced CT dataset",
"[data_generator][ct][enhanced]") {
178 constexpr uint32_t num_frames = 50;
181 SECTION(
"has Enhanced CT SOP Class") {
185 SECTION(
"has Image Type attribute") {
189 SECTION(
"has Number of Frames") {
195TEST_CASE(
"test_data_generator::enhanced_mr generates valid Enhanced MR dataset",
"[data_generator][mr][enhanced]") {
196 constexpr uint32_t num_frames = 25;
199 SECTION(
"has Enhanced MR SOP Class") {
203 SECTION(
"has Number of Frames") {
213TEST_CASE(
"test_data_generator::patient_journey creates multi-modal study",
"[data_generator][workflow]") {
216 SECTION(
"has consistent patient information") {
217 CHECK(study.patient_id ==
"PATIENT001");
218 CHECK_FALSE(study.study_uid.empty());
220 for (
const auto& ds : study.datasets) {
226 SECTION(
"contains all requested modalities") {
227 CHECK(study.datasets.size() == 3);
229 auto ct_datasets = study.get_by_modality(
"CT");
230 auto mr_datasets = study.get_by_modality(
"MR");
231 auto xa_datasets = study.get_by_modality(
"XA");
233 CHECK(ct_datasets.size() == 1);
234 CHECK(mr_datasets.size() == 1);
235 CHECK(xa_datasets.size() == 1);
238 SECTION(
"each modality has unique series UID") {
239 CHECK(study.series_count() == 3);
243TEST_CASE(
"test_data_generator::worklist generates valid worklist item",
"[data_generator][worklist]") {
246 SECTION(
"has patient attributes") {
251 SECTION(
"has scheduled procedure step attributes") {
257 SECTION(
"has requested procedure attributes") {
268TEST_CASE(
"test_data_generator::large creates appropriately sized dataset",
"[data_generator][edge_case]") {
269 constexpr size_t target_mb = 2;
273 REQUIRE(pixel_elem !=
nullptr);
277 size_t target_bytes = target_mb * 1024 * 1024;
278 size_t actual_size = pixel_elem->length();
281 CHECK(actual_size >= target_bytes / 2);
282 CHECK(actual_size <= target_bytes * 2);
285TEST_CASE(
"test_data_generator::unicode creates dataset with Unicode characters",
"[data_generator][edge_case][unicode]") {
288 SECTION(
"has specific character set") {
292 SECTION(
"has patient name with Korean characters") {
296 CHECK_FALSE(patient_name.empty());
300TEST_CASE(
"test_data_generator::with_private_tags includes private tags",
"[data_generator][edge_case][private]") {
303 SECTION(
"has private creator tag") {
305 REQUIRE(ds.contains(private_creator_tag));
306 CHECK(ds.get_string(private_creator_tag) ==
"MY_PRIVATE_CREATOR");
309 SECTION(
"has private data tags") {
313 REQUIRE(ds.contains(private_data_1));
314 REQUIRE(ds.contains(private_data_2));
318TEST_CASE(
"test_data_generator::invalid creates datasets with specific errors",
"[data_generator][edge_case][invalid]") {
319 SECTION(
"missing_sop_class_uid") {
324 SECTION(
"missing_sop_instance_uid") {
329 SECTION(
"missing_patient_id") {
334 SECTION(
"missing_study_instance_uid") {
339 SECTION(
"corrupted_pixel_data") {
342 REQUIRE(pixel_elem !=
nullptr);
344 CHECK(pixel_elem->length() < 1000);
352TEST_CASE(
"test_data_generator::generate_uid creates unique UIDs",
"[data_generator][utility]") {
362 CHECK(uid1.find(
"1.2.826.0.1.3680043.9.9999") == 0);
365TEST_CASE(
"test_data_generator::current_date returns valid DICOM date",
"[data_generator][utility]") {
369 CHECK(date.length() == 8);
372 CHECK(std::all_of(date.begin(), date.end(), ::isdigit));
375TEST_CASE(
"test_data_generator::current_time returns valid DICOM time",
"[data_generator][utility]") {
379 CHECK(time.length() >= 6);
382 CHECK(std::all_of(time.begin(), time.end(), ::isdigit));
static core::dicom_dataset us_cine(uint32_t frames=60, const std::string &study_uid="")
Generate a multi-frame US cine dataset.
static core::dicom_dataset invalid(invalid_dataset_type type)
Generate an intentionally invalid dataset.
static std::string generate_uid(const std::string &root="1.2.826.0.1.3680043.9.9999")
Generate a unique UID for testing.
static core::dicom_dataset large(size_t target_size_mb)
Generate a large dataset for stress testing.
static core::dicom_dataset worklist(const std::string &patient_id="", const std::string &modality="CT")
Generate a worklist item dataset.
static core::dicom_dataset mr(const std::string &study_uid="")
Generate an MR Image dataset.
static core::dicom_dataset enhanced_ct(uint32_t frames=100, const std::string &study_uid="")
Generate an Enhanced CT multi-frame dataset.
static multi_modal_study patient_journey(const std::string &patient_id, const std::vector< std::string > &modalities={"CT", "MR", "XA"})
Generate a complete multi-modal patient study.
static core::dicom_dataset unicode()
Generate a dataset with Unicode patient names.
static core::dicom_dataset ct(const std::string &study_uid="")
Generate a CT Image dataset.
static core::dicom_dataset enhanced_mr(uint32_t frames=50, const std::string &study_uid="")
Generate an Enhanced MR multi-frame dataset.
static core::dicom_dataset us(const std::string &study_uid="")
Generate a single-frame US Image dataset.
static core::dicom_dataset xa(const std::string &study_uid="")
Generate a single-frame XA Image dataset.
static core::dicom_dataset with_private_tags(const std::string &creator_id="TEST PRIVATE CREATOR")
Generate a dataset with private tags.
static std::string current_time()
Get current time in DICOM TM format (HHMMSS)
static std::string current_date()
Get current date in DICOM DA format (YYYYMMDD)
static core::dicom_dataset xa_cine(uint32_t frames=30, const std::string &study_uid="")
Generate a multi-frame XA cine dataset.
@ missing_patient_id
Missing Patient ID.
@ missing_sop_class_uid
Missing SOP Class UID.
@ missing_study_instance_uid
Missing Study Instance UID.
@ missing_sop_instance_uid
Missing SOP Instance UID.
@ corrupted_pixel_data
Corrupted pixel data.
TEST_CASE("test_data_generator::ct generates valid CT dataset", "[data_generator][ct]")
constexpr std::string_view us_image_storage_uid
US Image Storage SOP Class UID (single-frame)
constexpr std::string_view xa_image_storage_uid
XA Image Storage SOP Class UID (single/multi-frame)
constexpr std::string_view us_multiframe_image_storage_uid
US Multi-frame Image Storage SOP Class UID (cine loops)
Comprehensive DICOM test data generators for integration testing.
constexpr dicom_tag number_of_frames