Repository: FHIR/sushi (ts)

Issue:
Consider populating title/description/name(?) in instances when possible
Authors have to use instances for any conformance resources other than SD, CS, and VS.  These conformance resources often have a `title` and `description`.  We should consider auto-populating these items from keywords (e.g., `Title:`, `Description:`) when the corresponding elements exist in the target instance type.

So far, we've avoided doing so since not all instances have these elements -- and we wanted to be consistent with our behavior across instances.  But in doing so, we're inconsistent w/ our behavior on other conformance types.

We may want to consider making this a configurable option (which means we would need to decide what the default behavior should be).  We also may want to look at the `name` element and see if we should autopopulate that (although the "name" authors give after `Instance:` is already used as the `id`).

See: https://chat.fhir.org/#narrow/stream/215610-shorthand/topic/instance.20title/near/266818927

Pull request description:
Allow name/description in Instances
Fixes #1003

Allows users to put a specified Title and/or Description in their instances. 
To test, use this: https://fshschool.org/FSHOnline/#/share/32OCOPB

If the Instance has the title and description filled out then it is working.

Patch:
diff --git a/src/export/InstanceExporter.ts b/src/export/InstanceExporter.ts
index e2483e7..8a83105 100644
--- a/src/export/InstanceExporter.ts
+++ b/src/export/InstanceExporter.ts
@@ -454,13 +454,30 @@ export class InstanceExporter implements Fishable {
     }
     if (fshDefinition.usage) {
       instanceDef._instanceMeta.usage = fshDefinition.usage;
-      if (
-        fshDefinition.usage === 'Definition' &&
-        instanceOfStructureDefinition.elements.some(
-          element => element.id === `${instanceOfStructureDefinition.type}.url`
-        )
-      ) {
-        instanceDef.url = `${this.tank.config.canonical}/${instanceOfStructureDefinition.type}/${fshDefinition.id}`;
+      if (fshDefinition.usage === 'Definition') {
+        if (
+          instanceOfStructureDefinition.elements.some(
+            element => element.id === `${instanceOfStructureDefinition.type}.url`
+          )
+        ) {
+          instanceDef.url = `${this.tank.config.canonical}/${instanceOfStructureDefinition.type}/${fshDefinition.id}`;
+        }
+        if (
+          fshDefinition.title &&
+          instanceOfStructureDefinition.elements.some(
+            element => element.id === `${instanceOfStructureDefinition.type}.title`
+          )
+        ) {
+          instanceDef.title = fshDefinition.title;
+        }
+        if (
+          fshDefinition.description &&
+          instanceOfStructureDefinition.elements.some(
+            element => element.id === `${instanceOfStructureDefinition.type}.description`
+          )
+        ) {
+          instanceDef.description = fshDefinition.description;
+        }
       }
     }
     if (isResource) {


Test patch:
diff --git a/test/export/InstanceExporter.test.ts b/test/export/InstanceExporter.test.ts
index 266a5ce..e979ae2 100644
--- a/test/export/InstanceExporter.test.ts
+++ b/test/export/InstanceExporter.test.ts
@@ -4998,6 +4998,68 @@ describe('InstanceExporter', () => {
         /CaretValueRule.*Instance.*File: Caret\.fsh.*Line: 1 - 3.*Applied in File: Insert\.fsh.*Applied on Line: 5 - 7/s
       );
     });
+
+    it('should populate title and description when specified for instances with #definition', () => {
+      // Instance: DemoQuestionnaire
+      // InstanceOf: Questionnaire
+      // Usage: #definition
+      // Title: "My Demo Questionnaire"
+      // Description: "My Demo Questionnaire's description"
+      //* name = "DemoQuestionnaire"
+      //* status = #draft
+      const goalInstance = new Instance('DemoQuestionnaire');
+      goalInstance.instanceOf = 'Questionnaire';
+      goalInstance.usage = 'Definition';
+      goalInstance.title = 'My Demo Questionnaire';
+      goalInstance.description = "My Demo Questionnaire's description";
+      const statusDraft = new AssignmentRule('status');
+      statusDraft.value = new FshCode('draft');
+      const nameDemo = new AssignmentRule('name');
+      nameDemo.value = new FshCode('DemoQuestionnaire');
+      goalInstance.rules.push(statusDraft, nameDemo);
+      const exported = exportInstance(goalInstance);
+      expect(exported.title).toMatch('My Demo Questionnaire');
+      expect(exported.description).toMatch("My Demo Questionnaire's description");
+    });
+
+    it("should not populate title and description when specified for instances that aren't #definition", () => {
+      // Instance: DemoQuestionnaire
+      // InstanceOf: Questionnaire
+      // Usage: #example
+      // Title: "My Demo Questionnaire"
+      // Description: "My Demo Questionnaire's description"
+      //* name = "DemoQuestionnaire"
+      //* status = #draft
+      const goalInstance = new Instance('DemoQuestionnaire');
+      goalInstance.instanceOf = 'Questionnaire';
+      goalInstance.usage = 'Example';
+      goalInstance.title = 'My Demo Questionnaire';
+      goalInstance.description = "My Demo Questionnaire's description";
+      const statusDraft = new AssignmentRule('status');
+      statusDraft.value = new FshCode('draft');
+      const nameDemo = new AssignmentRule('name');
+      nameDemo.value = new FshCode('DemoQuestionnaire');
+      goalInstance.rules.push(statusDraft, nameDemo);
+      const exported = exportInstance(goalInstance);
+      expect(exported.title).toBeUndefined();
+      expect(exported.description).toBeUndefined();
+    });
+
+    it("should not populate title and description for instances that don't have title or description (like Patient)", () => {
+      // Instance: JustAPatient
+      // InstanceOf: Patient
+      // Usage: #definition
+      // Title: "Just a Patient"
+      // Description: "This is just a patient"
+      const goalInstance = new Instance('JustAPatient');
+      goalInstance.instanceOf = 'Patient';
+      goalInstance.usage = 'Definition';
+      goalInstance.title = 'Just a Patient';
+      goalInstance.description = 'This is just a patient';
+      const exported = exportInstance(goalInstance);
+      expect(exported.title).toBeUndefined();
+      expect(exported.description).toBeUndefined();
+    });
   });
 });