From 7d4ac2211725f7c91e474a35fbcfc1484f2a1ce1 Mon Sep 17 00:00:00 2001 From: kjefferson Date: Mon, 21 Oct 2024 12:01:16 -0400 Subject: [PATCH 1/7] adding test, conditional check --- src/fhirtypes/StructureDefinition.ts | 13 ++++++++++++- test/export/ValueSetExporter.test.ts | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts index d87303aba..8ae1845d9 100644 --- a/src/fhirtypes/StructureDefinition.ts +++ b/src/fhirtypes/StructureDefinition.ts @@ -691,7 +691,18 @@ export class StructureDefinition { ) { // We throw an error if the currentElement doesn't exist, has been zeroed out, // or is being incorrectly accessed as an array - throw new CannotResolvePathError(path); + if ( + pathPart.base === 'concept' && + pathPart.brackets[0] === 'undefined' && + pathPart.slices[0] === 'undefined' + ) { + throw new Error( + 'This rule is invalid. The rule does not contain a concept array in the compose element with the code system given.' + ); + // TODO: code system --> fisher.tank.docs[0].valueSets[0].value.rules[0].from.system + } else { + throw new CannotResolvePathError(path); + } } // Determine if base and/or current are arrays. Note that this is not perfect (if base or current max is missing), diff --git a/test/export/ValueSetExporter.test.ts b/test/export/ValueSetExporter.test.ts index 34c348c2d..974dad7ae 100644 --- a/test/export/ValueSetExporter.test.ts +++ b/test/export/ValueSetExporter.test.ts @@ -723,6 +723,31 @@ describe('ValueSetExporter', () => { }); }); + it('should throw error for caret rule on valueset compose component without any concept', () => { + // ValueSet: SomeVS + // * include codes from system http://example.org/CS + // * http://example.org/CS#"some-code" ^designation.value = "some value" + + const valueSet = new FshValueSet('SomeVS'); + + const component = new ValueSetConceptComponentRule(true); + component.from.system = 'http://example.org/CS'; + + const cvRule = new CaretValueRule(''); + cvRule.pathArray = ['http://example.org/CS#"some-code"']; + cvRule.caretPath = 'designation.value'; + cvRule.value = 'some value'; + + valueSet.rules.push(component, cvRule); + doc.valueSets.set(valueSet.name, valueSet); + const exported = exporter.export().valueSets; + expect(exported.length).toBe(1); + expect(loggerSpy.getAllMessages('error')).toHaveLength(1); + expect(loggerSpy.getLastMessage('error')).toMatch( + /This rule is invalid. The rule does not contain a concept array in the compose element/ + ); + }); + it('should remove and log error when exporting a value set that includes a component from a self referencing value set', () => { const valueSet = new FshValueSet('DinnerVS'); valueSet.id = 'dinner-vs'; From 1da4d898afc0fb4848530b69afc3a0831b4cb5e5 Mon Sep 17 00:00:00 2001 From: kjefferson Date: Sun, 1 Dec 2024 16:00:13 -0500 Subject: [PATCH 2/7] change to the conditional --- src/fhirtypes/StructureDefinition.ts | 6 ++---- test/export/ValueSetExporter.test.ts | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts index 8ae1845d9..b1fccdd3f 100644 --- a/src/fhirtypes/StructureDefinition.ts +++ b/src/fhirtypes/StructureDefinition.ts @@ -692,12 +692,10 @@ export class StructureDefinition { // We throw an error if the currentElement doesn't exist, has been zeroed out, // or is being incorrectly accessed as an array if ( - pathPart.base === 'concept' && - pathPart.brackets[0] === 'undefined' && - pathPart.slices[0] === 'undefined' + currentPath == 'compose.include.concept[undefined]' ) { throw new Error( - 'This rule is invalid. The rule does not contain a concept array in the compose element with the code system given.' + 'This rule is invalid. There is no concept array in the compose element with the code system: code_system.' ); // TODO: code system --> fisher.tank.docs[0].valueSets[0].value.rules[0].from.system } else { diff --git a/test/export/ValueSetExporter.test.ts b/test/export/ValueSetExporter.test.ts index 974dad7ae..e9ab09742 100644 --- a/test/export/ValueSetExporter.test.ts +++ b/test/export/ValueSetExporter.test.ts @@ -744,7 +744,7 @@ describe('ValueSetExporter', () => { expect(exported.length).toBe(1); expect(loggerSpy.getAllMessages('error')).toHaveLength(1); expect(loggerSpy.getLastMessage('error')).toMatch( - /This rule is invalid. The rule does not contain a concept array in the compose element/ + /This rule is invalid. There is no concept array in the compose element with the code system: code_system/ ); }); From 23a9e2fcd3278ac199f5cb33ae2043c1cbd70a29 Mon Sep 17 00:00:00 2001 From: kjefferson Date: Sun, 1 Dec 2024 16:04:24 -0500 Subject: [PATCH 3/7] missing prettier fix --- src/fhirtypes/StructureDefinition.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts index b1fccdd3f..9190d3167 100644 --- a/src/fhirtypes/StructureDefinition.ts +++ b/src/fhirtypes/StructureDefinition.ts @@ -691,9 +691,7 @@ export class StructureDefinition { ) { // We throw an error if the currentElement doesn't exist, has been zeroed out, // or is being incorrectly accessed as an array - if ( - currentPath == 'compose.include.concept[undefined]' - ) { + if (currentPath == 'compose.include.concept[undefined]') { throw new Error( 'This rule is invalid. There is no concept array in the compose element with the code system: code_system.' ); From a48662b7403189a19210abbdae89d062e9e9fbe8 Mon Sep 17 00:00:00 2001 From: kjefferson Date: Mon, 2 Dec 2024 13:06:36 -0500 Subject: [PATCH 4/7] moving conditional to ValueSetExporter --- src/export/ValueSetExporter.ts | 7 ++++++- src/fhirtypes/StructureDefinition.ts | 9 +-------- test/export/ValueSetExporter.test.ts | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/export/ValueSetExporter.ts b/src/export/ValueSetExporter.ts index 27ef54633..efd750e40 100644 --- a/src/export/ValueSetExporter.ts +++ b/src/export/ValueSetExporter.ts @@ -366,7 +366,12 @@ export class ValueSetExporter { }); } } - + if (conceptIndex === undefined) { + logger.error( + `This rule is invalid. There is no concept array in the compose element with the code system: ${system}.` + ); + return; + } if (conceptIndex !== -1) { if (rule.isInstance) { const instanceExporter = new InstanceExporter(this.tank, this.pkg, this.fisher); diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts index 9190d3167..d87303aba 100644 --- a/src/fhirtypes/StructureDefinition.ts +++ b/src/fhirtypes/StructureDefinition.ts @@ -691,14 +691,7 @@ export class StructureDefinition { ) { // We throw an error if the currentElement doesn't exist, has been zeroed out, // or is being incorrectly accessed as an array - if (currentPath == 'compose.include.concept[undefined]') { - throw new Error( - 'This rule is invalid. There is no concept array in the compose element with the code system: code_system.' - ); - // TODO: code system --> fisher.tank.docs[0].valueSets[0].value.rules[0].from.system - } else { - throw new CannotResolvePathError(path); - } + throw new CannotResolvePathError(path); } // Determine if base and/or current are arrays. Note that this is not perfect (if base or current max is missing), diff --git a/test/export/ValueSetExporter.test.ts b/test/export/ValueSetExporter.test.ts index e9ab09742..34e3b4644 100644 --- a/test/export/ValueSetExporter.test.ts +++ b/test/export/ValueSetExporter.test.ts @@ -743,8 +743,8 @@ describe('ValueSetExporter', () => { const exported = exporter.export().valueSets; expect(exported.length).toBe(1); expect(loggerSpy.getAllMessages('error')).toHaveLength(1); - expect(loggerSpy.getLastMessage('error')).toMatch( - /This rule is invalid. There is no concept array in the compose element with the code system: code_system/ + expect(loggerSpy.getLastMessage('error')).toBe( + 'This rule is invalid. There is no concept array in the compose element with the code system: http://example.org/CS.' ); }); From 87ed52e7c65212c693e61e21d220af1c172a0700 Mon Sep 17 00:00:00 2001 From: KaelynJefferson <106775284+KaelynJefferson@users.noreply.github.com> Date: Sat, 14 Dec 2024 15:07:55 -0500 Subject: [PATCH 5/7] Update src/export/ValueSetExporter.ts Co-authored-by: Julia Afeltra <30803904+jafeltra@users.noreply.github.com> --- src/export/ValueSetExporter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/export/ValueSetExporter.ts b/src/export/ValueSetExporter.ts index efd750e40..fb571a5ad 100644 --- a/src/export/ValueSetExporter.ts +++ b/src/export/ValueSetExporter.ts @@ -366,7 +366,7 @@ export class ValueSetExporter { }); } } - if (conceptIndex === undefined) { + if (conceptIndex == null) { logger.error( `This rule is invalid. There is no concept array in the compose element with the code system: ${system}.` ); From cb6401b71dc27a5a995bd10f1bc68d2c07d2bcec Mon Sep 17 00:00:00 2001 From: kjefferson Date: Sat, 14 Dec 2024 15:24:14 -0500 Subject: [PATCH 6/7] prettier fix for merge conflict resolved --- test/export/ValueSetExporter.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/export/ValueSetExporter.test.ts b/test/export/ValueSetExporter.test.ts index 9455a6683..3ba67031c 100644 --- a/test/export/ValueSetExporter.test.ts +++ b/test/export/ValueSetExporter.test.ts @@ -1287,7 +1287,6 @@ describe('ValueSetExporter', () => { /Resolved value "my-observation" is not a valid URI/s ); expect(loggerSpy.getLastMessage('error')).toMatch(/File: ValueSet\.fsh.*Line: 1 - 9\D*/s); - }); it('should remove and log error when exporting a value set that includes a component from a self referencing value set', () => { From a761cfb5943d5aafb1a1920086409c4fccab8b40 Mon Sep 17 00:00:00 2001 From: kjefferson Date: Fri, 20 Dec 2024 11:28:33 -0500 Subject: [PATCH 7/7] updating error message --- src/export/ValueSetExporter.ts | 5 ++++- test/export/ValueSetExporter.test.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/export/ValueSetExporter.ts b/src/export/ValueSetExporter.ts index 8ba579897..9a6019eb2 100644 --- a/src/export/ValueSetExporter.ts +++ b/src/export/ValueSetExporter.ts @@ -459,7 +459,10 @@ export class ValueSetExporter { } if (conceptIndex == null) { logger.error( - `This rule is invalid. There is no concept array in the compose element with the code system: ${system}.` + `Cannot process caret assignment rule for code ${system}#${code} because ` + + 'this value set does not explicitly include or exclude this code in its ' + + 'rules. To fix this error, add a rule that specifically includes or excludes ' + + 'this code for the value set.' ); return; } diff --git a/test/export/ValueSetExporter.test.ts b/test/export/ValueSetExporter.test.ts index 3ba67031c..38c44dd75 100644 --- a/test/export/ValueSetExporter.test.ts +++ b/test/export/ValueSetExporter.test.ts @@ -778,7 +778,10 @@ describe('ValueSetExporter', () => { expect(exported.length).toBe(1); expect(loggerSpy.getAllMessages('error')).toHaveLength(1); expect(loggerSpy.getLastMessage('error')).toBe( - 'This rule is invalid. There is no concept array in the compose element with the code system: http://example.org/CS.' + 'Cannot process caret assignment rule for code http://example.org/CS#"some-code" ' + + 'because this value set does not explicitly include or exclude this code in its ' + + 'rules. To fix this error, add a rule that specifically includes or excludes this ' + + 'code for the value set.' ); });