Repository: FHIR/sushi
Pull request #550 (2020-07-27 20:21:35)

Fix numerical index with slice name bug
This fixes https://github.com/FHIR/sushi/issues/549.

The bug being fixed here seems to be a pretty specific case, and it might be easiest to understand by looking at the example in the linked issue. But in words, when we try to unroll (to find sub-elements) a child of an element which has slices (not one of the slices themselves, but rather the original sliced element), and at least one of those slices starts with the same sequence of characters as the original sliced element, the unrolling will fail. 

In the example shown in the issue, the `item.adjudication.amount` element is of type `Money`, but it cannot be unrolled correctly, because the `findElementByPath` function does not correctly differentiate between `item.adjudication` and `item.adjudication[adjudicationamounttype]`. Specifically, `item.adjudication[adjudicationamounttype]` should be filtered out, but it is not. This PR fixes the bug causing that element to not be filtered out, allowing the child element to be correctly unrolled. To test this, you can use the example in the issue. On `master` you will see an error saying:
```
The element or path you referenced does not exist: item.adjudication.amount.value
```
and `item.adjudication.amount.value` will not be set on the exported instance. On this branch, that error will go away, and the resulting exported instance will have `item.adjudication.amount.value` correctly set to 11.43. 


Patch:
diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts
index 7709c3b..e7c0148 100644
--- a/src/fhirtypes/StructureDefinition.ts
+++ b/src/fhirtypes/StructureDefinition.ts
@@ -266,7 +266,7 @@ export class StructureDefinition {
           // If matchingElement id ends with pathEnd:, then it is a slice
           // pathPart.brackets is null, so keep nonslices (no ":" in idEnd)
           // and choice slices since valueString is equivalent to value[x]:valueString
-          return !idEnd.includes(`${pathEnd}:`) || idEnd.includes(`${pathEnd}:${pathPart.base}`);
+          return !idEnd.includes(`${pathEnd}:`) || idEnd === `${pathEnd}:${pathPart.base}`;
         });
       }
     }


Test patch:
diff --git a/test/fhirtypes/StructureDefinition.test.ts b/test/fhirtypes/StructureDefinition.test.ts
index 583bede..03e774f 100644
--- a/test/fhirtypes/StructureDefinition.test.ts
+++ b/test/fhirtypes/StructureDefinition.test.ts
@@ -566,6 +566,15 @@ describe('StructureDefinition', () => {
       expect(foundRoot.id).toBe('Observation.category:VSCat.coding');
     });
 
+    it('should find a child that must be unrolled of an element with slices that contain the name of that element', () => {
+      const coding = respRate.findElement('Observation.code.coding');
+      // the codingSlice slice contains the name of the base element, coding, this was causing unrolling of children to fail
+      // since the codingSlice element was not correctly differentiated from the code.coding element
+      coding.addSlice('codingSlice');
+      const codingSliceId = respRate.findElementByPath('code.coding.system.id', fisher);
+      expect(codingSliceId).toBeDefined();
+    });
+
     it('should find a slice that only exists on a sliced element child', () => {
       const coding = respRate.findElementByPath('category.coding', fisher);
       coding.slicing = {