diff --git a/src/exportable/ExportableInvariant.ts b/src/exportable/ExportableInvariant.ts index ea417149..381e5337 100644 --- a/src/exportable/ExportableInvariant.ts +++ b/src/exportable/ExportableInvariant.ts @@ -1,5 +1,7 @@ import { fshtypes } from 'fsh-sushi'; import { Exportable, ExportableAssignmentRule, ExportableInsertRule } from '.'; +import { fshifyString } from './common'; +import { EOL } from 'os'; export class ExportableInvariant extends fshtypes.Invariant implements Exportable { rules: (ExportableAssignmentRule | ExportableInsertRule)[]; @@ -7,4 +9,28 @@ export class ExportableInvariant extends fshtypes.Invariant implements Exportabl constructor(name: string) { super(name); } + + metadataToFSH(): string { + const resultLines: string[] = []; + resultLines.push(`Invariant: ${this.name}`); + if (this.description) { + // Description can be a multiline string. + // If it contains newline characters, treat it as a multiline string. + if (this.description.indexOf('\n') > -1) { + resultLines.push(`Description: """${this.description}"""`); + } else { + resultLines.push(`Description: "${fshifyString(this.description)}"`); + } + } + if (this.severity) { + resultLines.push(`* severity = ${this.severity}`); + } + if (this.expression) { + resultLines.push(`* expression = "${fshifyString(this.expression)}"`); + } + if (this.xpath) { + resultLines.push(`* xpath = "${fshifyString(this.xpath)}"`); + } + return resultLines.join(EOL); + } } diff --git a/test/exportable/ExportableInvariant.test.ts b/test/exportable/ExportableInvariant.test.ts index 58f519eb..cda75543 100644 --- a/test/exportable/ExportableInvariant.test.ts +++ b/test/exportable/ExportableInvariant.test.ts @@ -1,6 +1,6 @@ import { EOL } from 'os'; import { fshtypes } from 'fsh-sushi'; -import { ExportableInvariant } from '../../src/exportable'; +import { ExportableAssignmentRule, ExportableInvariant } from '../../src/exportable'; describe('ExportableInvariant', () => { it('should export the simplest invariant', () => { @@ -21,9 +21,9 @@ describe('ExportableInvariant', () => { const expectedResult = [ 'Invariant: inv-2', 'Description: "This is an important condition."', - 'Severity: #error', - 'Expression: "requirement.exists()"', - 'XPath: "f:requirement"' + '* severity = #error', + '* expression = "requirement.exists()"', + '* xpath = "f:requirement"' ].join(EOL); const result = input.toFSH(); expect(result).toBe(expectedResult); @@ -39,9 +39,38 @@ describe('ExportableInvariant', () => { const expectedResult = [ 'Invariant: inv-3', 'Description: """Please do this.\nPlease always do this with a \\ character."""', - 'Severity: #warning', - 'Expression: "requirement.contains(\\"\\\\\\")"', - 'XPath: "f:requirement"' + '* severity = #warning', + '* expression = "requirement.contains(\\"\\\\\\")"', + '* xpath = "f:requirement"' + ].join(EOL); + const result = input.toFSH(); + expect(result).toBe(expectedResult); + }); + + it('should produce FSH for an invariant with additional rules', () => { + const input = new ExportableInvariant('inv-4'); + input.description = 'This is an important condition.'; + input.severity = new fshtypes.FshCode('error'); + input.expression = 'requirement.exists()'; + input.xpath = 'f:requirement'; + + const requirements = new ExportableAssignmentRule('requirements'); + requirements.value = 'This is necessary because it is important.'; + const extensionUrl = new ExportableAssignmentRule('human.extension[0].url'); + extensionUrl.value = 'http://example.org/SomeExtension'; + const extensionValue = new ExportableAssignmentRule('human.extension[0].valueString'); + extensionValue.value = 'ExtensionValue'; + input.rules.push(requirements, extensionUrl, extensionValue); + + const expectedResult = [ + 'Invariant: inv-4', + 'Description: "This is an important condition."', + '* severity = #error', + '* expression = "requirement.exists()"', + '* xpath = "f:requirement"', + '* requirements = "This is necessary because it is important."', + '* human.extension[0].url = "http://example.org/SomeExtension"', + '* human.extension[0].valueString = "ExtensionValue"' ].join(EOL); const result = input.toFSH(); expect(result).toBe(expectedResult);