From 2ab5934778ff18b858dc16cf31848f16d9b09a22 Mon Sep 17 00:00:00 2001 From: eyelidlessness Date: Wed, 26 Feb 2025 09:55:53 -0800 Subject: [PATCH 1/8] Remove incorrect `submissionDefinition` detritus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without doing some commit history archaeology I’m not sure how this ended up here, but it’s wrong (`ClientReactiveSubmittableInstance` doesn’t specify this getter). In any case, I confirmed nothing references this before removing it! (Also removes redundant `// RootNode` header) --- packages/xforms-engine/src/instance/Root.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/xforms-engine/src/instance/Root.ts b/packages/xforms-engine/src/instance/Root.ts index 3c371c3d..c971a6fe 100644 --- a/packages/xforms-engine/src/instance/Root.ts +++ b/packages/xforms-engine/src/instance/Root.ts @@ -3,7 +3,6 @@ import type { Accessor } from 'solid-js'; import type { ActiveLanguage, FormLanguage, FormLanguages } from '../client/FormLanguage.ts'; import type { FormNodeID } from '../client/identity.ts'; import type { RootNode } from '../client/RootNode.ts'; -import type { SubmissionDefinition } from '../client/submission/SubmissionDefinition.ts'; import type { SubmissionChunkedType, SubmissionOptions, @@ -81,13 +80,6 @@ export class Root readonly currentState: MaterializedChildren, GeneralChildNode>; readonly validationState: AncestorNodeValidationState; readonly submissionState: SubmissionState; - - // ClientReactiveSubmittableInstance - get submissionDefinition(): SubmissionDefinition { - return this.definition.submission; - } - - // RootNode readonly languages: FormLanguages; constructor(parent: PrimaryInstance) { From 99f0869f9349de7ff8c4d1858d3d78a56e49bf0f Mon Sep 17 00:00:00 2001 From: eyelidlessness Date: Wed, 26 Feb 2025 12:48:48 -0800 Subject: [PATCH 2/8] engine (typo): Prepeare* -> Prepare* --- .../src/lib/client-reactivity/submission/prepareSubmission.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/xforms-engine/src/lib/client-reactivity/submission/prepareSubmission.ts b/packages/xforms-engine/src/lib/client-reactivity/submission/prepareSubmission.ts index 6a72075f..3bc85802 100644 --- a/packages/xforms-engine/src/lib/client-reactivity/submission/prepareSubmission.ts +++ b/packages/xforms-engine/src/lib/client-reactivity/submission/prepareSubmission.ts @@ -134,14 +134,14 @@ const chunkedSubmissionResult = ( }; }; -export interface PrepeareSubmissionOptions { +export interface PrepareSubmissionOptions { readonly chunked: ChunkedType; readonly maxSize: number; } export const prepareSubmission = ( instanceRoot: ClientReactiveSubmittableInstance, - options: PrepeareSubmissionOptions + options: PrepareSubmissionOptions ): SubmissionResult => { const validation = validateSubmission(instanceRoot); const definition = instanceRoot.definition.submission; From f94d665c722904f764592ed09c1596d8cf2ddd6f Mon Sep 17 00:00:00 2001 From: eyelidlessness Date: Wed, 26 Feb 2025 12:45:20 -0800 Subject: [PATCH 3/8] =?UTF-8?q?engine=20(client):=20=E2=80=9Csubmission?= =?UTF-8?q?=E2=80=9D-specific=20terminology=20to=20=E2=80=9Cinstance?= =?UTF-8?q?=E2=80=9D=20as=20appropriate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is being condensed into a single commit to create less git history noise. Each checklist item is being added below, as each corresponding change is appended. - [x] `SubmissionChunkedType` (enumerated type) -> `InstancePayloadType` - [x] `ChunkedType` (commonly used type parameter for ^) -> `PayloadType` - [x] `chunked` (options property) -> `payloadType` - [x] `SubmissionOptions` (interface union) & related base interfaces -> `InstancePayloadOptions` - [x] `SubmissionOptions.ts` -> `InstancePayloadOptions.ts` - [x] Constants: - `SUBMISSION_INSTANCE_FILE_NAME` & `SubmissionInstanceFileName` -> `INSTANCE_FILE_NAME` - `SUBMISSION_INSTANCE_FILE_TYPE` & `SubmissionInstanceFileType` -> `INSTANCE_FILE_TYPE` - [x] `SubmissionInstanceFile` -> `InstanceFile` - [x] `SubmissionData` -> `InstanceData` - [x] `SubmissionState.submissionXML` -> `SubmissionState.instanceXML` - [x] `SubmissionState` (interface) -> `InstanceState` - [x] `submissionState` -> `instanceState`, where property of: - `BaseNode` (client interface) and any more specific subtype thereof - `ClientReactiveSubmittable*` - [x] (See `@todo` JSDoc comments) Note consideration of moving `instanceValue` state into `InstanceState` - [x] `SubmissionResult` (type) & related -> `InstancePayload` etc (same naming conventions) - [x] `client/submission/Instance*` -> `client/serialization/Instance*` - [x] `RootNode.prepareSubmission` -> `RootNode.prepareInstancePayload` --- .../src/assertion/extensions/submission.ts | 87 ++++++------ packages/scenario/src/jr/Scenario.ts | 6 +- .../web-forms/src/components/OdkWebForm.vue | 16 +-- packages/web-forms/src/demo/FormPreview.vue | 8 +- packages/xforms-engine/src/client/BaseNode.ts | 8 +- .../xforms-engine/src/client/BaseValueNode.ts | 10 +- packages/xforms-engine/src/client/RootNode.ts | 46 ++++--- .../xforms-engine/src/client/constants.ts | 8 +- .../src/client/serialization/InstanceData.ts | 9 ++ .../src/client/serialization/InstanceFile.ts | 9 ++ .../client/serialization/InstancePayload.ts | 124 ++++++++++++++++++ .../serialization/InstancePayloadOptions.ts | 28 ++++ .../src/client/serialization/InstanceState.ts | 14 ++ .../src/client/submission/SubmissionData.ts | 12 -- .../submission/SubmissionInstanceFile.ts | 9 -- .../client/submission/SubmissionOptions.ts | 28 ---- .../src/client/submission/SubmissionResult.ts | 124 ------------------ .../src/client/submission/SubmissionState.ts | 14 -- packages/xforms-engine/src/index.ts | 12 +- packages/xforms-engine/src/instance/Group.ts | 6 +- .../src/instance/PrimaryInstance.ts | 24 ++-- packages/xforms-engine/src/instance/Root.ts | 22 ++-- .../xforms-engine/src/instance/Subtree.ts | 6 +- .../src/instance/abstract/InstanceNode.ts | 4 +- .../instance/abstract/UnsupportedControl.ts | 6 +- .../src/instance/abstract/ValueNode.ts | 6 +- .../ClientReactiveSubmittableLeafNode.ts | 14 +- .../ClientReactiveSubmittableParentNode.ts | 6 +- .../ClientReactiveSubmittableValueNode.ts | 8 +- .../src/instance/repeat/BaseRepeatRange.ts | 6 +- .../src/instance/repeat/RepeatInstance.ts | 6 +- .../createInstanceSubmissionState.ts | 8 +- .../createLeafNodeSubmissionState.ts | 6 +- .../createNodeRangeSubmissionState.ts | 8 +- .../createParentNodeSubmissionState.ts | 8 +- .../submission/createRootSubmissionState.ts | 8 +- .../createValueNodeSubmissionState.ts | 6 +- .../submission/prepareSubmission.ts | 79 ++++++----- 38 files changed, 408 insertions(+), 401 deletions(-) create mode 100644 packages/xforms-engine/src/client/serialization/InstanceData.ts create mode 100644 packages/xforms-engine/src/client/serialization/InstanceFile.ts create mode 100644 packages/xforms-engine/src/client/serialization/InstancePayload.ts create mode 100644 packages/xforms-engine/src/client/serialization/InstancePayloadOptions.ts create mode 100644 packages/xforms-engine/src/client/serialization/InstanceState.ts delete mode 100644 packages/xforms-engine/src/client/submission/SubmissionData.ts delete mode 100644 packages/xforms-engine/src/client/submission/SubmissionInstanceFile.ts delete mode 100644 packages/xforms-engine/src/client/submission/SubmissionOptions.ts delete mode 100644 packages/xforms-engine/src/client/submission/SubmissionResult.ts delete mode 100644 packages/xforms-engine/src/client/submission/SubmissionState.ts diff --git a/packages/scenario/src/assertion/extensions/submission.ts b/packages/scenario/src/assertion/extensions/submission.ts index 866a06dd..62a854e6 100644 --- a/packages/scenario/src/assertion/extensions/submission.ts +++ b/packages/scenario/src/assertion/extensions/submission.ts @@ -12,10 +12,10 @@ import { import type { SimpleAssertionResult } from '@getodk/common/test/assertions/vitest/shared-extension-types.ts'; import type { AssertIs } from '@getodk/common/types/assertions/AssertIs.ts'; import type { - SubmissionChunkedType, - SubmissionData, - SubmissionInstanceFile, - SubmissionResult, + InstanceData, + InstanceFile, + InstancePayload, + InstancePayloadType, } from '@getodk/xforms-engine'; import { constants } from '@getodk/xforms-engine'; import { assert, expect } from 'vitest'; @@ -38,10 +38,10 @@ const compareSubmissionXML = (actual: string, expected: string): SimpleAssertion const assertFormData: AssertIs = instanceAssertion(FormData); -type AnySubmissionResult = SubmissionResult; +type AnyInstancePayload = InstancePayload; /** - * Validating the full {@link SubmissionResult} type is fairly involved. We + * Validating the full {@link InstancePayload} type is fairly involved. We * check the basic object shape (expected keys present, gut check a few easy to * check property types), on the assumption that downstream assertions will fail * if the runtime and static types disagree. @@ -50,7 +50,7 @@ type AnySubmissionResult = SubmissionResult; * more complete validation here, serving as a smoke test for all tests * exercising aspects of a prepared submission result. */ -const assertSubmissionResult: AssertIs = (value) => { +const assertInstancePayload: AssertIs = (value) => { assertUnknownObject(value); assertString(value.status); if (value.violations !== null) { @@ -69,30 +69,30 @@ const assertSubmissionResult: AssertIs = (value) => { const assertFile: AssertIs = instanceAssertion(File); -const { SUBMISSION_INSTANCE_FILE_NAME, SUBMISSION_INSTANCE_FILE_TYPE } = constants; +const { INSTANCE_FILE_NAME, INSTANCE_FILE_TYPE } = constants; -const assertSubmissionInstanceFile: AssertIs = (value) => { +const assertInstanceFile: AssertIs = (value) => { assertFile(value); - if (value.name !== SUBMISSION_INSTANCE_FILE_NAME) { - throw new Error(`Expected file named ${SUBMISSION_INSTANCE_FILE_NAME}, got ${value.name}`); + if (value.name !== INSTANCE_FILE_NAME) { + throw new Error(`Expected file named ${INSTANCE_FILE_NAME}, got ${value.name}`); } - if (value.type !== SUBMISSION_INSTANCE_FILE_TYPE) { - throw new Error(`Expected file of type ${SUBMISSION_INSTANCE_FILE_TYPE}, got ${value.type}`); + if (value.type !== INSTANCE_FILE_TYPE) { + throw new Error(`Expected file of type ${INSTANCE_FILE_TYPE}, got ${value.type}`); } }; -type ChunkedSubmissionData = readonly [SubmissionData, ...SubmissionData[]]; +type ChunkedInstanceData = readonly [InstanceData, ...InstanceData[]]; const isChunkedSubmissionData = ( - data: ChunkedSubmissionData | SubmissionData -): data is ChunkedSubmissionData => { + data: ChunkedInstanceData | InstanceData +): data is ChunkedInstanceData => { return Array.isArray(data); }; -const getSubmissionData = (submissionResult: AnySubmissionResult): SubmissionData => { - const { data } = submissionResult; +const getInstanceData = (payload: AnyInstancePayload): InstanceData => { + const { data } = payload; if (isChunkedSubmissionData(data)) { const [first] = data; @@ -103,13 +103,11 @@ const getSubmissionData = (submissionResult: AnySubmissionResult): SubmissionDat return data; }; -const getSubmissionInstanceFile = ( - submissionResult: AnySubmissionResult -): SubmissionInstanceFile => { - const submissionData = getSubmissionData(submissionResult); - const file = submissionData.get(SUBMISSION_INSTANCE_FILE_NAME); +const getInstanceFile = (payload: AnyInstancePayload): InstanceFile => { + const instanceData = getInstanceData(payload); + const file = instanceData.get(INSTANCE_FILE_NAME); - assertSubmissionInstanceFile(file); + assertInstanceFile(file); return file; }; @@ -125,30 +123,27 @@ export const submissionExtensions = extendExpect(expect, { } ), - toBeReadyForSubmission: new ArbitraryConditionExpectExtension( - assertSubmissionResult, - (result) => { - try { - expect(result).toMatchObject({ - status: 'ready', - violations: null, - }); - - return true; - } catch (error) { - if (error instanceof Error) { - return error; - } - - // eslint-disable-next-line no-console - console.error(error); - return new Error('Unknown error'); + toBeReadyForSubmission: new ArbitraryConditionExpectExtension(assertInstancePayload, (result) => { + try { + expect(result).toMatchObject({ + status: 'ready', + violations: null, + }); + + return true; + } catch (error) { + if (error instanceof Error) { + return error; } + + // eslint-disable-next-line no-console + console.error(error); + return new Error('Unknown error'); } - ), + }), toBePendingSubmissionWithViolations: new ArbitraryConditionExpectExtension( - assertSubmissionResult, + assertInstancePayload, (result) => { try { expect(result.status).toBe('pending'); @@ -173,10 +168,10 @@ export const submissionExtensions = extendExpect(expect, { ), toHavePreparedSubmissionXML: new AsyncAsymmetricTypedExpectExtension( - assertSubmissionResult, + assertInstancePayload, assertString, async (actual, expected): Promise => { - const instanceFile = getSubmissionInstanceFile(actual); + const instanceFile = getInstanceFile(actual); const actualText = await getBlobText(instanceFile); return compareSubmissionXML(actualText, expected); diff --git a/packages/scenario/src/jr/Scenario.ts b/packages/scenario/src/jr/Scenario.ts index 4632c71c..003e3d21 100644 --- a/packages/scenario/src/jr/Scenario.ts +++ b/packages/scenario/src/jr/Scenario.ts @@ -12,8 +12,8 @@ import { constants as ENGINE_CONSTANTS } from '@getodk/xforms-engine'; import type { Accessor, Setter } from 'solid-js'; import { createMemo, createSignal, runWithOwner } from 'solid-js'; import { afterEach, assert, expect } from 'vitest'; -import { SelectValuesAnswer } from '../answer/SelectValuesAnswer.ts'; import { RankValuesAnswer } from '../answer/RankValuesAnswer.ts'; +import { SelectValuesAnswer } from '../answer/SelectValuesAnswer.ts'; import type { ValueNodeAnswer } from '../answer/ValueNodeAnswer.ts'; import { answerOf } from '../client/answerOf.ts'; import type { InitializeTestFormOptions, TestFormResource } from '../client/init.ts'; @@ -964,7 +964,7 @@ export class Scenario { } proposed_serializeInstance(): string { - return this.instanceRoot.submissionState.submissionXML; + return this.instanceRoot.instanceState.instanceXML; } /** @@ -975,7 +975,7 @@ export class Scenario { * already handled by {@link proposed_serializeInstance}). */ prepareWebFormsSubmission() { - return this.instanceRoot.prepareSubmission(); + return this.instanceRoot.prepareInstancePayload(); } // TODO: consider adapting tests which use the following interfaces to use diff --git a/packages/web-forms/src/components/OdkWebForm.vue b/packages/web-forms/src/components/OdkWebForm.vue index e06d01d2..feed0376 100644 --- a/packages/web-forms/src/components/OdkWebForm.vue +++ b/packages/web-forms/src/components/OdkWebForm.vue @@ -1,8 +1,8 @@