Skip to content

Commit

Permalink
feat: introduce square brackets with plus sign as null-preservable te…
Browse files Browse the repository at this point in the history
…mplate
  • Loading branch information
ruscoder committed May 29, 2024
1 parent 32c57da commit 36f6369
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 106 deletions.
2 changes: 0 additions & 2 deletions ts/server/src/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export class AppController {
context,
fhirpath_r4_model,
strict,
true,
);
}

Expand All @@ -46,7 +45,6 @@ export class AppController {
context,
null,
strict,
false
);
}
}
2 changes: 0 additions & 2 deletions ts/server/src/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export class AppService {
context: Context,
model?: Model,
strict?: boolean,
dropNulls?: boolean,
): object {
const options: FPOptions = {
userInvocationTable: {
Expand Down Expand Up @@ -43,7 +42,6 @@ export class AppService {
model,
options,
strict,
dropNulls,
);
}
}
8 changes: 4 additions & 4 deletions ts/server/src/utils/complex-example.aidbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const result = {
},
resource: {
resourceType: 'Observation',
id: null,
id: undefined,
subject: { resourceType: 'Patient', id: 'pid' },
status: 'final',
effective: { dateTime: '2024-01-01' },
Expand Down Expand Up @@ -57,7 +57,7 @@ const result = {
},
resource: {
resourceType: 'Observation',
id: null,
id: undefined,
subject: { resourceType: 'Patient', id: 'pid' },
status: 'final',
effective: { dateTime: '2024-01-01' },
Expand Down Expand Up @@ -113,7 +113,7 @@ const result = {
},
resource: {
resourceType: 'Condition',
id: null,
id: undefined,
subject: { resourceType: 'Patient', id: 'pid' },
recordedDate: '2024-01-01',
code: {
Expand All @@ -135,7 +135,7 @@ const result = {
},
resource: {
resourceType: 'Condition',
id: null,
id: undefined,
subject: { resourceType: 'Patient', id: 'pid' },
recordedDate: '2024-01-01',
code: {
Expand Down
8 changes: 4 additions & 4 deletions ts/server/src/utils/complex-example.fhir.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const result = {
},
resource: {
resourceType: 'Observation',
id: null,
id: undefined,
subject: 'Patient/pid',
status: 'final',
effectiveDateTime: '2024-01-01',
Expand Down Expand Up @@ -56,7 +56,7 @@ const result = {
},
resource: {
resourceType: 'Observation',
id: null,
id: undefined,
subject: 'Patient/pid',
status: 'final',
effectiveDateTime: '2024-01-01',
Expand Down Expand Up @@ -110,7 +110,7 @@ const result = {
},
resource: {
resourceType: 'Condition',
id: null,
id: undefined,
subject: 'Patient/pid',
recordedDate: '2024-01-01',
code: {
Expand All @@ -132,7 +132,7 @@ const result = {
},
resource: {
resourceType: 'Condition',
id: null,
id: undefined,
subject: 'Patient/pid',
recordedDate: '2024-01-01',
code: {
Expand Down
71 changes: 60 additions & 11 deletions ts/server/src/utils/extract.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,24 @@ describe('Transformation', () => {
).toStrictEqual([1, 2, 3, 4, 5, 6]);
});

test('for array with nulls returns compacted array', () => {
test('for array with null values returns compacted array', () => {
expect(resolveTemplate(resource, [[1, null, 2, null, 3]])).toStrictEqual([1, 2, 3]);
});

test('for array with undefined values returns compacted array', () => {
expect(resolveTemplate(resource, [[1, undefined, 2, undefined, 3]])).toStrictEqual([
1, 2, 3,
]);
});

test('for object with null keys returns null keys', () => {
expect(resolveTemplate(resource, { key: null })).toStrictEqual({ key: null });
});

test('for object with undefined keys returns undefined keys', () => {
expect(resolveTemplate(resource, { key: undefined })).toStrictEqual({ key: undefined });
});

test('for object with non-null keys returns non-null keys', () => {
expect(resolveTemplate(resource, { key: 1 })).toStrictEqual({ key: 1 });
});
Expand Down Expand Up @@ -68,12 +78,12 @@ describe('Transformation', () => {
expect(resolveTemplate(resource, '{{ list }}')).toStrictEqual({ key: 1 });
});

test('for empty array expression returns null', () => {
expect(resolveTemplate(resource, '{{ list.where($this = 0) }}')).toStrictEqual(null);
test('for empty array expression returns undefined', () => {
expect(resolveTemplate(resource, '{{ list.where($this = 0) }}')).toStrictEqual(undefined);
});

test('for empty array droppable expression returns undefined', () => {
expect(resolveTemplate(resource, '{{- list.where($this = 0) -}}')).toStrictEqual(undefined);
test('for empty array nullable expression returns null', () => {
expect(resolveTemplate(resource, '{{+ list.where($this = 0) +}}')).toStrictEqual(null);
});

test('for template expression returns resolved template', () => {
Expand All @@ -82,22 +92,22 @@ describe('Transformation', () => {
).toStrictEqual('/1/2/3');
});

test('for empty array template expression returns null', () => {
test('for empty array template expression returns undefined', () => {
expect(
resolveTemplate(
resource,
'/Patient/{{ list.where($this = 0) }}/_history/{{ list.last() }}',
),
).toStrictEqual(null);
).toStrictEqual(undefined);
});

test('for empty array droppable template expression returns undefined', () => {
test('for empty array nullable template expression returns null', () => {
expect(
resolveTemplate(
resource,
'/Patient/{{- list.where($this = 0) -}}/_history/{{ list.last() }}',
'/Patient/{{+ list.where($this = 0) +}}/_history/{{ list.last() }}',
),
).toStrictEqual(undefined);
).toStrictEqual(null);
});

test('for multiline template works properly', () => {
Expand Down Expand Up @@ -392,11 +402,24 @@ describe('If block', () => {
});
});

test('returns null for falsy condition without else branch', () => {
test('returns undefined for falsy condition without else branch', () => {
expect(
resolveTemplate(resource, {
result: {
"{% if key != 'value' %}": { nested: "{{ 'true' + key }}" },
},
}),
).toStrictEqual({
result: undefined,
});
});

test('returns null for falsy condition with nullable else branch', () => {
expect(
resolveTemplate(resource, {
result: {
"{% if key != 'value' %}": { nested: "{{ 'true' + key }}" },
'{% else %}': '{{+ {} +}}',
},
}),
).toStrictEqual({
Expand Down Expand Up @@ -449,6 +472,21 @@ describe('If block', () => {
});
});

test('implicitly merges with undefined returned', () => {
expect(
resolveTemplate(resource, {
result: {
myKey: 1,
"{% if key = 'value' %}": undefined,
},
}),
).toStrictEqual({
result: {
myKey: 1,
},
});
});

test('implicitly merges with object returned for truthy condition', () => {
expect(
resolveTemplate(resource, {
Expand Down Expand Up @@ -587,6 +625,17 @@ describe('Merge block', () => {
});
});

test('merges multiple blocks containing undefined', () => {
expect(
resolveTemplate(resource, {
'{% merge %}': [{ a: 1 }, undefined, { b: 2 }],
}),
).toStrictEqual({
a: 1,
b: 2,
});
});

test('fails on merge with non-object', () => {
expect(() =>
resolveTemplate(resource, {
Expand Down
Loading

0 comments on commit 36f6369

Please sign in to comment.