nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: FHIR/sushi
Pull request #96 (2020-01-15 19:23:28)

Add meta.profile to Instance
This addresses https://standardhealthrecord.atlassian.net/browse/CIMPL-210.

An instance will now have a meta.profile field, which will contain the name of the profile that we are making an instance of.


Patch:
diff --git a/src/export/InstanceExporter.ts b/src/export/InstanceExporter.ts
index 91d2305..401a0d5 100644
--- a/src/export/InstanceExporter.ts
+++ b/src/export/InstanceExporter.ts
@@ -119,6 +119,11 @@ export class InstanceExporter {
     instanceDef.resourceType = instanceOfStructureDefinition.type; // ResourceType is determined by the StructureDefinition of the type
     instanceDef.instanceName = fshDefinition.id; // This is name of the instance in the FSH
 
+    // Add the SD we are making an instance of to meta.profile, as long as SD is not a base FHIR resource
+    // If we end up adding more metadata, we should wrap this in a setMetadata function
+    if (instanceOfStructureDefinition.derivation === 'constraint') {
+      instanceDef.meta = { profile: [instanceOfStructureDefinition.url] };
+    }
     // Set Fixed values based on the FSH rules and the Structure Definition
     instanceDef = this.setFixedValues(fshDefinition, instanceDef, instanceOfStructureDefinition);
 


Test patch:
diff --git a/test/export/InstanceExporter.test.ts b/test/export/InstanceExporter.test.ts
index 3b487b1..7926402 100644
--- a/test/export/InstanceExporter.test.ts
+++ b/test/export/InstanceExporter.test.ts
@@ -133,6 +133,21 @@ describe('InstanceExporter', () => {
       doc.instances.set(lipidInstance.name, lipidInstance);
     });
 
+    // Setting Metadata
+    it('should set meta.profile to the defining URL we are making an instance of', () => {
+      const exported = exporter.exportInstance(instance);
+      expect(exported.meta).toEqual({
+        profile: ['http://example.com/StructureDefinition/TestPatient']
+      });
+    });
+
+    it('should not set meta.profile when we are making an instance of a base resource', () => {
+      const boo = new Instance('Boo');
+      boo.instanceOf = 'Patient';
+      const exported = exporter.exportInstance(boo);
+      expect(exported.meta).toBeUndefined();
+    });
+
     // Fixing top level elements
     it('should fix top level elements that are fixed on the Structure Definition', () => {
       const fixedValRule = new FixedValueRule('active');
Repository: FHIR/sushi
Pull request #107 (2020-01-21 14:10:47)

Fix e.type is not iterable error
I noticed when running SUSHI that an error would pop up sometimes saying "e.type is not iterable". On an ElementDefinition, type is technically not required, and there were some places we were assuming type would exist as an array. This PR fixes the places where we made those assumptions so that the error doesn't happen.

kjmahalingam: Do we want a test for this now that we can ensure it functions correctly?
kjmahalingam: All checks pass for me, and the changes generally seem to work, though I still would like to see if there's anything to address with my comments above.
ngfreiter: Ok @kjmahalingam I added a test that would fail without this fix, so it shows this is working correctly. Is there a consensus with you and @cmoesel on if I should add extra handling to the `type` property?

Patch:
diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts
index bd62e66..a08604e 100644
--- a/src/fhirtypes/StructureDefinition.ts
+++ b/src/fhirtypes/StructureDefinition.ts
@@ -472,7 +472,7 @@ export class StructureDefinition {
     let matchingType: ElementDefinitionType;
     const matchingXElements = elements.filter(e => {
       if (e.path.endsWith('[x]')) {
-        for (const t of e.type) {
+        for (const t of e.type ?? []) {
           if (`${e.path.slice(0, -3)}${upperFirst(t.code)}` === fhirPath) {
             matchingType = t;
             return true;
@@ -529,7 +529,7 @@ export class StructureDefinition {
         pathPart.brackets.length === 1 ||
         e.sliceName === pathPart.brackets.slice(0, -1).join('/')
       ) {
-        for (const t of e.type) {
+        for (const t of e.type ?? []) {
           return (
             t.code === 'Reference' &&
             t.targetProfile &&


Test patch:
diff --git a/test/fhirtypes/StructureDefinition.test.ts b/test/fhirtypes/StructureDefinition.test.ts
index 1b96ede..57deeeb 100644
--- a/test/fhirtypes/StructureDefinition.test.ts
+++ b/test/fhirtypes/StructureDefinition.test.ts
@@ -238,6 +238,12 @@ describe('StructureDefinition', () => {
       expect(emailWorkEmail.sliceName).toBe('email/workEmail');
     });
 
+    it('should not crash when trying to find a non-existent slice containing elements without a type', () => {
+      // component.referenceRange does not have a type, this test verifies that this does not cause a crash
+      const componentFooSlice = observation.findElementByPath('component[FooSlice]', fisher);
+      expect(componentFooSlice).toBeUndefined();
+    });
+
     // Choices
     it('should make explicit a non-existent choice element by path', () => {
       const originalLength = observation.elements.length;
Repository: FHIR/sushi
Pull request #111 (2020-01-21 21:29:46)

Instance ids set by default
This PR addresses Github issue #103.

It defaults the `id` to the name specified in the FSH definition (the id in the FSH definition is already being defaulted to the name). If the id is set by a rule in the FSH file, it is overwritten in the exported instance. There are two tests to test both these cases.

jafeltra: Ah, that is the way I probably should have done this. I tried to do kind of the opposite by comparing it to an instances of InstanceDefinition, but I'll switch it now.
jafeltra: Last commit should address your comment @cmoesel. The "whole exported instance" is pretty minimal, but it is comparing to that simple JSON, so if we add an extra field at the top level later on, those two tests should fail.

Patch:
diff --git a/src/export/InstanceExporter.ts b/src/export/InstanceExporter.ts
index 2c60054..df1783d 100644
--- a/src/export/InstanceExporter.ts
+++ b/src/export/InstanceExporter.ts
@@ -120,6 +120,7 @@ export class InstanceExporter {
     let instanceDef = new InstanceDefinition();
     instanceDef.resourceType = instanceOfStructureDefinition.type; // ResourceType is determined by the StructureDefinition of the type
     instanceDef.instanceName = fshDefinition.id; // This is name of the instance in the FSH
+    instanceDef.id = fshDefinition.id;
 
     // Add the SD we are making an instance of to meta.profile, as long as SD is not a base FHIR resource
     // If we end up adding more metadata, we should wrap this in a setMetadata function


Test patch:
diff --git a/test/export/InstanceExporter.test.ts b/test/export/InstanceExporter.test.ts
index 94d3c98..513a9d8 100644
--- a/test/export/InstanceExporter.test.ts
+++ b/test/export/InstanceExporter.test.ts
@@ -150,6 +150,32 @@ describe('InstanceExporter', () => {
       expect(exported.meta).toBeUndefined();
     });
 
+    // Setting instance id
+    it('should set id to instance name by default', () => {
+      const myExamplePatient = new Instance('MyExample');
+      myExamplePatient.instanceOf = 'Patient';
+      const exported = exportInstance(myExamplePatient);
+      const expectedInstanceJSON = {
+        resourceType: 'Patient',
+        id: 'MyExample'
+      };
+      expect(exported.toJSON()).toEqual(expectedInstanceJSON);
+    });
+
+    it('should overwrite id if it is set by a rule', () => {
+      const myExamplePatient = new Instance('MyExample');
+      myExamplePatient.instanceOf = 'Patient';
+      const fixedValRule = new FixedValueRule('id');
+      fixedValRule.fixedValue = 'PatientA';
+      myExamplePatient.rules.push(fixedValRule);
+      const exported = exportInstance(myExamplePatient);
+      const expectedInstanceJSON = {
+        resourceType: 'Patient',
+        id: 'PatientA'
+      };
+      expect(exported.toJSON()).toEqual(expectedInstanceJSON);
+    });
+
     // Fixing top level elements
     it('should fix top level elements that are fixed on the Structure Definition', () => {
       const fixedValRule = new FixedValueRule('active');
Repository: FHIR/sushi
Pull request #118 (2020-01-22 15:58:48)

Remove resource-level extensions
Resources have extensions indicating their ballot status, maturity, workgroup, etc -- most of which is probably not appropriate for the profile.  Remove these extensions from the profile.  Addresses #116.


Patch:
diff --git a/src/export/StructureDefinitionExporter.ts b/src/export/StructureDefinitionExporter.ts
index 91f48e2..209b970 100644
--- a/src/export/StructureDefinitionExporter.ts
+++ b/src/export/StructureDefinitionExporter.ts
@@ -59,6 +59,8 @@ export class StructureDefinitionExporter implements Fishable {
         ];
       }
     }
+    // Remove the base-level extensions as they may not be valid in this context
+    delete structDef.extension;
   }
 
   /**


Test patch:
diff --git a/test/export/StructureDefinitionExporter.test.ts b/test/export/StructureDefinitionExporter.test.ts
index 6110d5c..4013142 100644
--- a/test/export/StructureDefinitionExporter.test.ts
+++ b/test/export/StructureDefinitionExporter.test.ts
@@ -88,6 +88,14 @@ describe('StructureDefinitionExporter', () => {
     expect(exported.derivation).toBe('constraint');
   });
 
+  it('should remove the base-level extensions from the parent resource', () => {
+    const profile = new Profile('Foo');
+    doc.profiles.set(profile.name, profile);
+    exporter.exportStructDef(profile);
+    const exported = pkg.profiles[0];
+    expect(exported.extension).toBeUndefined();
+  });
+
   it('should throw ParentNotDefinedError when parent resource is not found', () => {
     const profile = new Profile('Foo');
     profile.parent = 'Bar';
Repository: FHIR/sushi
Pull request #171 (2020-01-31 14:17:13)

Add show-inherited-invariants parameter
Adds the `show-inherited-invariants` parameter.

There was an update to the IG publisher yesterday, so if you update to the newest version, this parameter should work. An example to make sure it works it to look at the `CancerPatient` profile. You should no longer see the long list of constraints that you can see here: http://build.fhir.org/ig/HL7/fhir-mCODE-ig/branches/master/StructureDefinition-CancerPatient.html.


Patch:
diff --git a/src/ig/IGExporter.ts b/src/ig/IGExporter.ts
index 5625a10..4c48e19 100644
--- a/src/ig/IGExporter.ts
+++ b/src/ig/IGExporter.ts
@@ -105,6 +105,10 @@ export class IGExporter {
           {
             code: 'releaselabel',
             value: 'CI Build' // TODO: Make this configurable
+          },
+          {
+            code: 'show-inherited-invariants',
+            value: 'false' // TODO: Make this configurable
           }
         ]
       }


Test patch:
diff --git a/test/ig/IGExporter.test.ts b/test/ig/IGExporter.test.ts
index 7e132f9..ad6ec8b 100644
--- a/test/ig/IGExporter.test.ts
+++ b/test/ig/IGExporter.test.ts
@@ -232,6 +232,10 @@ describe('IGExporter', () => {
             {
               code: 'releaselabel',
               value: 'CI Build'
+            },
+            {
+              code: 'show-inherited-invariants',
+              value: 'false'
             }
           ]
         }
Repository: FHIR/sushi
Pull request #212 (2020-02-12 15:12:48)

Include sliceName in StructureDefinition diff
When an element with a sliceName is included in a differential, the
sliceName attribute is included. This is done in order to meet the
needs of the IG publisher.

A skipped test is added to prevent the sliceName attribute from
being changed by a CaretValueRule.


Patch:
diff --git a/src/fhirtypes/ElementDefinition.ts b/src/fhirtypes/ElementDefinition.ts
index a94d58a..ea5c177 100644
--- a/src/fhirtypes/ElementDefinition.ts
+++ b/src/fhirtypes/ElementDefinition.ts
@@ -320,8 +320,11 @@ export class ElementDefinition {
     diff.id = diff.diffId();
     // If the snapshot is a choice (e.g., value[x]), but the diff is a specific choice (e.g., valueString), then
     // remove the slicename property from the diff (it is implied and not required in the diff)
+    // If the snapshot is not a choice, the diff needs to have a sliceName, so use the original.
     if (this.path.endsWith('[x]') && !diff.path.endsWith('[x]')) {
       delete diff.sliceName;
+    } else if (original.sliceName && diff.sliceName == null) {
+      diff.sliceName = original.sliceName;
     }
     return diff;
   }


Test patch:
diff --git a/test/export/StructureDefinitionExporter.test.ts b/test/export/StructureDefinitionExporter.test.ts
index fcda15d..57b9d6b 100644
--- a/test/export/StructureDefinitionExporter.test.ts
+++ b/test/export/StructureDefinitionExporter.test.ts
@@ -1545,6 +1545,42 @@ describe('StructureDefinitionExporter', () => {
     });
   });
 
+  it('should include sliceName in a differential when an attribute of the slice is changed', () => {
+    const profile = new Profile('MustSlice');
+    profile.parent = 'resprate';
+    const mustCode = new FlagRule('code.coding[RespRateCode]');
+    mustCode.mustSupport = true;
+    profile.rules.push(mustCode);
+    exporter.exportStructDef(profile);
+    const sd = pkg.profiles[0];
+    const json = sd.toJSON();
+    expect(json.differential.element).toHaveLength(1);
+    expect(json.differential.element[0]).toEqual({
+      id: 'Observation.code.coding:RespRateCode',
+      path: 'Observation.code.coding',
+      sliceName: 'RespRateCode',
+      mustSupport: true
+    });
+  });
+
+  it.skip('should not change sliceName based on a CaretValueRule', () => {
+    const profile = new Profile('NameChange');
+    profile.parent = 'resprate';
+    const sliceChange = new CaretValueRule('code.coding[RespRateCode]');
+    sliceChange.caretPath = 'sliceName';
+    sliceChange.value = 'SomeOtherCode';
+    profile.rules.push(sliceChange);
+    exporter.exportStructDef(profile);
+    const sd = pkg.profiles[0];
+    const json = sd.toJSON();
+    expect(json.differential.element).toHaveLength(1);
+    expect(json.differential.element[0]).toEqual({
+      id: 'Observation.code.coding:RespRateCode',
+      path: 'Observation.code.coding',
+      sliceName: 'RespRateCode'
+    });
+  });
+
   // No duplicate structure definitions exported
   it('should not export duplicate structure definitions', () => {
     const profile = new Profile('Foo');
Repository: FHIR/sushi
Pull request #255 (2020-02-25 17:10:27)

Log error when SD is missing snapshot
This fixes https://github.com/FHIR/sushi/issues/248.

This doesn't add support for importing SDs that don't have a snapshot. But now we log an error and more gracefully alert the user that they can't import SDs that don't have a snapshot.


Patch:
diff --git a/src/errors/MissingSnapshotError.ts b/src/errors/MissingSnapshotError.ts
new file mode 100644
index 0000000..13c13a2
--- /dev/null
+++ b/src/errors/MissingSnapshotError.ts
@@ -0,0 +1,5 @@
+export class MissingSnapshotError extends Error {
+  constructor(public url: string) {
+    super(`Structure Definition ${url} is missing snapshot. Snapshot is required for import.`);
+  }
+}
diff --git a/src/errors/index.ts b/src/errors/index.ts
index 8820e85..692e35c 100644
--- a/src/errors/index.ts
+++ b/src/errors/index.ts
@@ -31,3 +31,4 @@ export * from './ParentNotDefinedError';
 export * from './PackageLoadError';
 export * from './DevPackageLoadError';
 export * from './CurrentPackageLoadError';
+export * from './MissingSnapshotError';
diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts
index 43c3569..00aa390 100644
--- a/src/fhirtypes/StructureDefinition.ts
+++ b/src/fhirtypes/StructureDefinition.ts
@@ -8,7 +8,7 @@ import {
 import { Meta } from './specialTypes';
 import { Identifier, CodeableConcept, Coding, Narrative, Resource, Extension } from './dataTypes';
 import { ContactDetail, UsageContext } from './metaDataTypes';
-import { CannotResolvePathError, InvalidElementAccessError } from '../errors';
+import { CannotResolvePathError, InvalidElementAccessError, MissingSnapshotError } from '../errors';
 import {
   getArrayIndex,
   setPropertyOnDefinitionInstance,
@@ -395,6 +395,8 @@ export class StructureDefinition {
         ed.structDef = sd;
         sd.elements.push(ed);
       }
+    } else {
+      throw new MissingSnapshotError(sd.url);
     }
     // And finally add back the inProgress field if it's there
     if (json.inProgress) {


Test patch:
diff --git a/test/fhirtypes/StructureDefinition.test.ts b/test/fhirtypes/StructureDefinition.test.ts
index af7f5bc..9de1010 100644
--- a/test/fhirtypes/StructureDefinition.test.ts
+++ b/test/fhirtypes/StructureDefinition.test.ts
@@ -93,6 +93,14 @@ describe('StructureDefinition', () => {
         new ElementDefinitionType('Period')
       ]);
     });
+
+    it('should throw a MissingSnapshotError when the StructureDefinition to load is missing a snapshot', () => {
+      const noSnapshotJsonObservation = defs.fishForFHIR('Observation', Type.Resource);
+      delete noSnapshotJsonObservation.snapshot;
+      expect(() => StructureDefinition.fromJSON(noSnapshotJsonObservation)).toThrow(
+        /http:\/\/hl7.org\/fhir\/StructureDefinition\/Observation is missing snapshot/
+      );
+    });
   });
 
   describe('#toJSON', () => {
Repository: FHIR/sushi
Pull request #266 (2020-03-03 17:34:31)

Catch errors arising from mismatched input
This fixes https://github.com/FHIR/sushi/issues/228.

When there is mismatched input like:
```
Profile: "BadProfileName"
```
The importer was emitting an error that the mismatched input was detected, but would then crash when parsing the input. This PR prevents that crash by catching the error during parsing and logging it.

To test this, try making a FSH file with mismatched input, strings where ANTLR expects SEQUENCE, or the reverse. The mismatched input will cause crashed on `master`, but should not cause crashes on this branch.


Patch:
diff --git a/src/import/FSHImporter.ts b/src/import/FSHImporter.ts
index 930e18c..2ab7511 100644
--- a/src/import/FSHImporter.ts
+++ b/src/import/FSHImporter.ts
@@ -177,7 +177,12 @@ export class FSHImporter extends FSHVisitor {
 
   visitDoc(ctx: pc.DocContext): void {
     ctx.entity().forEach(e => {
-      this.visitEntity(e);
+      try {
+        this.visitEntity(e);
+      } catch (err) {
+        const sourceInfo = { location: this.extractStartStop(e), file: this.currentFile };
+        logger.error(`Error in parsing: ${err.message}`, sourceInfo);
+      }
     });
   }
 


Test patch:
diff --git a/test/import/FSHImporter.test.ts b/test/import/FSHImporter.test.ts
index f19c8c1..c08c6ef 100644
--- a/test/import/FSHImporter.test.ts
+++ b/test/import/FSHImporter.test.ts
@@ -260,4 +260,25 @@ describe('FSHImporter', () => {
     expect(allLogs[1].level).toMatch(/info/);
     expect(allLogs[1].message).toMatch(/Imported 0 definitions/);
   });
+
+  it('should avoid crashing and log error messages because of mismatched input', () => {
+    const input = `
+    Profile: "BadProfile"
+  
+    Profile: BetterProfile
+    Id: "BadId"
+    Description: BadDescription
+    `;
+    const result = importSingleText(input, 'Mismatch.fsh');
+    const messages = loggerSpy.getAllMessages('error');
+    expect(messages).toHaveLength(5);
+    expect(messages[0]).toMatch(/BadProfile.*SEQUENCE.*File: Mismatch\.fsh.*Line: 2\D*/s);
+    expect(messages[1]).toMatch(/BadId.*SEQUENCE.*File: Mismatch\.fsh.*Line: 5\D*/s);
+    expect(messages[2]).toMatch(
+      /BadDescription.*{STRING, MULTILINE_STRING}.*File: Mismatch\.fsh.*Line: 6\D*/s
+    );
+    expect(messages[3]).toMatch(/Error in parsing.*File: Mismatch\.fsh.*Line: 2\D*/s);
+    expect(messages[4]).toMatch(/Error in parsing.*File: Mismatch\.fsh.*Line: 4 - 6\D*/s);
+    expect(result).toBeDefined();
+  });
 });
Repository: FHIR/sushi
Pull request #363 (2020-04-15 12:13:45)

Allow fixing values on slices with no discriminators
This fixes https://github.com/FHIR/sushi/issues/362. 

This was a new bug introduced in 0.12.0 that causes SUSHI to log an error when trying to fix a value on a slice for which the corresponding slicing does not have a discriminator. The issue contains a fully detailed example of this situation.

To test this, you can use the example shown in the issue to compare running SUSHI on that example on this branch, versus running SUSHI on that example on master. On master you will see the incorrect error message, and on this branch you should not. I also added a test of this situation.

cmoesel: It's irrelevant to the bug, but note that technically the example in the GH issue is invalid anyway -- because if there is no `slicing.discriminator` then there _must_ be a `slicing.description`:
![image](https://user-images.githubusercontent.com/2278253/79340652-9c731b80-7ef8-11ea-84c4-c3794e395ad5.png)

cmoesel: But I agree, the PR looks good!

Patch:
diff --git a/src/fhirtypes/ElementDefinition.ts b/src/fhirtypes/ElementDefinition.ts
index 1361bc2..fa36720 100644
--- a/src/fhirtypes/ElementDefinition.ts
+++ b/src/fhirtypes/ElementDefinition.ts
@@ -1172,7 +1172,7 @@ export class ElementDefinition {
     parentSlices.forEach(parentSlice => {
       const slicedElement = parentSlice.slicedElement();
       if (
-        slicedElement.slicing.discriminator.some(
+        slicedElement.slicing.discriminator?.some(
           d =>
             `${slicedElement.path}${d.path === '$this' ? '' : `.${d.path}`}` === this.path &&
             ['value', 'pattern'].includes(d.type)


Test patch:
diff --git a/test/fhirtypes/ElementDefinition.fixValue.test.ts b/test/fhirtypes/ElementDefinition.fixValue.test.ts
index 7924a53..ea0a819 100644
--- a/test/fhirtypes/ElementDefinition.fixValue.test.ts
+++ b/test/fhirtypes/ElementDefinition.fixValue.test.ts
@@ -166,6 +166,17 @@ describe('ElementDefinition', () => {
       expect(catMouseCoding.patternCoding).toEqual({ code: 'cheese' });
       expect(catMouseCoding.min).toBe(2); // We do not try to decrease min to 1
     });
+
+    it('should not ensure that minimum cardinality is 1 when fixing a value with no parent slice discriminator', () => {
+      const cat = medicationRequest.elements.find(e => e.id === 'MedicationRequest.category');
+      cat.slicing = { rules: 'open' };
+      cat.addSlice('mouse');
+      const catMouseCoding = medicationRequest.findElementByPath('category[mouse].coding', fisher);
+      expect(catMouseCoding.min).toBe(0);
+      catMouseCoding.fixValue(new FshCode('cheese'));
+      expect(catMouseCoding.patternCoding).toEqual({ code: 'cheese' });
+      expect(catMouseCoding.min).toBe(0); // We do not increase min, since no discriminator
+    });
   });
 
   describe('#fixedByDirectParent', () => {