Skip to content

Commit

Permalink
Support for parents with versioned canonical URLs as their baseDefini…
Browse files Browse the repository at this point in the history
…tion (#1078)

* Log error when a type is based on a version, but sushi finds a different version

* Fixed tests

* Commit tests and fixtures in ElementDefinition.constrainType

* Update test/fhirtypes/ElementDefinition.constrainType.test.ts

Co-authored-by: Chris Moesel <[email protected]>

* Update test/fhirtypes/ElementDefinition.constrainType.test.ts

Co-authored-by: Chris Moesel <[email protected]>

* Spacing and phrasing changes

Co-authored-by: gthuran <Suma1-dumont>
Co-authored-by: Chris Moesel <[email protected]>
  • Loading branch information
guhanthuran and cmoesel authored May 16, 2022
1 parent 84c0d5e commit 0ce58dc
Show file tree
Hide file tree
Showing 13 changed files with 31,425 additions and 3 deletions.
1 change: 0 additions & 1 deletion src/export/InstanceExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,6 @@ export class InstanceExporter implements Fishable {
}

const instanceOfStructureDefinition = StructureDefinition.fromJSON(json);

let instanceDef = new InstanceDefinition();
instanceDef._instanceMeta.name = fshDefinition.id; // This is name of the instance in the FSH
if (fshDefinition.title) {
Expand Down
2 changes: 2 additions & 0 deletions src/export/Package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export class Package implements Fishable {
instanceUsage:
result instanceof InstanceDefinition ? result._instanceMeta.usage : undefined,
url: result.url,
version: result.version,
resourceType: result.resourceType
};
if (result instanceof StructureDefinition) {
Expand All @@ -152,6 +153,7 @@ export class Package implements Fishable {
url:
this.config.url ||
`${this.config.canonical}/ImplementationGuide/${this.config.packageId || this.config.id}`,
version: this.config.version,
resourceType: 'ImplementationGuide'
};
return metadata;
Expand Down
2 changes: 2 additions & 0 deletions src/fhirdefs/FHIRDefinitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export class FHIRDefinitions implements Fishable {
url: resource.url as string,
parent: resource.baseDefinition as string,
abstract: resource.abstract as boolean,
version: resource.version as string,
resourceType: resource.resourceType as string
};
}
Expand Down Expand Up @@ -257,6 +258,7 @@ export class FHIRDefinitions implements Fishable {
url: result.url as string,
parent: result.baseDefinition as string,
abstract: result.abstract as boolean,
version: result.version as string,
resourceType: result.resourceType as string
};
}
Expand Down
8 changes: 7 additions & 1 deletion src/fhirtypes/ElementDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1197,8 +1197,14 @@ export class ElementDefinition {
// Stop when we can't find a definition or the base definition is blank.
let currentType = type;
while (currentType != null) {
const result = fisher.fishForMetadata(currentType);
const [name, version] = currentType.split('|', 2);
const result = fisher.fishForMetadata(name);
if (result) {
if (version != null && result.version != null && result.version != version) {
logger.error(
`${type} is based on ${name} version ${version}, but SUSHI found version ${result.version}`
);
}
results.push(result);
}
currentType = result?.parent;
Expand Down
1 change: 1 addition & 0 deletions src/utils/Fishable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface Metadata {
url?: string;
parent?: string;
abstract?: boolean;
version?: string;
instanceUsage?: Instance['usage'];
}

Expand Down
4 changes: 4 additions & 0 deletions test/export/Package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ describe('Package', () => {
id: 'soup-flavors',
name: 'Soups',
url: 'http://hl7.org/fhir/us/minimal/ValueSet/soup-flavors',
version: '4.0.1',
resourceType: 'ValueSet'
});
expect(pkg.fishForMetadata('Soups', Type.ValueSet)).toEqual(soupsValueSetByID);
Expand All @@ -617,6 +618,7 @@ describe('Package', () => {
id: 'numerics',
name: 'Numbers',
url: 'http://hl7.org/fhir/us/minimal/CodeSystem/numerics',
version: '4.0.1',
resourceType: 'CodeSystem'
});
expect(pkg.fishForMetadata('Numbers', Type.CodeSystem)).toEqual(numericsCodeSystemByID);
Expand Down Expand Up @@ -783,6 +785,7 @@ describe('Package', () => {
id: 'soup-flavors',
name: 'Soups',
url: 'http://hl7.org/fhir/us/minimal/ValueSet/soup-flavors',
version: '4.0.1',
resourceType: 'ValueSet'
});
expect(pkg.fishForMetadata('Soups')).toEqual(soupsValueSetByID);
Expand All @@ -795,6 +798,7 @@ describe('Package', () => {
id: 'numerics',
name: 'Numbers',
url: 'http://hl7.org/fhir/us/minimal/CodeSystem/numerics',
version: '4.0.1',
resourceType: 'CodeSystem'
});
expect(pkg.fishForMetadata('Numbers')).toEqual(numericsCodeSystemByID);
Expand Down
16 changes: 16 additions & 0 deletions test/fhirdefs/FHIRDefinitions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ describe('FHIRDefinitions', () => {
name: 'Condition',
sdType: 'Condition',
url: 'http://hl7.org/fhir/StructureDefinition/Condition',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/DomainResource',
resourceType: 'StructureDefinition'
});
Expand All @@ -402,6 +403,7 @@ describe('FHIRDefinitions', () => {
name: 'ELTSSServiceModel',
sdType: 'eLTSSServiceModel',
url: 'http://hl7.org/fhir/us/eltss/StructureDefinition/eLTSSServiceModel',
version: '0.1.0',
parent: 'http://hl7.org/fhir/StructureDefinition/Element',
resourceType: 'StructureDefinition'
});
Expand All @@ -421,6 +423,7 @@ describe('FHIRDefinitions', () => {
name: 'boolean',
sdType: 'boolean',
url: 'http://hl7.org/fhir/StructureDefinition/boolean',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Element',
resourceType: 'StructureDefinition'
});
Expand All @@ -437,6 +440,7 @@ describe('FHIRDefinitions', () => {
name: 'Address',
sdType: 'Address',
url: 'http://hl7.org/fhir/StructureDefinition/Address',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Element',
resourceType: 'StructureDefinition'
});
Expand All @@ -453,6 +457,7 @@ describe('FHIRDefinitions', () => {
name: 'observation-vitalsigns',
sdType: 'Observation',
url: 'http://hl7.org/fhir/StructureDefinition/vitalsigns',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Observation',
resourceType: 'StructureDefinition'
});
Expand All @@ -473,6 +478,7 @@ describe('FHIRDefinitions', () => {
name: 'mothersMaidenName',
sdType: 'Extension',
url: 'http://hl7.org/fhir/StructureDefinition/patient-mothersMaidenName',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Extension',
resourceType: 'StructureDefinition'
});
Expand All @@ -496,6 +502,7 @@ describe('FHIRDefinitions', () => {
id: 'allergyintolerance-clinical',
name: 'AllergyIntoleranceClinicalStatusCodes',
url: 'http://hl7.org/fhir/ValueSet/allergyintolerance-clinical',
version: '4.0.1',
resourceType: 'ValueSet'
});
expect(defs.fishForMetadata('AllergyIntoleranceClinicalStatusCodes', Type.ValueSet)).toEqual(
Expand All @@ -518,6 +525,7 @@ describe('FHIRDefinitions', () => {
id: 'allergyintolerance-clinical',
name: 'AllergyIntoleranceClinicalStatusCodes',
url: 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical',
version: '4.0.1',
resourceType: 'CodeSystem'
});
expect(
Expand Down Expand Up @@ -657,6 +665,7 @@ describe('FHIRDefinitions', () => {
name: 'Condition',
sdType: 'Condition',
url: 'http://hl7.org/fhir/StructureDefinition/Condition',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/DomainResource',
resourceType: 'StructureDefinition'
});
Expand All @@ -671,6 +680,7 @@ describe('FHIRDefinitions', () => {
name: 'boolean',
sdType: 'boolean',
url: 'http://hl7.org/fhir/StructureDefinition/boolean',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Element',
resourceType: 'StructureDefinition'
});
Expand All @@ -685,6 +695,7 @@ describe('FHIRDefinitions', () => {
name: 'Address',
sdType: 'Address',
url: 'http://hl7.org/fhir/StructureDefinition/Address',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Element',
resourceType: 'StructureDefinition'
});
Expand All @@ -699,6 +710,7 @@ describe('FHIRDefinitions', () => {
name: 'observation-vitalsigns',
sdType: 'Observation',
url: 'http://hl7.org/fhir/StructureDefinition/vitalsigns',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Observation',
resourceType: 'StructureDefinition'
});
Expand All @@ -714,6 +726,7 @@ describe('FHIRDefinitions', () => {
name: 'mothersMaidenName',
sdType: 'Extension',
url: 'http://hl7.org/fhir/StructureDefinition/patient-mothersMaidenName',
version: '4.0.1',
parent: 'http://hl7.org/fhir/StructureDefinition/Extension',
resourceType: 'StructureDefinition'
});
Expand All @@ -729,6 +742,7 @@ describe('FHIRDefinitions', () => {
id: 'allergyintolerance-clinical',
name: 'AllergyIntoleranceClinicalStatusCodes',
url: 'http://hl7.org/fhir/ValueSet/allergyintolerance-clinical',
version: '4.0.1',
resourceType: 'ValueSet'
});
expect(defs.fishForMetadata('AllergyIntoleranceClinicalStatusCodes')).toEqual(
Expand All @@ -743,6 +757,7 @@ describe('FHIRDefinitions', () => {
id: 'w3c-provenance-activity-type',
name: 'W3cProvenanceActivityType',
url: 'http://hl7.org/fhir/w3c-provenance-activity-type',
version: '4.0.1',
resourceType: 'CodeSystem'
});
expect(defs.fishForMetadata('W3cProvenanceActivityType')).toEqual(
Expand All @@ -760,6 +775,7 @@ describe('FHIRDefinitions', () => {
parent: 'http://hl7.org/fhir/StructureDefinition/Element',
sdType: 'eLTSSServiceModel',
url: 'http://hl7.org/fhir/us/eltss/StructureDefinition/eLTSSServiceModel',
version: '0.1.0',
resourceType: 'StructureDefinition'
});
expect(defs.fishForMetadata('ELTSSServiceModel')).toEqual(eLTSSServiceModelByID);
Expand Down
43 changes: 42 additions & 1 deletion test/fhirtypes/ElementDefinition.constrainType.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TestFisher } from '../testhelpers';
import { TestFisher, loggerSpy } from '../testhelpers';
import { loadFromPath } from '../../src/fhirdefs/load';
import { FHIRDefinitions } from '../../src/fhirdefs/FHIRDefinitions';
import { StructureDefinition } from '../../src/fhirtypes/StructureDefinition';
Expand Down Expand Up @@ -31,6 +31,7 @@ describe('ElementDefinition', () => {
});

beforeEach(() => {
loggerSpy.reset();
observation = fisher.fishForStructureDefinition('Observation');
planDefinition = fisher.fishForStructureDefinition('PlanDefinition');
extension = fisher.fishForStructureDefinition('Extension');
Expand Down Expand Up @@ -338,6 +339,46 @@ describe('ElementDefinition', () => {
);
});

it('should allow us to constrain a reference to a profile whose parent is specified using a versioned canonical URL', () => {
const hasMember = observation.elements.find(e => e.id === 'Observation.hasMember');
const hasMemberConstraint = new OnlyRule('hasMember');
hasMemberConstraint.types = [
{
type: 'https://fhir.kbv.de/StructureDefinition/KBV_PR_Base_Observation_Body_Weight',
isReference: true
}
];
hasMember.constrainType(hasMemberConstraint, fisher);
expect(hasMember.type).toHaveLength(1);
expect(hasMember.type[0]).toEqual(
new ElementDefinitionType('Reference').withTargetProfiles(
'https://fhir.kbv.de/StructureDefinition/KBV_PR_Base_Observation_Body_Weight'
)
);
expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
});

it('should log an error when constraining a reference to a profile whose parent is specified using the wrong version', () => {
const hasMember = observation.elements.find(e => e.id === 'Observation.hasMember');
const hasMemberConstraint = new OnlyRule('hasMember');
hasMemberConstraint.types = [
{
type: 'https://fhir.kbv.de/StructureDefinition/KBV_PR_Base_Observation_Body_Weight-wrong-parent',
isReference: true
}
];
hasMember.constrainType(hasMemberConstraint, fisher);
expect(hasMember.type).toHaveLength(1);
expect(hasMember.type[0]).toEqual(
new ElementDefinitionType('Reference').withTargetProfiles(
'https://fhir.kbv.de/StructureDefinition/KBV_PR_Base_Observation_Body_Weight-wrong-parent'
)
);
expect(loggerSpy.getLastMessage('error')).toBe(
'https://fhir.kbv.de/StructureDefinition/KBV_PR_Base_Observation_Body_Weight-wrong-parent is based on http://fhir.de/StructureDefinition/observation-de-vitalsign-koerpergewicht version 0.9.34, but SUSHI found version 0.9.13'
);
});

it('should allow a resource type in a reference to multiple types to be constrained to a resource and a single profile', () => {
const subject = observation.elements.find(e => e.id === 'Observation.subject');
const subjectConstraint = new OnlyRule('subject');
Expand Down
Loading

0 comments on commit 0ce58dc

Please sign in to comment.