Repository: FHIR/sushi
Pull request #784 (2021-03-21 20:43:48)

AddElementRule, Logical, and Resource classes
This completes [CIMPL-688](https://standardhealthrecord.atlassian.net/browse/CIMPL-688) by adding an `AddElementRule` class, a `Logical` class, and a `Resource` class.

I think @cmoesel should be one of the reviewers, since he designed the syntaxes that these classes represent, and I want to make sure I didn't misunderstand any of the requirements.


Patch:
diff --git a/src/fshtypes/Extension.ts b/src/fshtypes/Extension.ts
index d56fe46..9cfe8aa 100644
--- a/src/fshtypes/Extension.ts
+++ b/src/fshtypes/Extension.ts
@@ -1,23 +1,16 @@
-import { FshEntity } from './FshEntity';
+import { FshStructure } from './FshStructure';
 import { SdRule } from './rules';
 
-export class Extension extends FshEntity {
-  id: string;
-  parent: string;
-  title?: string;
-  description?: string;
+export class Extension extends FshStructure {
   mixins?: string[];
   rules: SdRule[];
 
   constructor(public name: string) {
-    super();
-    // Init id to be same as name.  This can be overridden using FSH syntax (Id: keyword)
-    this.id = name;
+    super(name);
     // Init the parent to 'Extension', as this is what 99% of extensions do.
     // This can still be overridden via the FSH syntax (using Parent: keyword).
     this.parent = 'Extension'; // init to 'Extension'
     this.mixins = [];
-    this.rules = [];
   }
 
   get constructorName() {
diff --git a/src/fshtypes/FshStructure.ts b/src/fshtypes/FshStructure.ts
new file mode 100644
index 0000000..a8431ab
--- /dev/null
+++ b/src/fshtypes/FshStructure.ts
@@ -0,0 +1,20 @@
+import { FshEntity } from './FshEntity';
+import { Rule } from './rules';
+
+export abstract class FshStructure extends FshEntity {
+  id: string;
+  parent?: string;
+  title?: string;
+  description?: string;
+  rules: Rule[];
+
+  constructor(public name: string) {
+    super();
+    this.id = name; // init same as name
+    this.rules = [];
+  }
+
+  get constructorName() {
+    return 'FshStructure';
+  }
+}
diff --git a/src/fshtypes/Logical.ts b/src/fshtypes/Logical.ts
new file mode 100644
index 0000000..76cec34
--- /dev/null
+++ b/src/fshtypes/Logical.ts
@@ -0,0 +1,10 @@
+import { FshStructure } from './FshStructure';
+import { AddElementRule, SdRule } from './rules';
+
+export class Logical extends FshStructure {
+  rules: (AddElementRule | SdRule)[];
+
+  get constructorName() {
+    return 'Logical';
+  }
+}
diff --git a/src/fshtypes/Profile.ts b/src/fshtypes/Profile.ts
index 8c9b189..cd06b19 100644
--- a/src/fshtypes/Profile.ts
+++ b/src/fshtypes/Profile.ts
@@ -1,19 +1,13 @@
-import { FshEntity } from './FshEntity';
+import { FshStructure } from './FshStructure';
 import { SdRule } from './rules';
 
-export class Profile extends FshEntity {
-  id: string;
-  parent?: string;
-  title?: string;
-  description?: string;
+export class Profile extends FshStructure {
   mixins?: string[];
   rules: SdRule[];
 
   constructor(public name: string) {
-    super();
-    this.id = name; // init same as name
+    super(name);
     this.mixins = [];
-    this.rules = [];
   }
 
   get constructorName() {
diff --git a/src/fshtypes/Resource.ts b/src/fshtypes/Resource.ts
new file mode 100644
index 0000000..588d45a
--- /dev/null
+++ b/src/fshtypes/Resource.ts
@@ -0,0 +1,10 @@
+import { FshStructure } from './FshStructure';
+import { AddElementRule, SdRule } from './rules';
+
+export class Resource extends FshStructure {
+  rules: (AddElementRule | SdRule)[];
+
+  get constructorName() {
+    return 'Resource';
+  }
+}
diff --git a/src/fshtypes/index.ts b/src/fshtypes/index.ts
index 121c897..720bc03 100644
--- a/src/fshtypes/index.ts
+++ b/src/fshtypes/index.ts
@@ -18,3 +18,5 @@ export * from './ParamRuleSet';
 export * from './Mapping';
 export * from './Configuration';
 export * from './AllowedRules';
+export * from './Logical';
+export * from './Resource';
diff --git a/src/fshtypes/rules/AddElementRule.ts b/src/fshtypes/rules/AddElementRule.ts
new file mode 100644
index 0000000..1d92194
--- /dev/null
+++ b/src/fshtypes/rules/AddElementRule.ts
@@ -0,0 +1,24 @@
+import { Rule } from './Rule';
+import { OnlyRuleType } from './OnlyRule';
+
+export class AddElementRule extends Rule {
+  min: number;
+  max: string;
+  types: OnlyRuleType[] = [];
+  mustSupport?: boolean;
+  summary?: boolean;
+  modifier?: boolean;
+  trialUse?: boolean;
+  normative?: boolean;
+  draft?: boolean;
+  short?: string;
+  definition?: string;
+
+  constructor(path: string) {
+    super(path);
+  }
+
+  get constructorName() {
+    return 'AddElementRule';
+  }
+}
diff --git a/src/fshtypes/rules/index.ts b/src/fshtypes/rules/index.ts
index d0147bf..c7582fe 100644
--- a/src/fshtypes/rules/index.ts
+++ b/src/fshtypes/rules/index.ts
@@ -11,4 +11,5 @@ export * from './MappingRule';
 export * from './InsertRule';
 export * from './ValueSetComponentRule';
 export * from './ConceptRule';
+export * from './AddElementRule';
 export * from './SdRule';


Test patch:
diff --git a/test/fshtypes/Logical.test.ts b/test/fshtypes/Logical.test.ts
new file mode 100644
index 0000000..0496046
--- /dev/null
+++ b/test/fshtypes/Logical.test.ts
@@ -0,0 +1,20 @@
+import 'jest-extended';
+import { Logical } from '../../src/fshtypes/';
+describe('Logical', () => {
+  describe('#constructor', () => {
+    it('should set the properties correctly', () => {
+      const l = new Logical('MyLogical');
+      expect(l.name).toBe('MyLogical');
+      expect(l.id).toBe('MyLogical');
+      expect(l.parent).toBeUndefined();
+      expect(l.title).toBeUndefined();
+      expect(l.description).toBeUndefined();
+      expect(l.rules).toBeEmpty();
+    });
+
+    it('should get the correct constructor name', () => {
+      const l = new Logical('MyLogical');
+      expect(l.constructorName).toBe('Logical');
+    });
+  });
+});
diff --git a/test/fshtypes/Resource.test.ts b/test/fshtypes/Resource.test.ts
new file mode 100644
index 0000000..cedd60f
--- /dev/null
+++ b/test/fshtypes/Resource.test.ts
@@ -0,0 +1,20 @@
+import 'jest-extended';
+import { Resource } from '../../src/fshtypes/';
+describe('Resource', () => {
+  describe('#constructor', () => {
+    it('should set the properties correctly', () => {
+      const r = new Resource('MyResource');
+      expect(r.name).toBe('MyResource');
+      expect(r.id).toBe('MyResource');
+      expect(r.parent).toBeUndefined();
+      expect(r.title).toBeUndefined();
+      expect(r.description).toBeUndefined();
+      expect(r.rules).toBeEmpty();
+    });
+
+    it('should get the correct constructor name', () => {
+      const r = new Resource('MyResource');
+      expect(r.constructorName).toBe('Resource');
+    });
+  });
+});
diff --git a/test/fshtypes/rules/AddElementRule.test.ts b/test/fshtypes/rules/AddElementRule.test.ts
new file mode 100644
index 0000000..2d36e12
--- /dev/null
+++ b/test/fshtypes/rules/AddElementRule.test.ts
@@ -0,0 +1,22 @@
+import 'jest-extended';
+import { AddElementRule } from '../../../src/fshtypes/rules/AddElementRule';
+
+describe('AddElementRule', () => {
+  describe('#constructor', () => {
+    it('should set the properties correctly', () => {
+      const r = new AddElementRule('component.code');
+      expect(r.path).toBe('component.code');
+      expect(r.min).toBeUndefined();
+      expect(r.max).toBeUndefined();
+      expect(r.types).toEqual([]);
+      expect(r.mustSupport).toBeUndefined();
+      expect(r.summary).toBeUndefined();
+      expect(r.modifier).toBeUndefined();
+      expect(r.trialUse).toBeUndefined();
+      expect(r.normative).toBeUndefined();
+      expect(r.draft).toBeUndefined();
+      expect(r.short).toBeUndefined();
+      expect(r.definition).toBeUndefined();
+    });
+  });
+});