Skip to content

Commit

Permalink
adding conditional for checking same name with entities, start to tests
Browse files Browse the repository at this point in the history
  • Loading branch information
KaelynJefferson committed Sep 23, 2024
1 parent 04b9d7b commit fbb11a7
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 1 deletion.
24 changes: 24 additions & 0 deletions src/export/CodeSystemExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ export class CodeSystemExporter {
fshDefinition.rules.filter(rule => rule instanceof CaretValueRule) as CaretValueRule[]
);

// TODO: move below push to codeSystems?
// check for another code system with the same id
// see https://www.hl7.org/fhir/resource.html#id
if (this.pkg.codeSystems.some(cs => codeSystem.id === cs.id)) {
Expand All @@ -304,6 +305,29 @@ export class CodeSystemExporter {
fshName: fshDefinition.name,
fshType: 'CodeSystem'
});


// check for another entity with same name
if (
// instances
this.pkg.instances.some(instance => codeSystem.name === instance._instanceMeta.name) ||
// structdef
this.pkg.profiles.some(prof => codeSystem.name === prof.name) ||
this.pkg.extensions.some(extn => codeSystem.name === extn.name ) ||
this.pkg.logicals.some(logical => codeSystem.name === logical.name ) ||
this.pkg.resources.some(resource => codeSystem.name === resource.name ) ||
// valueset
this.pkg.valueSets.some(valueSet => (codeSystem.name === valueSet.name)) || // && (codeSystem !== valueSet)
// code system
this.pkg.codeSystems.some(cs => codeSystem.name === cs.name)
) {
logger.error(
`Multiple FSH entities created with name ${
codeSystem.name
}.`
);
}

return codeSystem;
}

Expand Down
21 changes: 21 additions & 0 deletions src/export/InstanceExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -963,6 +963,27 @@ export class InstanceExporter implements Fishable {
);
}

// check for another entity with same name
if (
// instances
this.pkg.instances.some(instance => instanceDef._instanceMeta.name === instance._instanceMeta.name ) ||
// structdef
this.pkg.profiles.some(prof => instanceDef._instanceMeta.name === prof.name ) ||
this.pkg.extensions.some(extn => instanceDef._instanceMeta.name === extn.name ) ||
this.pkg.logicals.some(logical => instanceDef._instanceMeta.name === logical.name ) ||
this.pkg.resources.some(resource => instanceDef._instanceMeta.name === resource.name ) ||
// valueset
this.pkg.valueSets.some(valueSet => instanceDef._instanceMeta.name === valueSet.name) ||
// code system
this.pkg.codeSystems.some(cs => instanceDef._instanceMeta.name === cs.name)
) {
logger.error(
`Multiple FSH entities created with name ${
instanceDef._instanceMeta.name
}.`
);
}

return instanceDef;
}

Expand Down
21 changes: 21 additions & 0 deletions src/export/StructureDefinitionExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1419,6 +1419,27 @@ export class StructureDefinitionExporter implements Fishable {
);
}

// check for another entity with same name
if (
// instances
this.pkg.instances.some(instance => structDef.name === instance._instanceMeta.name) ||
// structdef
this.pkg.profiles.some(prof => structDef.name === prof.name) || // && (structDef !== prof)
this.pkg.extensions.some(extn => structDef.name === extn.name ) || // && (structDef !== extn)
this.pkg.logicals.some(logical => structDef.name === logical.name ) || // && (structDef !== logical)
this.pkg.resources.some(resource => structDef.name === resource.name ) || // && (structDef !== resource)
// valueset
this.pkg.valueSets.some(valueSet => structDef.name === valueSet.name) ||
// code system
this.pkg.codeSystems.some(cs => structDef.name === cs.name)
) {
logger.error(
`Multiple FSH entities created with name ${
structDef.name
}.`
);
}

return structDef;
}

Expand Down
23 changes: 23 additions & 0 deletions src/export/ValueSetExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ export class ValueSetExporter {
throw new ValueSetComposeError(fshDefinition.name);
}

// TODO: move below push to valueSets?
// check for another value set with the same id
// see https://www.hl7.org/fhir/resource.html#id
if (this.pkg.valueSets.some(valueSet => vs.id === valueSet.id)) {
Expand All @@ -465,6 +466,28 @@ export class ValueSetExporter {
fshName: fshDefinition.name,
fshType: 'ValueSet'
});

// check for another entity with same name
if (
// instances
this.pkg.instances.some(instance => vs.name === instance._instanceMeta.name) ||
// structdef
this.pkg.profiles.some(prof => vs.name === prof.name) ||
this.pkg.extensions.some(extn => vs.name === extn.name ) ||
this.pkg.logicals.some(logical => vs.name === logical.name ) ||
this.pkg.resources.some(resource => vs.name === resource.name ) ||
// valueset
this.pkg.valueSets.some(valueSet => vs.name === valueSet.name) || // && (vs !== valueSet)
// code system
this.pkg.codeSystems.some(cs => vs.name === cs.name)
) {
logger.error(
`Multiple FSH entities created with name ${
vs.name
}.`
);
}

return vs;
}
}
34 changes: 34 additions & 0 deletions test/export/CodeSystemExporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,40 @@ describe('CodeSystemExporter', () => {
expect(loggerSpy.getLastMessage('error')).toMatch(/File: CodeSystems\.fsh.*Line: 8 - 15\D*/s);
});

it('should log an error when multiple entities have the same name', () => {
const firstCodeSystem = new FshCodeSystem('FirstCodeSystem')
.withFile('CodeSystems.fsh')
.withLocation([2, 8, 6, 15]);
firstCodeSystem.id = 'my-code-system-one';
const secondCodeSystem = new FshCodeSystem('SecondCodeSystem')
.withFile('CodeSystems.fsh')
.withLocation([8, 8, 15, 19]);
secondCodeSystem.id = 'my-code-system-two';
doc.codeSystems.set(firstCodeSystem.name, firstCodeSystem);
doc.codeSystems.set(secondCodeSystem.name, secondCodeSystem);
exporter.exportCodeSystem(firstCodeSystem);
exporter.exportCodeSystem(secondCodeSystem);
expect(loggerSpy.getAllMessages('error')).toHaveLength(2); // TODO
expect(loggerSpy.getLastMessage()).toMatch(/Multiple FSH entities created with name/s);
});

it('should log an error when multiple entities of different types have the same name', () => {
const firstCodeSystem = new FshCodeSystem('FirstCodeSystem')
.withFile('CodeSystems.fsh')
.withLocation([2, 8, 6, 15]);
firstCodeSystem.id = 'my-code-system-one';
const secondCodeSystem = new FshCodeSystem('SecondCodeSystem')
.withFile('CodeSystems.fsh')
.withLocation([8, 8, 15, 19]);
secondCodeSystem.id = 'my-code-system-two';
doc.codeSystems.set(firstCodeSystem.name, firstCodeSystem);
doc.codeSystems.set(secondCodeSystem.name, secondCodeSystem);
exporter.exportCodeSystem(firstCodeSystem);
exporter.exportCodeSystem(secondCodeSystem);
expect(loggerSpy.getAllMessages('error')).toHaveLength(2); // TODO
expect(loggerSpy.getLastMessage('error')).toMatch(/Multiple FSH entities created with name/s);
});

// CaretValueRules
it('should apply a CaretValueRule', () => {
const codeSystem = new FshCodeSystem('CaretCodeSystem');
Expand Down
29 changes: 29 additions & 0 deletions test/export/InstanceExporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,35 @@ describe('InstanceExporter', () => {
expect(loggerSpy.getAllMessages('error')).toHaveLength(0);
});

it('should log an error when multiple entities have the same name', () => {
const myExamplePatient = new Instance('MySameExampleName');
myExamplePatient.instanceOf = 'Patient';
doc.instances.set(myExamplePatient.name, myExamplePatient);

const secondExamplePractitioner = new Instance('MySameExampleName');
myExamplePatient.instanceOf = 'Practitioner';
doc.instances.set(secondExamplePractitioner.name, secondExamplePractitioner);

exporter.exportInstance(myExamplePatient);
exporter.exportInstance(secondExamplePractitioner);
expect(loggerSpy.getAllMessages('error')).toHaveLength(1);
expect(loggerSpy.getLastMessage()).toMatch(/Multiple FSH entities created with name/s);
});

it('should log an error when multiple entities of different types have the same name', () => {
const myExamplePatient = new Instance('MySameExampleName');
myExamplePatient.instanceOf = 'Patient';
doc.instances.set(myExamplePatient.name, myExamplePatient);

const codeSystem = new FshCodeSystem('MySameExampleName');
doc.codeSystems.set(codeSystem.name, codeSystem);

exporter.exportInstance(myExamplePatient);
csExporter.exportCodeSystem(codeSystem);
expect(loggerSpy.getAllMessages('error')).toHaveLength(2); // TODO
expect(loggerSpy.getLastMessage()).toMatch(/Multiple FSH entities created with name/s);
});

it('should not log an error when multiple inline instances of the same type have the same id', () => {
// Inline instances will typically not have an id assigned to them
const firstQuantity = new Instance('FirstQuantity');
Expand Down
41 changes: 40 additions & 1 deletion test/export/StructureDefinitionExporter.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { loadFromPath } from 'fhir-package-loader';
import { StructureDefinitionExporter, Package } from '../../src/export';
import { StructureDefinitionExporter, Package, InstanceExporter } from '../../src/export';
import { FSHTank, FSHDocument } from '../../src/import';
import { FHIRDefinitions } from '../../src/fhirdefs';
import {
Expand Down Expand Up @@ -50,6 +50,7 @@ describe('StructureDefinitionExporter R4', () => {
let doc: FSHDocument;
let pkg: Package;
let exporter: StructureDefinitionExporter;
let inExporter: InstanceExporter;

beforeAll(() => {
defs = new FHIRDefinitions();
Expand Down Expand Up @@ -115,6 +116,7 @@ describe('StructureDefinitionExporter R4', () => {
pkg = new Package(input.config);
fisher = new TestFisher(input, defs, pkg);
exporter = new StructureDefinitionExporter(input, pkg, fisher);
inExporter = new InstanceExporter(input, pkg, fisher);
});

describe('#StructureDefinition', () => {
Expand Down Expand Up @@ -1006,6 +1008,43 @@ describe('StructureDefinitionExporter R4', () => {
expect(exported.name).toBe('Foo');
expect(exported.status).toBe('draft');
});
it('should log an error when multiple entities have the same name', () => {
const firstProfile = new Profile('ExampleProfile')
.withFile('Profiles.fsh')
.withLocation([2, 8, 6, 25]);
firstProfile.id = 'my-profile-one';
firstProfile.parent = 'Basic';

const secondProfile = new Profile('ExampleProfile')
.withFile('Profiles.fsh')
.withLocation([8, 8, 11, 25]);
secondProfile.id = 'my-profile-two';
secondProfile.parent = 'Basic';
doc.profiles.set(firstProfile.name, firstProfile);
doc.profiles.set(secondProfile.name, secondProfile);
exporter.export();
expect(loggerSpy.getAllMessages('error')).toHaveLength(1);
expect(loggerSpy.getLastMessage('error')).toMatch(/Multiple FSH entities created with name/s);
});

it('should log an error when multiple entities of different types have the same name', () => {
const firstProfile = new Profile('SameExampleName')
.withFile('Profiles.fsh')
.withLocation([2, 8, 6, 25]);
firstProfile.id = 'my-profile-one';
firstProfile.parent = 'Basic';

const myExamplePatient = new Instance('SameExampleName');
myExamplePatient.instanceOf = 'Patient';
doc.instances.set(myExamplePatient.name, myExamplePatient);

doc.profiles.set(firstProfile.name, firstProfile);
exporter.export();
inExporter.exportInstance(myExamplePatient);

expect(loggerSpy.getAllMessages('error')).toHaveLength(2); // TODO
expect(loggerSpy.getLastMessage('error')).toMatch(/Multiple FSH entities created with name/s);
});

it('should log an error when multiple profiles have the same id', () => {
const firstProfile = new Profile('FirstProfile')
Expand Down
13 changes: 13 additions & 0 deletions test/export/ValueSetExporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,19 @@ describe('ValueSetExporter', () => {
expect(loggerSpy.getLastMessage('error')).toMatch(/File: ValueSets\.fsh.*Line: 7 - 9\D*/s);
});

it('should log an error when multiple entities have the same name', () => {
const breakfast = new FshValueSet('BreakfastVS');
breakfast.id = 'first-value-set';
const dinner = new FshValueSet('BreakfastVS');
dinner.id = 'second-value-set';
doc.valueSets.set(breakfast.name, breakfast);
doc.valueSets.set(dinner.name, dinner);
exporter.exportValueSet(breakfast);
exporter.exportValueSet(dinner);
expect(loggerSpy.getAllMessages('error')).toHaveLength(1);
expect(loggerSpy.getLastMessage('error')).toMatch(/Multiple FSH entities created with name/s);
});

it('should export each value set once, even if export is called more than once', () => {
const breakfast = new FshValueSet('BreakfastVS');
doc.valueSets.set(breakfast.name, breakfast);
Expand Down

0 comments on commit fbb11a7

Please sign in to comment.