Repository: FHIR/sushi
Pull request #921 (2021-09-24 21:29:44)

Show error when inserting RuleSet with concepts at a path
Completes task [CIMPL-807](https://standardhealthrecord.atlassian.net/browse/CIMPL-807).

If a RuleSet is inserted at a path, that path is the context for the rules in the RuleSet. However, a ConceptRule should not have a path as context. So, if a RuleSet that contains a ConceptRule is inserted at a path, show an error so that the author knows that this should not be done. The ConceptRule should still be applied.

mint-thompson: @jafeltra The reason why I think an error is deserved here is because if we think of how the RuleSet's rules would get applied, it becomes something that isn't syntactically valid FSH:
```
* somePath #someCode "Some code"
```
This would result in an error from the importer. So, I feel like the situation in this PR is equivalent.

Patch:
diff --git a/src/fhirtypes/common.ts b/src/fhirtypes/common.ts
index f37faa7..765b70e 100644
--- a/src/fhirtypes/common.ts
+++ b/src/fhirtypes/common.ts
@@ -491,6 +491,14 @@ export function applyInsertRules(
             ruleSetRuleClone.path = newPath;
           }
           if (ruleSetRuleClone instanceof ConceptRule && fshDefinition instanceof FshCodeSystem) {
+            // ConceptRules should not have a path context, so if one exists, show an error.
+            // The concept is still added to the CodeSystem.
+            if (context) {
+              logger.error(
+                'Do not insert a RuleSet at a path when the RuleSet adds a concept.',
+                ruleSetRuleClone.sourceInfo
+              );
+            }
             try {
               if (fshDefinition.checkConcept(ruleSetRuleClone)) {
                 expandedRules.push(ruleSetRuleClone);


Test patch:
diff --git a/test/fhirtypes/applyInsertRules.test.ts b/test/fhirtypes/applyInsertRules.test.ts
index 48823a8..a85e5a7 100644
--- a/test/fhirtypes/applyInsertRules.test.ts
+++ b/test/fhirtypes/applyInsertRules.test.ts
@@ -451,6 +451,35 @@ describe('applyInsertRules', () => {
     );
   });
 
+  it('should log an error when a ConceptRule is inserted at a path', () => {
+    // RuleSet: Bar
+    // * #bear "Bear"
+    //
+    // CodeSystem: MyCodeSystem
+    // * somePath insert Bar
+    const cs = new FshCodeSystem('MyCodeSystem');
+    doc.codeSystems.set(cs.name, cs);
+
+    const concept = new ConceptRule('bear', 'Bear')
+      .withFile('RuleSets.fsh')
+      .withLocation([7, 5, 7, 12]);
+    ruleSet1.rules.push(concept);
+
+    const insertRule = new InsertRule('somePath')
+      .withFile('CodeSystems.fsh')
+      .withLocation([3, 5, 3, 19]);
+    insertRule.ruleSet = 'Bar';
+    cs.rules.push(insertRule);
+
+    applyInsertRules(cs, tank);
+
+    expect(cs.rules).toHaveLength(1);
+    assertConceptRule(cs.rules[0], 'bear', 'Bear', undefined, []);
+    expect(loggerSpy.getLastMessage('error')).toMatch(
+      /Do not insert a RuleSet at a path when the RuleSet adds a concept\..*File: RuleSets\.fsh.*Line: 7.*Applied in File: CodeSystems\.fsh.*Line: 3\D*/s
+    );
+  });
+
   it('should not convert a ConceptRule to a ValueSetConceptComponent when applying to a Profile', () => {
     // RuleSet: Bar
     // * ZOO#bear "brown bear"