compressedfhir 0.0.1__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.

Potentially problematic release.


This version of compressedfhir might be problematic. Click here for more details.

Files changed (41) hide show
  1. compressedfhir/__init__.py +0 -0
  2. compressedfhir/fhir/__init__.py +0 -0
  3. compressedfhir/fhir/base_resource_list.py +165 -0
  4. compressedfhir/fhir/fhir_bundle.py +291 -0
  5. compressedfhir/fhir/fhir_bundle_entry.py +234 -0
  6. compressedfhir/fhir/fhir_bundle_entry_list.py +82 -0
  7. compressedfhir/fhir/fhir_bundle_entry_request.py +71 -0
  8. compressedfhir/fhir/fhir_bundle_entry_response.py +64 -0
  9. compressedfhir/fhir/fhir_bundle_entry_search.py +75 -0
  10. compressedfhir/fhir/fhir_identifier.py +84 -0
  11. compressedfhir/fhir/fhir_link.py +63 -0
  12. compressedfhir/fhir/fhir_meta.py +47 -0
  13. compressedfhir/fhir/fhir_resource.py +163 -0
  14. compressedfhir/fhir/fhir_resource_list.py +143 -0
  15. compressedfhir/fhir/fhir_resource_map.py +193 -0
  16. compressedfhir/fhir/test/__init__.py +0 -0
  17. compressedfhir/fhir/test/test_bundle_entry.py +129 -0
  18. compressedfhir/fhir/test/test_bundle_entry_list.py +187 -0
  19. compressedfhir/fhir/test/test_bundle_entry_request.py +74 -0
  20. compressedfhir/fhir/test/test_bundle_entry_response.py +65 -0
  21. compressedfhir/fhir/test/test_fhir_bundle.py +245 -0
  22. compressedfhir/fhir/test/test_fhir_resource.py +225 -0
  23. compressedfhir/fhir/test/test_fhir_resource_list.py +160 -0
  24. compressedfhir/fhir/test/test_fhir_resource_map.py +293 -0
  25. compressedfhir/py.typed +0 -0
  26. compressedfhir/utilities/__init__.py +0 -0
  27. compressedfhir/utilities/compressed_dict/__init__.py +0 -0
  28. compressedfhir/utilities/compressed_dict/v1/__init__.py +0 -0
  29. compressedfhir/utilities/compressed_dict/v1/compressed_dict.py +635 -0
  30. compressedfhir/utilities/compressed_dict/v1/compressed_dict_access_error.py +2 -0
  31. compressedfhir/utilities/compressed_dict/v1/compressed_dict_storage_mode.py +50 -0
  32. compressedfhir/utilities/compressed_dict/v1/test/__init__.py +0 -0
  33. compressedfhir/utilities/compressed_dict/v1/test/test_compressed_dict.py +360 -0
  34. compressedfhir/utilities/fhir_json_encoder.py +30 -0
  35. compressedfhir/utilities/json_helpers.py +181 -0
  36. compressedfhir-0.0.1.dist-info/METADATA +28 -0
  37. compressedfhir-0.0.1.dist-info/RECORD +41 -0
  38. compressedfhir-0.0.1.dist-info/WHEEL +5 -0
  39. compressedfhir-0.0.1.dist-info/licenses/LICENSE +201 -0
  40. compressedfhir-0.0.1.dist-info/top_level.txt +2 -0
  41. tests/__init__.py +0 -0
@@ -0,0 +1,74 @@
1
+ from datetime import datetime, timezone
2
+
3
+ from compressedfhir.fhir.fhir_bundle_entry_request import FhirBundleEntryRequest
4
+
5
+
6
+ class TestBundleEntryRequest:
7
+ def test_init_default(self) -> None:
8
+ """Test initialization with default parameters."""
9
+ request = FhirBundleEntryRequest(url="https://example.com")
10
+ assert request.url == "https://example.com"
11
+ assert request.method == "GET"
12
+ assert request.ifModifiedSince is None
13
+ assert request.ifNoneMatch is None
14
+
15
+ def test_init_full(self) -> None:
16
+ """Test initialization with all parameters."""
17
+ now = datetime.now(timezone.utc)
18
+ request = FhirBundleEntryRequest(
19
+ url="https://example.com",
20
+ method="POST",
21
+ ifModifiedSince=now,
22
+ ifNoneMatch='W/"abc"',
23
+ )
24
+ assert request.url == "https://example.com"
25
+ assert request.method == "POST"
26
+ assert request.ifModifiedSince == now
27
+ assert request.ifNoneMatch == 'W/"abc"'
28
+
29
+ def test_to_dict_minimal(self) -> None:
30
+ """Test converting to dictionary with minimal parameters."""
31
+ request = FhirBundleEntryRequest(url="https://example.com")
32
+ result = request.dict()
33
+ assert result == {"url": "https://example.com", "method": "GET"}
34
+
35
+ def test_to_dict_full(self) -> None:
36
+ """Test converting to dictionary with all parameters."""
37
+ now = datetime.now(timezone.utc)
38
+ request = FhirBundleEntryRequest(
39
+ url="https://example.com",
40
+ method="POST",
41
+ ifModifiedSince=now,
42
+ ifNoneMatch='W/"abc"',
43
+ )
44
+ result = request.dict()
45
+ assert result == {
46
+ "url": "https://example.com",
47
+ "method": "POST",
48
+ "ifModifiedSince": now.isoformat(),
49
+ "ifNoneMatch": 'W/"abc"',
50
+ }
51
+
52
+ def test_from_dict_minimal(self) -> None:
53
+ """Test creating from dictionary with minimal parameters."""
54
+ data = {"url": "https://example.com", "method": "GET"}
55
+ request = FhirBundleEntryRequest.from_dict(data)
56
+ assert request.url == "https://example.com"
57
+ assert request.method == "GET"
58
+ assert request.ifModifiedSince is None
59
+ assert request.ifNoneMatch is None
60
+
61
+ def test_from_dict_full(self) -> None:
62
+ """Test creating from dictionary with all parameters."""
63
+ now = datetime.now(timezone.utc)
64
+ data = {
65
+ "url": "https://example.com",
66
+ "method": "POST",
67
+ "ifModifiedSince": now.isoformat(),
68
+ "ifNoneMatch": 'W/"abc"',
69
+ }
70
+ request = FhirBundleEntryRequest.from_dict(data)
71
+ assert request.url == "https://example.com"
72
+ assert request.method == "POST"
73
+ assert request.ifModifiedSince == now
74
+ assert request.ifNoneMatch == 'W/"abc"'
@@ -0,0 +1,65 @@
1
+ from datetime import datetime, timezone
2
+
3
+ from compressedfhir.fhir.fhir_bundle_entry_response import (
4
+ FhirBundleEntryResponse,
5
+ )
6
+
7
+
8
+ class TestBundleEntryResponse:
9
+ def test_init_default(self) -> None:
10
+ """Test initialization with default parameters."""
11
+ response = FhirBundleEntryResponse(status="200", etag=None, lastModified=None)
12
+ assert response.status == "200"
13
+ assert response.etag is None
14
+ assert response.lastModified is None
15
+
16
+ def test_init_full(self) -> None:
17
+ """Test initialization with all parameters."""
18
+ now = datetime.now(timezone.utc)
19
+ response = FhirBundleEntryResponse(
20
+ status="201", etag='W/"def"', lastModified=now
21
+ )
22
+ assert response.status == "201"
23
+ assert response.etag == 'W/"def"'
24
+ assert response.lastModified == now
25
+
26
+ def test_init_int_status(self) -> None:
27
+ """Test initialization with integer status."""
28
+ response = FhirBundleEntryResponse(status="200", etag=None, lastModified=None)
29
+ assert response.status == "200"
30
+
31
+ def test_to_dict_minimal(self) -> None:
32
+ """Test converting to dictionary with minimal parameters."""
33
+ response = FhirBundleEntryResponse(status="200", etag=None, lastModified=None)
34
+ result = response.dict()
35
+ assert result == {"status": "200"}
36
+
37
+ def test_to_dict_full(self) -> None:
38
+ """Test converting to dictionary with all parameters."""
39
+ now = datetime.now(timezone.utc)
40
+ response = FhirBundleEntryResponse(
41
+ status="201", etag='W/"def"', lastModified=now
42
+ )
43
+ result = response.dict()
44
+ assert result == {
45
+ "status": "201",
46
+ "lastModified": now.isoformat(),
47
+ "etag": 'W/"def"',
48
+ }
49
+
50
+ def test_from_dict_minimal(self) -> None:
51
+ """Test creating from dictionary with minimal parameters."""
52
+ data = {"status": "200"}
53
+ response = FhirBundleEntryResponse.from_dict(data)
54
+ assert response.status == "200"
55
+ assert response.etag is None
56
+ assert response.lastModified is None
57
+
58
+ def test_from_dict_full(self) -> None:
59
+ """Test creating from dictionary with all parameters."""
60
+ now = datetime.now(timezone.utc)
61
+ data = {"status": "201", "lastModified": now.isoformat(), "etag": 'W/"def"'}
62
+ response = FhirBundleEntryResponse.from_dict(data)
63
+ assert response.status == "201"
64
+ assert response.lastModified == now
65
+ assert response.etag == 'W/"def"'
@@ -0,0 +1,245 @@
1
+ import json
2
+
3
+ from compressedfhir.fhir.fhir_bundle import FhirBundle
4
+ from compressedfhir.fhir.fhir_bundle_entry import FhirBundleEntry
5
+ from compressedfhir.fhir.fhir_bundle_entry_list import FhirBundleEntryList
6
+ from compressedfhir.fhir.fhir_resource import FhirResource
7
+ from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode import (
8
+ CompressedDictStorageMode,
9
+ )
10
+
11
+
12
+ class TestBundle:
13
+ def test_init_minimal(self) -> None:
14
+ """Test initialization with minimal parameters."""
15
+ bundle = FhirBundle(type_="searchset")
16
+ assert bundle.type_ == "searchset"
17
+ assert len(bundle.entry) == 0
18
+ assert bundle.total is None
19
+ assert bundle.id_ is None
20
+ assert bundle.timestamp is None
21
+
22
+ def test_init_full(self) -> None:
23
+ """Test initialization with all parameters."""
24
+ entries = FhirBundleEntryList(
25
+ [
26
+ FhirBundleEntry(
27
+ resource={"resourceType": "Patient"},
28
+ request=None,
29
+ response=None,
30
+ storage_mode=CompressedDictStorageMode(),
31
+ ),
32
+ FhirBundleEntry(
33
+ resource={"resourceType": "Observation"},
34
+ request=None,
35
+ response=None,
36
+ storage_mode=CompressedDictStorageMode(),
37
+ ),
38
+ ]
39
+ )
40
+ bundle = FhirBundle(
41
+ type_="searchset",
42
+ entry=entries,
43
+ total=2,
44
+ id_="test-bundle",
45
+ timestamp="2023-12-01T12:00:00Z",
46
+ )
47
+ assert bundle.type_ == "searchset"
48
+ assert bundle.entry is not None
49
+ assert len(bundle.entry) == 2
50
+ assert bundle.total == 2
51
+ assert bundle.id_ == "test-bundle"
52
+ assert bundle.timestamp == "2023-12-01T12:00:00Z"
53
+
54
+ def test_to_dict_minimal(self) -> None:
55
+ """Test converting to dictionary with minimal parameters."""
56
+ bundle = FhirBundle(type_="searchset")
57
+ result = bundle.dict()
58
+ assert result == {"type": "searchset", "resourceType": "Bundle"}
59
+
60
+ def test_to_dict_full(self) -> None:
61
+ """Test converting to dictionary with all parameters."""
62
+ entries = FhirBundleEntryList(
63
+ [
64
+ FhirBundleEntry(
65
+ resource={"resourceType": "Patient"},
66
+ request=None,
67
+ response=None,
68
+ storage_mode=CompressedDictStorageMode(),
69
+ ),
70
+ FhirBundleEntry(
71
+ resource={"resourceType": "Observation"},
72
+ request=None,
73
+ response=None,
74
+ storage_mode=CompressedDictStorageMode(),
75
+ ),
76
+ ]
77
+ )
78
+ bundle = FhirBundle(
79
+ type_="searchset",
80
+ entry=entries,
81
+ total=2,
82
+ id_="test-bundle",
83
+ timestamp="2023-12-01T12:00:00Z",
84
+ )
85
+ result = bundle.dict()
86
+ assert result == {
87
+ "type": "searchset",
88
+ "resourceType": "Bundle",
89
+ "id": "test-bundle",
90
+ "timestamp": "2023-12-01T12:00:00Z",
91
+ "total": 2,
92
+ "entry": [
93
+ {"resource": {"resourceType": "Patient"}},
94
+ {"resource": {"resourceType": "Observation"}},
95
+ ],
96
+ }
97
+
98
+ def test_to_json(self) -> None:
99
+ """Test converting Bundle to JSON."""
100
+ entries = FhirBundleEntryList(
101
+ [
102
+ FhirBundleEntry(
103
+ resource={"resourceType": "Patient"},
104
+ request=None,
105
+ response=None,
106
+ storage_mode=CompressedDictStorageMode(),
107
+ ),
108
+ FhirBundleEntry(
109
+ resource={"resourceType": "Observation"},
110
+ request=None,
111
+ response=None,
112
+ storage_mode=CompressedDictStorageMode(),
113
+ ),
114
+ ]
115
+ )
116
+ bundle = FhirBundle(
117
+ type_="searchset",
118
+ entry=entries,
119
+ total=2,
120
+ id_="test-bundle",
121
+ timestamp="2023-12-01T12:00:00Z",
122
+ )
123
+ json_str = bundle.json()
124
+ parsed_json = json.loads(json_str)
125
+ assert parsed_json["type"] == "searchset"
126
+ assert parsed_json["resourceType"] == "Bundle"
127
+
128
+ def test_add_diagnostics_to_operation_outcomes(self) -> None:
129
+ """Test adding diagnostics to OperationOutcome resources."""
130
+ resource = FhirResource(
131
+ initial_dict={
132
+ "resourceType": "OperationOutcome",
133
+ "issue": [{"severity": "error", "details": {}}],
134
+ },
135
+ storage_mode=CompressedDictStorageMode(),
136
+ )
137
+ diagnostics_coding = [{"code": "test-code"}]
138
+
139
+ updated_resource = FhirBundle.add_diagnostics_to_operation_outcomes(
140
+ resource=resource, diagnostics_coding=diagnostics_coding
141
+ )
142
+
143
+ with updated_resource.transaction():
144
+ assert (
145
+ updated_resource["issue"][0]["details"]["coding"] == diagnostics_coding
146
+ )
147
+
148
+
149
+ class TestFhirBundleCopy:
150
+ def test_copy_full_bundle(self) -> None:
151
+ """
152
+ Test copying a fully populated FhirBundle
153
+ """
154
+ # Create a mock FhirBundleEntryList
155
+ mock_entry_list = FhirBundleEntryList()
156
+ mock_resource = FhirBundleEntry(
157
+ resource=FhirResource({"resourceType": "Patient", "id": "123"})
158
+ )
159
+ mock_entry_list.append(mock_resource)
160
+
161
+ # Create original bundle
162
+ original_bundle = FhirBundle(
163
+ id_="test-bundle-id",
164
+ timestamp="2023-01-01T00:00:00Z",
165
+ type_="transaction",
166
+ entry=mock_entry_list,
167
+ total=1,
168
+ )
169
+
170
+ # Create a copy
171
+ copied_bundle = original_bundle.copy()
172
+
173
+ # Assert that the copied bundle has the same attributes
174
+ assert copied_bundle.id_ == original_bundle.id_
175
+ assert copied_bundle.timestamp == original_bundle.timestamp
176
+ assert copied_bundle.type_ == original_bundle.type_
177
+ assert copied_bundle.total == original_bundle.total
178
+
179
+ # Ensure the entry list is a copy, not the same object
180
+ assert copied_bundle.entry is not original_bundle.entry
181
+ assert copied_bundle.entry is not None
182
+ assert original_bundle.entry is not None
183
+ assert len(copied_bundle.entry) == len(original_bundle.entry)
184
+ assert copied_bundle.entry[0].dict() == original_bundle.entry[0].dict()
185
+
186
+ def test_copy_empty_bundle(self) -> None:
187
+ """
188
+ Test copying a bundle with no entries
189
+ """
190
+ # Create an empty bundle
191
+ original_bundle = FhirBundle(type_="batch", entry=None, total=None)
192
+
193
+ # Create a copy
194
+ copied_bundle = original_bundle.copy()
195
+
196
+ # Assert that the copied bundle has the same attributes
197
+ assert copied_bundle.id_ is None
198
+ assert copied_bundle.timestamp is None
199
+ assert copied_bundle.type_ == "batch"
200
+ assert copied_bundle.total is None
201
+ assert len(copied_bundle.entry) == 0
202
+
203
+ def test_copy_modifying_original_does_not_affect_copy(self) -> None:
204
+ """
205
+ Test that modifying the original bundle does not affect the copy
206
+ """
207
+ # Create a mock FhirBundleEntryList
208
+ mock_entry_list = FhirBundleEntryList()
209
+ mock_resource = FhirResource({"resourceType": "Patient", "id": "123"})
210
+ mock_entry_list.append(FhirBundleEntry(resource=mock_resource))
211
+
212
+ # Create original bundle
213
+ original_bundle = FhirBundle(
214
+ id_="test-bundle-id",
215
+ timestamp="2023-01-01T00:00:00Z",
216
+ type_="transaction",
217
+ entry=mock_entry_list,
218
+ total=1,
219
+ )
220
+
221
+ # Create a copy
222
+ copied_bundle = original_bundle.copy()
223
+
224
+ # Modify the original bundle
225
+ original_bundle.id_ = "modified-id"
226
+ original_bundle.timestamp = "2023-02-01T00:00:00Z"
227
+ original_bundle.total = 2
228
+
229
+ # Assert that the copied bundle remains unchanged
230
+ assert copied_bundle.id_ == "test-bundle-id"
231
+ assert copied_bundle.timestamp == "2023-01-01T00:00:00Z"
232
+ assert copied_bundle.total == 1
233
+
234
+ def test_copy_returns_new_instance(self) -> None:
235
+ """
236
+ Test that copy() returns a new FhirBundle instance
237
+ """
238
+ # Create a bundle
239
+ original_bundle = FhirBundle(type_="batch")
240
+
241
+ # Create a copy
242
+ copied_bundle = original_bundle.copy()
243
+
244
+ # Assert that it's a different object
245
+ assert copied_bundle is not original_bundle
@@ -0,0 +1,225 @@
1
+ import json
2
+ from typing import Dict, Any
3
+
4
+ from compressedfhir.fhir.fhir_resource import FhirResource
5
+ from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode import (
6
+ CompressedDictStorageMode,
7
+ )
8
+
9
+
10
+ class TestFhirResource:
11
+ def test_init_empty(self) -> None:
12
+ """Test initializing FhirResource with no initial dictionary."""
13
+ resource = FhirResource(storage_mode=CompressedDictStorageMode())
14
+ assert len(resource) == 0
15
+ assert resource.resource_type is None
16
+ assert resource.id is None
17
+ assert resource.resource_type_and_id is None
18
+
19
+ def test_init_with_data(self) -> None:
20
+ """Test initializing FhirResource with a dictionary."""
21
+ initial_data: Dict[str, Any] = {
22
+ "resourceType": "Patient",
23
+ "id": "123",
24
+ "name": [{"given": ["John"]}],
25
+ }
26
+ resource = FhirResource(
27
+ initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
28
+ )
29
+
30
+ with resource.transaction():
31
+ assert resource.resource_type == "Patient"
32
+ assert resource.id == "123"
33
+ assert resource.resource_type_and_id == "Patient/123"
34
+ assert resource["name"][0]["given"][0] == "John"
35
+
36
+ def test_resource_type_and_id_property(self) -> None:
37
+ """Test resource_type_and_id property with various scenarios."""
38
+ # Scenario 1: Both resource type and id present
39
+ resource1 = FhirResource(
40
+ initial_dict={"resourceType": "Observation", "id": "456"},
41
+ storage_mode=CompressedDictStorageMode(),
42
+ )
43
+ assert resource1.resource_type_and_id == "Observation/456"
44
+
45
+ # Scenario 2: Missing resource type
46
+ resource2 = FhirResource(
47
+ initial_dict={"id": "789"}, storage_mode=CompressedDictStorageMode()
48
+ )
49
+ assert resource2.resource_type_and_id is None
50
+
51
+ # Scenario 3: Missing id
52
+ resource3 = FhirResource(
53
+ initial_dict={"resourceType": "Patient"},
54
+ storage_mode=CompressedDictStorageMode(),
55
+ )
56
+ assert resource3.resource_type_and_id is None
57
+
58
+ def test_equality(self) -> None:
59
+ """Test equality comparison between FhirResource instances."""
60
+ # Scenario 1: Equal resources
61
+ resource1 = FhirResource(
62
+ initial_dict={"resourceType": "Patient", "id": "123"},
63
+ storage_mode=CompressedDictStorageMode(),
64
+ )
65
+ resource2 = FhirResource(
66
+ initial_dict={"resourceType": "Patient", "id": "123"},
67
+ storage_mode=CompressedDictStorageMode(),
68
+ )
69
+ assert resource1 == resource2
70
+
71
+ # Scenario 2: Different resource types
72
+ resource3 = FhirResource(
73
+ initial_dict={"resourceType": "Observation", "id": "123"},
74
+ storage_mode=CompressedDictStorageMode(),
75
+ )
76
+ assert resource1 != resource3
77
+
78
+ # Scenario 3: Different ids
79
+ resource4 = FhirResource(
80
+ initial_dict={"resourceType": "Patient", "id": "456"},
81
+ storage_mode=CompressedDictStorageMode(),
82
+ )
83
+ assert resource1 != resource4
84
+
85
+ # Scenario 4: Comparing with non-FhirResource
86
+ assert resource1 != "Not a FhirResource"
87
+
88
+ def test_to_json(self) -> None:
89
+ """Test JSON serialization of FhirResource."""
90
+ initial_data: Dict[str, Any] = {
91
+ "resourceType": "Patient",
92
+ "id": "123",
93
+ "name": [{"given": ["John"]}],
94
+ }
95
+ resource = FhirResource(
96
+ initial_dict=initial_data, storage_mode=CompressedDictStorageMode()
97
+ )
98
+
99
+ json_str = resource.json()
100
+ parsed_json = json.loads(json_str)
101
+
102
+ assert parsed_json == initial_data
103
+ assert "resourceType" in parsed_json
104
+ assert "id" in parsed_json
105
+
106
+
107
+ class TestFhirResourceRemoveNulls:
108
+ def test_remove_nulls_simple_dict(self) -> None:
109
+ """
110
+ Test removing None values from a simple dictionary
111
+ """
112
+ initial_dict: Dict[str, Any] = {
113
+ "name": "John Doe",
114
+ "age": None,
115
+ "active": True,
116
+ "email": None,
117
+ }
118
+ resource = FhirResource(initial_dict=initial_dict)
119
+ resource.remove_nulls()
120
+
121
+ with resource.transaction():
122
+ # Check that None values are removed
123
+ assert "age" not in resource
124
+ assert "email" not in resource
125
+ assert resource.get("name") == "John Doe"
126
+ assert resource.get("active") is True
127
+
128
+ def test_remove_nulls_nested_dict(self) -> None:
129
+ """
130
+ Test removing None values from a nested dictionary
131
+ """
132
+ initial_dict: Dict[str, Any] = {
133
+ "patient": {
134
+ "name": "Jane Smith",
135
+ "contact": None,
136
+ "address": {"street": None, "city": "New York"},
137
+ },
138
+ "status": None,
139
+ }
140
+ resource = FhirResource(initial_dict=initial_dict)
141
+ resource.remove_nulls()
142
+
143
+ with resource.transaction():
144
+ assert "status" not in resource
145
+ assert "contact" not in resource.get("patient", {})
146
+ assert resource.get("patient", {}).get("address", {}).get("street") is None
147
+ assert (
148
+ resource.get("patient", {}).get("address", {}).get("city") == "New York"
149
+ )
150
+
151
+ def test_remove_nulls_list_of_dicts(self) -> None:
152
+ """
153
+ Test removing None values from a list of dictionaries
154
+ """
155
+ initial_dict: Dict[str, Any] = {
156
+ "patients": [
157
+ {"name": "Alice", "age": None},
158
+ {"name": "Bob", "age": 30},
159
+ {"name": None, "active": False},
160
+ ]
161
+ }
162
+ resource = FhirResource(initial_dict=initial_dict)
163
+ resource.remove_nulls()
164
+
165
+ with resource.transaction():
166
+ assert len(resource.get("patients", [])) == 3
167
+ assert resource.get("patients", [])[0].get("name") == "Alice"
168
+ assert resource.get("patients", [])[1].get("name") == "Bob"
169
+ assert resource.get("patients", [])[1].get("age") == 30
170
+
171
+ def test_remove_nulls_empty_dict(self) -> None:
172
+ """
173
+ Test removing None values from an empty dictionary
174
+ """
175
+ resource = FhirResource(initial_dict={})
176
+ resource.remove_nulls()
177
+
178
+ assert len(resource) == 0
179
+
180
+ def test_remove_nulls_no_changes(self) -> None:
181
+ """
182
+ Test removing None values when no None values exist
183
+ """
184
+ initial_dict: Dict[str, Any] = {
185
+ "name": "Test User",
186
+ "active": True,
187
+ "score": 100,
188
+ }
189
+ resource = FhirResource(initial_dict=initial_dict)
190
+ original_dict = resource.copy()
191
+ resource.remove_nulls()
192
+
193
+ assert resource == original_dict
194
+
195
+ def test_remove_nulls_with_custom_storage_mode(self) -> None:
196
+ """
197
+ Test removing None values with a custom storage mode
198
+ """
199
+ initial_dict: Dict[str, Any] = {
200
+ "name": "Custom Mode User",
201
+ "email": None,
202
+ "active": True,
203
+ }
204
+ resource = FhirResource(
205
+ initial_dict=initial_dict, storage_mode=CompressedDictStorageMode.default()
206
+ )
207
+ resource.remove_nulls()
208
+
209
+ with resource.transaction():
210
+ assert "email" not in resource
211
+ assert resource.get("name") == "Custom Mode User"
212
+ assert resource.get("active") is True
213
+
214
+ def test_remove_nulls_preserves_false_and_zero_values(self) -> None:
215
+ """
216
+ Test that False and 0 values are not removed
217
+ """
218
+ initial_dict: Dict[str, Any] = {"active": False, "score": 0, "name": None}
219
+ resource = FhirResource(initial_dict=initial_dict)
220
+ resource.remove_nulls()
221
+
222
+ with resource.transaction():
223
+ assert resource.get("active") is False
224
+ assert resource.get("score") == 0
225
+ assert "name" not in resource