From f19b0bafb51ff3cbe0f151bdf98a314da8588fe4 Mon Sep 17 00:00:00 2001 From: Jan Loewe <jan.loewe@ptb.de> Date: Tue, 16 May 2023 09:22:39 +0000 Subject: [PATCH] Add tests --- .eslintrc.json | 2 +- .gitignore | 3 + .gitlab-ci.yml | 56 ++ .idea/git_toolbox_prj.xml | 5 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/jsLinters/eslint.xml | 6 + .yarnrc.yml | 1 + jest.config.ts | 10 + package-lock.json | Bin 303276 -> 0 bytes package.json | 42 +- tests/Arbitraries.ts | 17 + tests/DCC/AdministrativeData.Items.test.ts | 117 +++ ...dministrativeData.SoftwareListType.test.ts | 41 + tests/DCC/AdministrativeData.test.ts | 19 + .../DigitalCalibrationCertificateType.test.ts | 21 + ...strativeData.CalibrationLaboratory.test.ts | 84 ++ .../AdministrativeData.CoreDataType.test.ts | 118 +++ .../AdministrativeData.Customer.test.ts | 70 ++ .../AdministrativeData.Items.test.ts | 117 +++ .../AdministrativeData.RespPersons.test.ts | 56 ++ ...dministrativeData.SoftwareListType.test.ts | 37 + .../AdministrativeData.Statements.test.ts | 127 +++ .../DigitalCalibrationCertificateType.test.ts | 21 + ...surementResult.InfluenceConditions.test.ts | 218 ++++++ ...surementResult.MeasuringEquipments.test.ts | 58 ++ ...mentResults.MeasurementResult.Name.test.ts | 35 + ...tResults.MeasurementResult.Results.test.ts | 339 ++++++++ ...ults.MeasurementResult.UsedMethods.test.ts | 44 ++ .../AdministrativeData.Items_variant.test.ts | 37 + ...inistrativeData.Statements_variant.test.ts | 95 +++ ...strativeData.CalibrationLaboratory.test.ts | 80 ++ .../AdministrativeData.CoreDataType.test.ts | 120 +++ .../AdministrativeData.Customer.test.ts | 77 ++ .../AdministrativeData.Items.test.ts | 117 +++ .../AdministrativeData.RespPersons.test.ts | 56 ++ ...dministrativeData.SoftwareListType.test.ts | 39 + .../AdministrativeData.Statements.test.ts | 213 +++++ .../DigitalCalibrationCertificateType.test.ts | 21 + ...surementResult.InfluenceConditions.test.ts | 249 ++++++ ...surementResult.MeasuringEquipments.test.ts | 58 ++ ...mentResults.MeasurementResult.Name.test.ts | 35 + ...tResults.MeasurementResult.Results.test.ts | 302 +++++++ ...ults.MeasurementResult.UsedMethods.test.ts | 81 ++ ...strativeData.CalibrationLaboratory.test.ts | 84 ++ .../AdministrativeData.CoreDataType.test.ts | 128 +++ .../AdministrativeData.Customer.test.ts | 70 ++ .../AdministrativeData.Items.test.ts | 144 ++++ ...ministrativeData.RefTypeDefinitons.test.ts | 72 ++ .../AdministrativeData.RespPersons.test.ts | 56 ++ ...dministrativeData.SoftwareListType.test.ts | 60 ++ .../AdministrativeData.Statements.test.ts | 127 +++ .../DigitalCalibrationCertificateType.test.ts | 21 + ...surementResult.InfluenceConditions.test.ts | 218 ++++++ ...surementResult.MeasuringEquipments.test.ts | 58 ++ ...mentResults.MeasurementResult.Name.test.ts | 35 + ...tResults.MeasurementResult.Results.test.ts | 737 ++++++++++++++++++ ...ults.MeasurementResult.UsedMethods.test.ts | 44 ++ ...surementResult.InfluenceConditions.test.ts | 249 ++++++ ...surementResult.MeasuringEquipments.test.ts | 58 ++ ...mentResults.MeasurementResult.Name.test.ts | 35 + ...tResults.MeasurementResult.Results.test.ts | 302 +++++++ ...ults.MeasurementResult.UsedMethods.test.ts | 81 ++ ...strativeData.CalibrationLaboratory.test.ts | 34 + .../AdministrativeData.CoreDataType.test.ts | 116 +++ .../AdministrativeData.Customer.test.ts | 42 + .../AdministrativeData.Items.test.ts | 64 ++ .../AdministrativeData.RespPersons.test.ts | 37 + ...dministrativeData.SoftwareListType.test.ts | 41 + .../DigitalCalibrationCertificateType.test.ts | 21 + ...mentResults.MeasurementResult.Name.test.ts | 35 + ...tResults.MeasurementResult.Results.test.ts | 100 +++ .../CalibrationLaboratory.ts | 78 ++ .../common/AdministrativeData/CoreDataType.ts | 117 +++ .../common/AdministrativeData/RespPersons.ts | 19 + tests/DCC/common/Types/ContactType.ts | 72 ++ tests/DCC/common/Types/DataType.ts | 23 + tests/DCC/common/Types/RespPersonType.ts | 28 + tests/DCC/common/Types/RichContentType.ts | 25 + tests/DCC/common/Types/StatementListType.ts | 18 + .../DCC/common/Types/StatementMetaDataType.ts | 72 ++ tests/DCCDocument.test.ts | 30 +- tests/GP_Temperature/CharsXMLList.test.ts | 25 + tests/GP_Temperature/noQuantity.test.ts | 56 ++ tests/XMLEnvironment.ts | 44 ++ tests/index.d.ts | 12 + tests/resources/GP_Temperature_Simplified.xml | 352 +++++++++ .../GP_Temperature_Simplified_variant.xml | 365 +++++++++ tests/resources/GP_Temperature_Typical.xml | 441 +++++++++++ tests/resources/GP_Temperature_v3.2.0_DCC.xml | 540 +++++++++++++ tests/resources/Test_DCC_Minimal.xml | 108 +++ .../example.xml.ts => resources/example.xml} | 40 +- tests/tsconfig.json | 7 + tests/util.ts | 36 + tsconfig.json | 6 +- yarn.lock | Bin 0 -> 202139 bytes 95 files changed, 8781 insertions(+), 52 deletions(-) create mode 100644 .gitlab-ci.yml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/jsLinters/eslint.xml create mode 100644 .yarnrc.yml create mode 100644 jest.config.ts delete mode 100644 package-lock.json create mode 100644 tests/Arbitraries.ts create mode 100644 tests/DCC/AdministrativeData.Items.test.ts create mode 100644 tests/DCC/AdministrativeData.SoftwareListType.test.ts create mode 100644 tests/DCC/AdministrativeData.test.ts create mode 100644 tests/DCC/DigitalCalibrationCertificateType.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CalibrationLaboratory.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CoreDataType.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Customer.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Items.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.RespPersons.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.SoftwareListType.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Statements.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/DigitalCalibrationCertificateType.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Name.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Results.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.UsedMethods.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Items_variant.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Statements_variant.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CalibrationLaboratory.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CoreDataType.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Customer.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Items.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.RespPersons.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.SoftwareListType.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Statements.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/DigitalCalibrationCertificateType.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Name.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Results.test.ts create mode 100644 tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.UsedMethods.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CalibrationLaboratory.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CoreDataType.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Customer.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Items.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RefTypeDefinitons.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RespPersons.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.SoftwareListType.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Statements.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/DigitalCalibrationCertificateType.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Name.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Results.test.ts create mode 100644 tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts create mode 100644 tests/DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts create mode 100644 tests/DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts create mode 100644 tests/DCC/MeasurementResults.MeasurementResult.Name.test.ts create mode 100644 tests/DCC/MeasurementResults.MeasurementResult.Results.test.ts create mode 100644 tests/DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/AdministrativeData.CalibrationLaboratory.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/AdministrativeData.CoreDataType.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/AdministrativeData.Customer.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/AdministrativeData.Items.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/AdministrativeData.RespPersons.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/AdministrativeData.SoftwareListType.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/DigitalCalibrationCertificateType.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Name.test.ts create mode 100644 tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Results.test.ts create mode 100644 tests/DCC/common/AdministrativeData/CalibrationLaboratory.ts create mode 100644 tests/DCC/common/AdministrativeData/CoreDataType.ts create mode 100644 tests/DCC/common/AdministrativeData/RespPersons.ts create mode 100644 tests/DCC/common/Types/ContactType.ts create mode 100644 tests/DCC/common/Types/DataType.ts create mode 100644 tests/DCC/common/Types/RespPersonType.ts create mode 100644 tests/DCC/common/Types/RichContentType.ts create mode 100644 tests/DCC/common/Types/StatementListType.ts create mode 100644 tests/DCC/common/Types/StatementMetaDataType.ts create mode 100644 tests/GP_Temperature/CharsXMLList.test.ts create mode 100644 tests/GP_Temperature/noQuantity.test.ts create mode 100644 tests/XMLEnvironment.ts create mode 100644 tests/index.d.ts create mode 100644 tests/resources/GP_Temperature_Simplified.xml create mode 100644 tests/resources/GP_Temperature_Simplified_variant.xml create mode 100644 tests/resources/GP_Temperature_Typical.xml create mode 100644 tests/resources/GP_Temperature_v3.2.0_DCC.xml create mode 100644 tests/resources/Test_DCC_Minimal.xml rename tests/{Resources/example.xml.ts => resources/example.xml} (93%) create mode 100644 tests/tsconfig.json create mode 100644 tests/util.ts create mode 100644 yarn.lock diff --git a/.eslintrc.json b/.eslintrc.json index 8a39c34..cfec66a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,4 +10,4 @@ "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended" ] -} \ No newline at end of file +} diff --git a/.gitignore b/.gitignore index d583f86..ef05b8c 100644 --- a/.gitignore +++ b/.gitignore @@ -612,3 +612,6 @@ $RECYCLE.BIN/ /.tgitconfig lib +junit.xml + +.yarn/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..43d696f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,56 @@ +image: node:18.15.0 + +stages: + - test + +# === Caches === +.yarn-cache: &yarn-cache + key: yarn-$CI_JOB_IMAGE + paths: + - .yarn + +# === Proxy === +# Description: sets up the proxy needed for the runner inside of the PTB. Produces a build.env that is used in the next jobs +proxy: + stage: .pre + script: + - touch build.env + - if [[ "$CI_RUNNER_TAGS" == *"behind_proxy"* ]]; then + - echo "behind_proxy=true" >> build.env + - echo "http_proxy=http://webproxy.bs.ptb.de:8080/" >> build.env + - echo "https_proxy=http://webproxy.bs.ptb.de:8080/" >> build.env + - fi + artifacts: + reports: + dotenv: build.env + + +# === Yarn Install === +# Description: installs and caches dependencies +.yarn-install: &yarn-install + - corepack enable + # proxy settings + - if [[ "$behind_proxy" == true ]]; then + - npm config set proxy $http_proxy + - npm config set https-proxy $https_proxy + - yarn config set -H httpProxy $http_proxy + - yarn config set -H httpsProxy $https_proxy + - fi + # install deps + - yarn install --immutable + +# === Job: Unit Tests === +# Description: this job runs the unit tests +test: + stage: test + needs: ["proxy"] + script: + - *yarn-install + - yarn run test:unit --ci + cache: + - <<: *yarn-cache + artifacts: + when: always + reports: + junit: + - junit.xml diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml index b382006..bcb1d9d 100644 --- a/.idea/git_toolbox_prj.xml +++ b/.idea/git_toolbox_prj.xml @@ -11,5 +11,10 @@ <option name="enabled" value="true" /> </CommitMessageValidationOverride> </option> + <option name="commitMessageValidationEnabledOverride"> + <BoolValueOverride> + <option name="enabled" value="true" /> + </BoolValueOverride> + </option> </component> </project> \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ +<component name="InspectionProjectProfileManager"> + <profile version="1.0"> + <option name="myName" value="Project Default" /> + <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> + </profile> +</component> \ No newline at end of file diff --git a/.idea/jsLinters/eslint.xml b/.idea/jsLinters/eslint.xml new file mode 100644 index 0000000..541945b --- /dev/null +++ b/.idea/jsLinters/eslint.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="EslintConfiguration"> + <option name="fix-on-save" value="true" /> + </component> +</project> \ No newline at end of file diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..3186f3f --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..85289d3 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,10 @@ +import type { JestConfigWithTsJest } from "ts-jest"; + +const config: JestConfigWithTsJest = { + preset: "ts-jest", + testEnvironment: "node", + reporters: ["default", "jest-junit"], + coverageProvider: "v8", +}; + +export default config; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 5f2c10e590391b41038f3c19919e003c6dacf6c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 303276 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 diff --git a/package.json b/package.json index 98f1ca0..5e495af 100644 --- a/package.json +++ b/package.json @@ -11,31 +11,36 @@ "fix:prettier": "prettier \"src/**/*.ts\" --write", "fix:lint": "eslint src --ext .ts --fix", "test": "run-s test:*", - "test:unit": "mocha -r ts-node/register tests/**/*.test.ts", + "test:unit": "jest", "test:lint": "eslint src --ext .ts", "test:prettier": "prettier \"src/**/*.ts\" --list-different", - "coverage": "nyc -r lcov -e .ts -x \"*.test.ts\" mocha -r ts-node/register tests/**/*.test.ts && nyc report", - "prepare": "npm run build", - "prepublishOnly": "npm run test", - "preversion": "npm run test" + "prepare": "yarn run build", + "prepublishOnly": "yarn run test", + "preversion": "yarn run test" }, "dependencies": { "xml-js": "^1.6.11" }, "devDependencies": { - "@types/chai": "^4.3.0", - "@types/mocha": "^9.1.0", - "@typescript-eslint/eslint-plugin": "^5.11.0", - "@typescript-eslint/parser": "^5.11.0", - "chai": "^4.3.6", - "eslint": "^8.8.0", - "eslint-config-prettier": "^8.3.0", - "mocha": "^9.2.0", + "@jest/globals": "^29.5.0", + "@types/jest": "^29.5.1", + "@types/node": "^18.16.2", + "@typescript-eslint/eslint-plugin": "^5.56.0", + "@typescript-eslint/parser": "^5.56.0", + "eslint": "^8.36.0", + "eslint-config-prettier": "^8.8.0", + "fast-check": "^3.7.1", + "jest": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-junit": "^16.0.0", + "jsdom": "^21.1.1", + "lodash": "^4.17.21", "npm-run-all": "^4.1.5", - "nyc": "^15.1.0", - "prettier": "^2.5.1", - "ts-node": "^10.5.0", - "typescript": "^4.5.5" + "prettier": "^2.8.6", + "ts-jest": "^29.1.0", + "ts-node": "^10.9.1", + "typescript": "^4.9.5", + "xpath-ts": "^1.3.13" }, "publishConfig": { "@d-ptb:registry": "https://gitlab1.ptb.de/api/v4/projects/105/packages/npm/" @@ -46,5 +51,6 @@ "!**/*.json", "LICENSE", "README.md" - ] + ], + "packageManager": "yarn@3.5.0" } diff --git a/tests/Arbitraries.ts b/tests/Arbitraries.ts new file mode 100644 index 0000000..be7453c --- /dev/null +++ b/tests/Arbitraries.ts @@ -0,0 +1,17 @@ +import * as fc from "fast-check"; + +export const string_ISO3166_1 = () => + fc + .integer({ + min: "A".charCodeAt(0), + max: "Z".charCodeAt(0), + }) + .map(String.fromCharCode); + +export const string_ISO639_1 = () => + fc + .integer({ + min: "a".charCodeAt(0), + max: "z".charCodeAt(0), + }) + .map(String.fromCharCode); diff --git a/tests/DCC/AdministrativeData.Items.test.ts b/tests/DCC/AdministrativeData.Items.test.ts new file mode 100644 index 0000000..79dfe54 --- /dev/null +++ b/tests/DCC/AdministrativeData.Items.test.ts @@ -0,0 +1,117 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { ItemType, DCCDocument, IdentificationType } from "../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:items"; +const xpath = { + items: { + item: { + name: { + content: `${base}/dcc:item[1]/dcc:name/dcc:content`, + }, + manufacturer: { + name: { + content: `${base}/dcc:item[1]/dcc:manufacturer/dcc:name/dcc:content`, + }, + }, + model: `string(${base}/dcc:item[1]/dcc:model)`, + + identifications: { + identification1: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + identification2: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:name/dcc:content`, + }, + }, + identification3: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:name/dcc:content`, + }, + }, + }, + }, + }, +}; + +describe("ItemType", () => { + let dcc: DCCDocument, item: ItemType, identification1, identification2, identification3: IdentificationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + item = dcc.digitalCalibrationCertificate.administrativeData.items.item[0]; + identification1 = item.identifications.identification[0]; + identification2 = item.identifications.identification[1]; + identification3 = item.identifications.identification[2]; + }); + + test("should get correct item name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.name.content, dom); + expect(toTextArr(item.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item manufacturer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.manufacturer.name.content, dom); + expect(toTextArr(item.manufacturer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item model from XML", () => { + expect(item.model._text).toBe(select(xpath.items.item.model, dom)); + }); + + test("should get correct identification 1 issuer from XML", () => { + expect(identification1.issuer._text).toBe(select(xpath.items.item.identifications.identification1.issuer, dom)); + }); + + test("should get correct identification 1 value from XML", () => { + expect(identification1.value._text).toBe(select(xpath.items.item.identifications.identification1.value, dom)); + }); + + test("should get correct identification 1 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification1.name.content, dom); + expect(toTextArr(identification1.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 2 issuer from XML", () => { + expect(identification2.issuer._text).toBe(select(xpath.items.item.identifications.identification2.issuer, dom)); + }); + + test("should get correct identification 2 value from XML", () => { + expect(identification2.value._text).toBe(select(xpath.items.item.identifications.identification2.value, dom)); + }); + + test("should get correct identification 2 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification2.name.content, dom); + expect(toTextArr(identification2.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 3 issuer from XML", () => { + expect(identification3.issuer._text).toBe(select(xpath.items.item.identifications.identification3.issuer, dom)); + }); + + test("should get correct identification 3 value from XML", () => { + expect(identification3.value._text).toBe(select(xpath.items.item.identifications.identification3.value, dom)); + }); + + test("should get correct identification 3 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification3.name.content, dom); + expect(toTextArr(identification3.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/AdministrativeData.SoftwareListType.test.ts b/tests/DCC/AdministrativeData.SoftwareListType.test.ts new file mode 100644 index 0000000..6139807 --- /dev/null +++ b/tests/DCC/AdministrativeData.SoftwareListType.test.ts @@ -0,0 +1,41 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { SoftwareListType, DCCDocument, SoftwareType } from "../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:dccSoftware/dcc:software"; +const xpath = { + software: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + release: `string(${base}/dcc:release)`, + type: `string(${base}/dcc:type)`, + description: `${base}/dcc:description`, + _id: `${base}/@id`, + _refType: `${base}/@refType`, + }, +}; + +describe("DccSoftwareType", () => { + let dcc: DCCDocument, dccSoftware: SoftwareListType, software: SoftwareType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + dccSoftware = dcc.digitalCalibrationCertificate.administrativeData.dccSoftware; + software = dccSoftware.software[0]; + }); + + test("should get correct software name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.software.name.content, dom); + expect(toTextArr(software.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct software release version of software from XML", () => { + expect(software.release._text).toBe(select(xpath.software.release, dom)); + }); +}); diff --git a/tests/DCC/AdministrativeData.test.ts b/tests/DCC/AdministrativeData.test.ts new file mode 100644 index 0000000..b6f6ade --- /dev/null +++ b/tests/DCC/AdministrativeData.test.ts @@ -0,0 +1,19 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { testCalibrationLaboratory } from "./common/AdministrativeData/CalibrationLaboratory"; +import { testCoreData } from "./common/AdministrativeData/CoreDataType"; +import { testContactType } from "./common/Types/ContactType"; +import { testRespPersonListType } from "./common/AdministrativeData/RespPersons"; +import { testStatementListType } from "./common/Types/StatementListType"; + +describe(`[example.xml] AdministrativeData`, () => { + const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData"; + testCalibrationLaboratory(); + testCoreData(); + testContactType(`${base}/dcc:customer`, (dcc) => dcc.digitalCalibrationCertificate.administrativeData.customer); + testRespPersonListType(); + testStatementListType(`${base}/dcc:statements`, (dcc) => dcc.digitalCalibrationCertificate.administrativeData.statements); +}); diff --git a/tests/DCC/DigitalCalibrationCertificateType.test.ts b/tests/DCC/DigitalCalibrationCertificateType.test.ts new file mode 100644 index 0000000..eaceec3 --- /dev/null +++ b/tests/DCC/DigitalCalibrationCertificateType.test.ts @@ -0,0 +1,21 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select } from "../util"; + +const VERSION_XPATH = "string(/dcc:digitalCalibrationCertificate/@schemaVersion)"; + +describe("DigitalCalibrationCertificateType", () => { + let xml, dcc, dom; + + beforeEach(() => { + ({ xml, dcc, dom } = xmlEnv.recreateEnv()); + }); + + test("should get correct schemaVersion from XML", () => { + const expectedVersion = select(VERSION_XPATH, dom); + expect(dcc.digitalCalibrationCertificate._attr.schemaVersion).toBe(expectedVersion); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CalibrationLaboratory.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CalibrationLaboratory.test.ts new file mode 100644 index 0000000..0bf3cce --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CalibrationLaboratory.test.ts @@ -0,0 +1,84 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { CalibrationLaboratoryType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:calibrationLaboratory/dcc:contact"; +const xpath = { + name: `string(${base}/dcc:name/dcc:content)`, + eMail: `string(${base}/dcc:eMail)`, + phone: `string(${base}/dcc:phone)`, + fax: `string(${base}/dcc:fax)`, + location: { + city: `${base}/dcc:location/dcc:city`, + countryCode: `${base}/dcc:location/dcc:countryCode`, + postCode: `${base}/dcc:location/dcc:postCode`, + street: `${base}/dcc:location/dcc:street`, + streetNo: `${base}/dcc:location/dcc:streetNo`, + further: `${base}/dcc:location/dcc:further/dcc:content`, + }, +}; + +describe("GP_DCC_Temperature_Simplified: CalibrationLaboratoryType", () => { + let dcc: DCCDocument, calibrationLaboratory: CalibrationLaboratoryType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + calibrationLaboratory = dcc.digitalCalibrationCertificate.administrativeData.calibrationLaboratory; + }); + + test("should get correct name from XML", () => { + expect(calibrationLaboratory.contact.name.content[0]._text).toBe(select(xpath.name, dom)); + }); + + test("should get correct eMail from XML", () => { + expect(calibrationLaboratory.contact.eMail._text).toBe(select(xpath.eMail, dom)); + }); + + test("should get correct phone from XML", () => { + expect(calibrationLaboratory.contact.phone._text).toBe(select(xpath.phone, dom)); + }); + + test("should get correct fax from XML", () => { + expect(calibrationLaboratory.contact.fax._text).toBe(select(xpath.fax, dom)); + }); + + test("should get correct city from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.city, dom); + expect(toTextArr(calibrationLaboratory.contact.location.city)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct countryCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.countryCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.countryCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct postCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.postCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.postCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct street from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.street, dom); + expect(toTextArr(calibrationLaboratory.contact.location.street)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct streetNo from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.streetNo, dom); + expect(toTextArr(calibrationLaboratory.contact.location.streetNo)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct further element from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.further, dom); + expect(toTextArr(calibrationLaboratory.contact.location.further[0].content)).toEqual(toTextContentArr(expected)); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CoreDataType.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CoreDataType.test.ts new file mode 100644 index 0000000..0c3aaf0 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.CoreDataType.test.ts @@ -0,0 +1,118 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import * as fc from "fast-check"; +import { indexOf, select, toTextArr, toTextContentArr } from "../../util"; +import { CoreDataType, DCCDocument, DCCXMLElement } from "../../../src"; +import { string_ISO639_1 } from "../../Arbitraries"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:coreData"; +const xpath = { + coreData: { + countryCodeISO3166_1: `string(${base}/dcc:countryCodeISO3166_1)`, + usedLangCodeISO639_1: `${base}/dcc:usedLangCodeISO639_1`, + mandatoryLangCodeISO639_1: `${base}/dcc:mandatoryLangCodeISO639_1`, + uniqueIdentifier: `string(${base}/dcc:uniqueIdentifier)`, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + }, + beginPerformanceDate: `string(${base}/dcc:beginPerformanceDate)`, + endPerformanceDate: `string(${base}/dcc:endPerformanceDate)`, + performanceLocation: `string(${base}/dcc:performanceLocation)`, + }, +}; + +describe("GP_DCC_Temperature_Simplified: CoreDataType", () => { + let dcc: DCCDocument, coreData: CoreDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + coreData = dcc.digitalCalibrationCertificate.administrativeData.coreData; + }); + + test("should get correct countryCodeISO3166_1 from XML", () => { + expect(coreData.countryCodeISO3166_1._text).toBe(select(xpath.coreData.countryCodeISO3166_1, dom)); + }); + + test("should get correct usedLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom); + expect(toTextArr(coreData.usedLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct mandatoryLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.mandatoryLangCodeISO639_1, dom); + expect(toTextArr(coreData.mandatoryLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct unique identifier from XML", () => { + expect(coreData.uniqueIdentifier._text).toBe(select(xpath.coreData.uniqueIdentifier, dom)); + }); + + test("should get correct identification issuer from XML", () => { + expect(coreData.identifications.identification[0].issuer._text).toBe(select(xpath.coreData.identifications.identification.issuer, dom)); + }); + + test("should get correct identification value from XML", () => { + expect(coreData.identifications.identification[0].value._text).toBe(select(xpath.coreData.identifications.identification.value, dom)); + }); + + test("should get correct identification name content from XML", () => { + const expected = <Element[]>select(xpath.coreData.identifications.identification.name.content, dom); + expect(toTextArr(coreData.identifications.identification[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct begin performance date from XML", () => { + expect(coreData.beginPerformanceDate._text).toBe(select(xpath.coreData.beginPerformanceDate, dom)); + }); + + test("should get correct end performance date from XML", () => { + expect(coreData.endPerformanceDate._text).toBe(select(xpath.coreData.endPerformanceDate, dom)); + }); + + test("should get correct performance location from XML", () => { + expect(coreData.performanceLocation._text).toBe(select(xpath.coreData.performanceLocation, dom)); + }); + + /* test for setters */ + test("should set usedLangCodeISO639_1 correctly", () => { + fc.assert( + fc.property(string_ISO639_1(), (str) => { + // add new element to array + coreData.usedLangCodeISO639_1.push(new DCCXMLElement({ _text: str })); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).toContain(str); + expect(toTextContentArr(actual)).toContain(str); + }), + ); + }); + + test("should delete usedLangCodeISO639_1 correctly", () => { + const selection = toTextContentArr(<Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom)); + fc.assert( + fc.property(fc.constantFrom(...selection), (str) => { + // get index and remove element from array + const index = indexOf(coreData.usedLangCodeISO639_1, str); + coreData.usedLangCodeISO639_1.splice(index, 1); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).not.toContain(str); + expect(toTextContentArr(actual)).not.toContain(str); + }), + ); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Customer.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Customer.test.ts new file mode 100644 index 0000000..99bc252 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Customer.test.ts @@ -0,0 +1,70 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ContactType, DCCDocument, LocationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:customer"; +const xpath = { + customer: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:eMail)`, + location: { + city: `${base}/dcc:location/dcc:city[1]`, + countryCode: `${base}/dcc:location/dcc:countryCode[1]`, + postCode: `${base}/dcc:location/dcc:postCode[1]`, + further: `${base}/dcc:location/dcc:further[1]/dcc:content`, + }, + descriptionData: `${base}/dcc:descriptionData`, + _id: `${base}/@id`, + }, +}; + +describe("GP_DCC_Temperature_Simplified: ContactType", () => { + let dcc: DCCDocument, customer: ContactType, location: LocationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + customer = dcc.digitalCalibrationCertificate.administrativeData.customer; + location = customer.location; /* TODO: check iff this variable is used anywhere */ + }); + + test("should get correct customer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.customer.name.content, dom); + expect(toTextArr(customer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct customer email address from XML", () => { + expect(customer.eMail._text).toBe(select(xpath.customer.email, dom)); + }); + + test("should get correct customer location city from XML", () => { + const expected = <Element[]>select(xpath.customer.location.city, dom); + expect(customer.location.city[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location county code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.countryCode, dom); + expect(customer.location.countryCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location post code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.postCode, dom); + expect(customer.location.postCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location further from XML", () => { + const expected = <Element[]>select(xpath.customer.location.further, dom); + + for (let i = 0; i < expected.length; i++) { + expect(customer.location.further[0].content[i]._text).toBe(expected[i].textContent); + } + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Items.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Items.test.ts new file mode 100644 index 0000000..66f37cf --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Items.test.ts @@ -0,0 +1,117 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ItemType, DCCDocument, IdentificationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:items"; +const xpath = { + items: { + item: { + name: { + content: `${base}/dcc:item[1]/dcc:name/dcc:content`, + }, + manufacturer: { + name: { + content: `${base}/dcc:item[1]/dcc:manufacturer/dcc:name/dcc:content`, + }, + }, + model: `string(${base}/dcc:item[1]/dcc:model)`, + + identifications: { + identification1: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + identification2: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:name/dcc:content`, + }, + }, + identification3: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:name/dcc:content`, + }, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: ItemType", () => { + let dcc: DCCDocument, item: ItemType, identification1, identification2, identification3: IdentificationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + item = dcc.digitalCalibrationCertificate.administrativeData.items.item[0]; + identification1 = item.identifications.identification[0]; + identification2 = item.identifications.identification[1]; + identification3 = item.identifications.identification[2]; + }); + + test("should get correct item name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.name.content, dom); + expect(toTextArr(item.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item manufacturer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.manufacturer.name.content, dom); + expect(toTextArr(item.manufacturer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item model from XML", () => { + expect(item.model._text).toBe(select(xpath.items.item.model, dom)); + }); + + test("should get correct identification 1 issuer from XML", () => { + expect(identification1.issuer._text).toBe(select(xpath.items.item.identifications.identification1.issuer, dom)); + }); + + test("should get correct identification 1 value from XML", () => { + expect(identification1.value._text).toBe(select(xpath.items.item.identifications.identification1.value, dom)); + }); + + test("should get correct identification 1 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification1.name.content, dom); + expect(toTextArr(identification1.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 2 issuer from XML", () => { + expect(identification2.issuer._text).toBe(select(xpath.items.item.identifications.identification2.issuer, dom)); + }); + + test("should get correct identification 2 value from XML", () => { + expect(identification2.value._text).toBe(select(xpath.items.item.identifications.identification2.value, dom)); + }); + + test("should get correct identification 2 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification2.name.content, dom); + expect(toTextArr(identification2.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 3 issuer from XML", () => { + expect(identification3.issuer._text).toBe(select(xpath.items.item.identifications.identification3.issuer, dom)); + }); + + test("should get correct identification 3 value from XML", () => { + expect(identification3.value._text).toBe(select(xpath.items.item.identifications.identification3.value, dom)); + }); + + test("should get correct identification 3 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification3.name.content, dom); + expect(toTextArr(identification3.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.RespPersons.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.RespPersons.test.ts new file mode 100644 index 0000000..8d52086 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.RespPersons.test.ts @@ -0,0 +1,56 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { RespPersonType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:respPersons"; +const xpath = { + respPersons: { + respPerson1: { + person: { + name: { + content: `${base}/dcc:respPerson[1]/dcc:person/dcc:name/dcc:content`, + }, + }, + mainSigner: `string(${base}/dcc:respPerson[1]/dcc:mainSigner)`, + }, + respPerson2: { + person: { + name: { + content: `${base}/dcc:respPerson[2]/dcc:person/dcc:name/dcc:content`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: RespPersonType", () => { + let dcc: DCCDocument, respPerson1, respPerson2: RespPersonType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + respPerson1 = dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[0]; + respPerson2 = dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[1]; + }); + + test("should get correct responsible person 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.respPersons.respPerson1.person.name.content, dom); + expect(toTextArr(respPerson1.person.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct responsible person 1 main signer flag from XML", () => { + expect(respPerson1.mainSigner._text).toBe(select(xpath.respPersons.respPerson1.mainSigner, dom)); + }); + + test("should get correct responsible person 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.respPersons.respPerson2.person.name.content, dom); + expect(toTextArr(respPerson2.person.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.SoftwareListType.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.SoftwareListType.test.ts new file mode 100644 index 0000000..fb27ba6 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.SoftwareListType.test.ts @@ -0,0 +1,37 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { SoftwareListType, DCCDocument, SoftwareType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:dccSoftware/dcc:software"; +const xpath = { + software: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + release: `string(${base}/dcc:release)`, + }, +}; + +describe("GP_DCC_Temperature_Simplified: DccSoftwareType", () => { + let dcc: DCCDocument, dccSoftware: SoftwareListType, software: SoftwareType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + dccSoftware = dcc.digitalCalibrationCertificate.administrativeData.dccSoftware; + software = dccSoftware.software[0]; + }); + + test("should get correct software name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.software.name.content, dom); + expect(toTextArr(software.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct software release version of software from XML", () => { + expect(software.release._text).toBe(select(xpath.software.release, dom)); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Statements.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Statements.test.ts new file mode 100644 index 0000000..f68a629 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/AdministrativeData.Statements.test.ts @@ -0,0 +1,127 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { StatementMetaDataType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:statements"; +const xpath = { + statements: { + statement1: { + declaration: { + content: `${base}/dcc:statement[1]/dcc:declaration/dcc:content`, + }, + respAuthority: { + name: { + content: `${base}/dcc:statement[1]/dcc:respAuthority/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:eMail)`, + location: { + city: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:location/dcc:city)`, + countryCode: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:location/dcc:countryCode)`, + postCode: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:location/dcc:postCode)`, + }, + }, + conformity: `string(${base}/dcc:statement[1]/dcc:conformity)`, + refType: `string(${base}/dcc:statement[1]/@refType)`, + }, + statement2: { + declaration: { + content: `${base}/dcc:statement[2]/dcc:declaration/dcc:content`, + }, + date: `string(${base}/dcc:statement[2]/dcc:date)`, + respAuthority: { + name: { + content: `${base}/dcc:statement[2]/dcc:respAuthority/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:eMail)`, + location: { + city: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:location/dcc:city)`, + countryCode: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:location/dcc:countryCode)`, + postCode: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:location/dcc:postCode)`, + }, + }, + refType: `string(${base}/dcc:statement[2]/@refType)`, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: StatementMetaDataType", () => { + let dcc: DCCDocument, statement1, statement2: StatementMetaDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + statement1 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[0]; + statement2 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[1]; + }); + + test("should get correct statement 1 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement1.declaration.content, dom); + expect(toTextArr(statement1.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + /* responsible authority 1 */ + test("should get correct statement 1 responsible authority name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement1.respAuthority.name.content, dom); + expect(toTextArr(statement1.respAuthority.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 1 responsible authority email from XML", () => { + expect(statement1.respAuthority.eMail._text).toBe(select(xpath.statements.statement1.respAuthority.email, dom)); + }); + + test("should get correct statement 1 responsible authority location city from XML", () => { + expect(statement1.respAuthority.location.city[0]._text).toBe(select(xpath.statements.statement1.respAuthority.location.city, dom)); + }); + test("should get correct statement 1 responsible authority location country code from XML", () => { + expect(statement1.respAuthority.location.countryCode[0]._text).toBe(select(xpath.statements.statement1.respAuthority.location.countryCode, dom)); + }); + test("should get correct statement 1 responsible authority location post code from XML", () => { + expect(statement1.respAuthority.location.postCode[0]._text).toBe(select(xpath.statements.statement1.respAuthority.location.postCode, dom)); + }); + + test("should get correct statement 1 conformity from XML", () => { + expect(statement1.conformity._text).toBe(select(xpath.statements.statement1.conformity, dom)); + }); + + test("should get correct statement 2 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement2.declaration.content, dom); + expect(toTextArr(statement2.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 2 refType from XML", () => { + expect(statement2.date._text).toBe(select(xpath.statements.statement2.date, dom)); + }); + + /* responsible authority 2 */ + test("should get correct statement 2 responsible authority name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement2.respAuthority.name.content, dom); + expect(toTextArr(statement2.respAuthority.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 2 responsible authority email from XML", () => { + expect(statement2.respAuthority.eMail._text).toBe(select(xpath.statements.statement2.respAuthority.email, dom)); + }); + + test("should get correct statement 2 responsible authority location city from XML", () => { + expect(statement2.respAuthority.location.city[0]._text).toBe(select(xpath.statements.statement2.respAuthority.location.city, dom)); + }); + test("should get correct statement 2 responsible authority location country code from XML", () => { + expect(statement2.respAuthority.location.countryCode[0]._text).toBe(select(xpath.statements.statement2.respAuthority.location.countryCode, dom)); + }); + test("should get correct statement 2 responsible authority location post code from XML", () => { + expect(statement2.respAuthority.location.postCode[0]._text).toBe(select(xpath.statements.statement2.respAuthority.location.postCode, dom)); + }); + + test("should get correct statement 2 refType from XML", () => { + expect(statement2._attr.refType).toBe(select(xpath.statements.statement2.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/DigitalCalibrationCertificateType.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/DigitalCalibrationCertificateType.test.ts new file mode 100644 index 0000000..df17932 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/DigitalCalibrationCertificateType.test.ts @@ -0,0 +1,21 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select } from "../../util"; + +const VERSION_XPATH = "string(/dcc:digitalCalibrationCertificate/@schemaVersion)"; + +describe("GP_DCC_Temperature_Simplified: DigitalCalibrationCertificateType", () => { + let xml, dcc, dom; + + beforeEach(() => { + ({ xml, dcc, dom } = xmlEnv.recreateEnv()); + }); + + test("should get correct schemaVersion from XML", () => { + const expectedVersion = select(VERSION_XPATH, dom); + expect(dcc.digitalCalibrationCertificate._attr.schemaVersion).toBe(expectedVersion); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts new file mode 100644 index 0000000..f989c1d --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts @@ -0,0 +1,218 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, InfluenceConditionListType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:influenceConditions"; +const xpath = { + measurementResults: { + measurementResult: { + influenceConditions: { + influenceCondition1: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[1]/dcc:description/dcc:content`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[1]//@refType)`, + }, + influenceCondition2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='en']`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[2]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: InfluenceConditionListType", () => { + let dcc: DCCDocument, influenceConditions: InfluenceConditionListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + influenceConditions = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].influenceConditions; + }); + + test("should get correct influence condition 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity si:value from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 1 quantity si:unit from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 1 quantity 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.refType, dom), + ); + }); + + test("should get correct influence condition 1 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 1 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 1 quantity 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity2.refType, dom), + ); + }); + + test("should get correct influence condition 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.refType, dom), + ); + }); + + test("should get correct influence condition 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 1 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 quantity 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.refType, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.refType, dom), + ); + }); + + test("should get correct influence condition 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts new file mode 100644 index 0000000..d130350 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts @@ -0,0 +1,58 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, MeasuringEquipmentType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:measuringEquipments/dcc:measuringEquipment[1]"; +const xpath = { + measuringEquipments: { + measuringEquipment: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + }, + }, + refType: `string(${base}//@refType)`, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: MeasuringEquipmentType", () => { + let dcc: DCCDocument, measuringEquipment: MeasuringEquipmentType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measuringEquipment = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].measuringEquipments.measuringEquipment[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measuringEquipments.measuringEquipment.name.content, dom); + expect(toTextArr(measuringEquipment.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct measuring equipment 1 identification issuer from XML", () => { + expect(measuringEquipment.identifications.identification[0].issuer._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.issuer, dom), + ); + }); + + test("should get correct measuring equipment 1 identification value from XML", () => { + expect(measuringEquipment.identifications.identification[0].value._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.value, dom), + ); + }); + + test("should get correct measuring equipment 1 refType from XML", () => { + expect(measuringEquipment._attr.refType).toBe(select(xpath.measuringEquipments.measuringEquipment.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Name.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Name.test.ts new file mode 100644 index 0000000..6fad3df --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Name.test.ts @@ -0,0 +1,35 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, MeasurementResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults"; +const xpath = { + measurementResults: { + measurementResult: { + name: { + content: `${base}/dcc:measurementResult[1]/dcc:name/dcc:content`, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: MeasurementResultType", () => { + let dcc: DCCDocument, measurementResult: MeasurementResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measurementResult = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.name.content, dom); + expect(toTextArr(measurementResult.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Results.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Results.test.ts new file mode 100644 index 0000000..4fd7681 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.Results.test.ts @@ -0,0 +1,339 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, ResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:results"; +const xpath = { + measurementResults: { + measurementResult: { + results: { + result: { + name: { + content: `${base}/dcc:result[1]/dcc:name/dcc:content`, + }, + data: { + list: { + quantity1: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]//@refType)`, + }, + quantity3: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:name/dcc:content`, + }, + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:unitXMLList)`, + si_expandedUncXMLList: { + si_uncertaintyXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:uncertaintyXMLList)`, + si_coverageFactorXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageFactorXMLList)`, + si_coverageProbabilityXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageProbabilityXMLList)`, + si_distributionXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:distributionXMLList)`, + }, + }, + measurementMetaData: { + metaData: { + declaration: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData[1]/dcc:declaration/dcc:name/dcc:content`, + }, + }, + conformityXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:conformityXMLList)`, + data: { + quantity1: { + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:realListXMLList/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:realListXMLList/si:unitXMLList)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[2]/si:realListXMLList/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[2]/si:realListXMLList/si:unitXMLList)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/@refType)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: ResultType", () => { + let dcc: DCCDocument, result: ResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + result = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].results.result[0]; + }); + + test("should get correct result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.name.content, dom); + expect(toTextArr(result.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:unitXMLList 2: from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 2 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:unitXMLList 2: from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 3 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[2].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 3 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 3 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 3 uncertainty list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.uncertaintyXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_uncertaintyXMLList, dom), + ); + }); + + test("should get correct result quantity 3 uncertainty coverage factor list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageFactorXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageFactorXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 uncertainty coverage probability list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageProbabilityXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageProbabilityXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 uncertainty distribution list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.distributionXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_distributionXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 meta data declaration name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.declaration.name.content, dom) + ); + expect(toTextArr(result.data.list[0].quantity[2].measurementMetaData.metaData[0].declaration.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 3 meta data conformityXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].conformityXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.conformityXMLList, dom), + ); + }); + + test("should get correct result quantity 3 meta data quantity 1 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[0].realListXMLList.valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity1.si_realListXMLList + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 meta data quantity 1 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[0].realListXMLList.unitXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity1.si_realListXMLList + .si_unitXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 meta data quantity 2 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[1].realListXMLList.valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity2.si_realListXMLList + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 meta data quantity 2 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[1].realListXMLList.valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity2.si_realListXMLList + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 meta data quantity 2 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[1].realListXMLList.unitXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity2.si_realListXMLList + .si_unitXMLList, + dom, + ), + ); + }); + + test("should get correct result refType from XML", () => { + expect(result._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.refType, dom)); + }); + + test("should get correct result data list refType from XML", () => { + expect(result.data.list[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.list.refType, dom)); + }); + + test("should get correct result quantity 1 refType from XML", () => { + expect(result.data.list[0].quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.refType, dom), + ); + }); + + test("should get correct result quantity2 refType from XML", () => { + expect(result.data.list[0].quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.refType, dom), + ); + }); + + test("should get correct result quantity3 refType from XML", () => { + expect(result.data.list[0].quantity[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.refType, dom), + ); + }); + + test("should get correct result quantity 3 meta data refType from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.refType, dom), + ); + }); + + test("should get correct result quantity 2 refType from XML", () => { + expect(result.data.list[0].quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.refType, dom), + ); + }); + + test("should get correct result quantity 3 refType from XML", () => { + expect(result.data.list[0].quantity[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.UsedMethods.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.UsedMethods.test.ts new file mode 100644 index 0000000..6becd0f --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified/MeasurementResults.MeasurementResult.UsedMethods.test.ts @@ -0,0 +1,44 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, UsedMethodListType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]"; +const xpath = { + measurementResults: { + measurementResult: { + usedMethods: { + usedMethod1: { + name: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:name/dcc:content`, + }, + refType: `string(${base}/dcc:usedMethods/dcc:usedMethod[1]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: UsedMethodListType", () => { + let dcc: DCCDocument, usedMethods: UsedMethodListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + usedMethods = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].usedMethods; + }); + + test("should get correct used method 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.name.content, dom); + expect(toTextArr(usedMethods.usedMethod[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 1 refType from XML", () => { + expect(usedMethods.usedMethod[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Items_variant.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Items_variant.test.ts new file mode 100644 index 0000000..de4e310 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Items_variant.test.ts @@ -0,0 +1,37 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified_variant.xml + */ + +import { select } from "../../util"; +import { ItemType, DCCDocument, EquipmentClassType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:items"; +const xpath = { + items: { + item: { + equipmentClass: { + reference: `string(${base}/dcc:item[1]/dcc:equipmentClass[1]/dcc:reference)`, + classID: `string(${base}/dcc:item[1]/dcc:equipmentClass[1]/dcc:classID)`, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: ItemType", () => { + let dcc: DCCDocument, item: ItemType, equipmentClass: EquipmentClassType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + item = dcc.digitalCalibrationCertificate.administrativeData.items.item[0]; + equipmentClass = item.equipmentClass[0]; + }); + + test("should get correct equipmentClass reference from XML", () => { + expect(equipmentClass.reference._text).toBe(select(xpath.items.item.equipmentClass.reference, dom)); + }); + + test("should get correct equipmentClass classID from XML", () => { + expect(equipmentClass.classID._text).toBe(select(xpath.items.item.equipmentClass.classID, dom)); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Statements_variant.test.ts b/tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Statements_variant.test.ts new file mode 100644 index 0000000..26ad9a3 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Simplified_variant/AdministrativeData.Statements_variant.test.ts @@ -0,0 +1,95 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Simplified_variant.xml + */ + +import * as fc from "fast-check"; +import { select, toTextArr, toTextContentArr, indexOf } from "../../util"; +import { StatementMetaDataType, DCCDocument, DCCXMLElement } from "../../../src"; +import { string_ISO3166_1 } from "../../Arbitraries"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:statements"; +const xpath = { + statements: { + statement3: { + countryCodeISO3166_1: `${base}/dcc:statement[3]/dcc:countryCodeISO3166_1`, + convention: `string(${base}/dcc:statement[3]/dcc:convention)`, + traceable: `string(${base}/dcc:statement[3]/dcc:traceable)`, + period: `string(${base}/dcc:statement[3]/dcc:period)`, + nonSIDefinition: `string(${base}/dcc:statement[3]/dcc:nonSIDefinition)`, + nonSIUnit: `string(${base}/dcc:statement[3]/dcc:nonSIUnit)`, + }, + }, +}; + +describe("GP_DCC_Temperature_Simplified: StatementMetaDataType", () => { + let dcc: DCCDocument, statement3: StatementMetaDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + statement3 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[2]; + }); + + test("should get correct statement 3 countryCodeISO3166_1 from XML", () => { + const expected = <Element[]>select(xpath.statements.statement3.countryCodeISO3166_1, dom); + expect(toTextArr(statement3.countryCodeISO3166_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 3 convention from XML", () => { + const expected = select(xpath.statements.statement3.convention, dom); + expect(statement3.convention._text).toEqual(expected); + }); + + test("should get correct statement 3 traceable from XML", () => { + const expected = select(xpath.statements.statement3.traceable, dom); + expect(statement3.traceable._text).toEqual(expected); + }); + + test("should get correct statement 3 period from XML", () => { + const expected = select(xpath.statements.statement3.period, dom); + expect(statement3.period._text).toEqual(expected); + }); + + test("should get correct statement 3 nonSIDefinition from XML", () => { + const expected = select(xpath.statements.statement3.nonSIDefinition, dom); + expect(statement3.nonSIDefinition._text).toEqual(expected); + }); + + test("should get correct statement 3 nonSIUnit from XML", () => { + const expected = select(xpath.statements.statement3.nonSIUnit, dom); + expect(statement3.nonSIUnit._text).toEqual(expected); + }); + + /* test for setters */ + test("should set statement 3 countryCodeISO3166_1 correctly", () => { + fc.assert( + fc.property(string_ISO3166_1(), (str) => { + // add new element to array + statement3.countryCodeISO3166_1.push(new DCCXMLElement({ _text: str })); + + // get actual list from xml + const actual = <Element[]>select(xpath.statements.statement3.countryCodeISO3166_1, dcc); + + expect(toTextArr(statement3.countryCodeISO3166_1)).toContain(str); + expect(toTextContentArr(actual)).toContain(str); + }), + ); + }); + + test("should delete statement 3 countryCodeISO3166_1 correctly", () => { + const selection = toTextContentArr(<Element[]>select(xpath.statements.statement3.countryCodeISO3166_1, dom)); + fc.assert( + fc.property(fc.constantFrom(...selection), (str) => { + // get index and remove element from array + const index = indexOf(statement3.countryCodeISO3166_1, str); + statement3.countryCodeISO3166_1.splice(index, 1); + + // get actual list from xml + const actual = <Element[]>select(xpath.statements.statement3.countryCodeISO3166_1, dcc); + + expect(toTextArr(statement3.countryCodeISO3166_1)).not.toContain(str); + expect(toTextContentArr(actual)).not.toContain(str); + }), + ); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CalibrationLaboratory.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CalibrationLaboratory.test.ts new file mode 100644 index 0000000..fdaf96a --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CalibrationLaboratory.test.ts @@ -0,0 +1,80 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { CalibrationLaboratoryType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:calibrationLaboratory/dcc:contact"; +const xpath = { + name: `string(${base}/dcc:name/dcc:content)`, + eMail: `string(${base}/dcc:eMail)`, + phone: `string(${base}/dcc:phone)`, + fax: `string(${base}/dcc:fax)`, + location: { + city: `${base}/dcc:location/dcc:city`, + countryCode: `${base}/dcc:location/dcc:countryCode`, + postCode: `${base}/dcc:location/dcc:postCode`, + street: `${base}/dcc:location/dcc:street`, + streetNo: `${base}/dcc:location/dcc:streetNo`, + further: `${base}/dcc:location/dcc:further/dcc:content`, + }, +}; + +describe("GP_DCC_Temperature_Typical: CalibrationLaboratoryType", () => { + let dcc: DCCDocument, calibrationLaboratory: CalibrationLaboratoryType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + calibrationLaboratory = dcc.digitalCalibrationCertificate.administrativeData.calibrationLaboratory; + }); + + test("should get correct name from XML", () => { + expect(calibrationLaboratory.contact.name.content[0]._text).toBe(select(xpath.name, dom)); + }); + + test("should get correct eMail from XML", () => { + expect(calibrationLaboratory.contact.eMail._text).toBe(select(xpath.eMail, dom)); + }); + + test("should get correct phone from XML", () => { + expect(calibrationLaboratory.contact.phone._text).toBe(select(xpath.phone, dom)); + }); + + test("should get correct city from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.city, dom); + expect(toTextArr(calibrationLaboratory.contact.location.city)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct countryCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.countryCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.countryCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct postCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.postCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.postCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct street from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.street, dom); + expect(toTextArr(calibrationLaboratory.contact.location.street)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct streetNo from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.streetNo, dom); + expect(toTextArr(calibrationLaboratory.contact.location.streetNo)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct further element from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.further, dom); + expect(toTextArr(calibrationLaboratory.contact.location.further[0].content)).toEqual(toTextContentArr(expected)); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CoreDataType.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CoreDataType.test.ts new file mode 100644 index 0000000..da8c8ee --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.CoreDataType.test.ts @@ -0,0 +1,120 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import * as fc from "fast-check"; +import { indexOf, select, toTextArr, toTextContentArr } from "../../util"; +import { CoreDataType, DCCDocument, DCCXMLElement } from "../../../src"; +import { string_ISO639_1 } from "../../Arbitraries"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:coreData"; +const xpath = { + coreData: { + countryCodeISO3166_1: `string(${base}/dcc:countryCodeISO3166_1)`, + usedLangCodeISO639_1: `${base}/dcc:usedLangCodeISO639_1`, + mandatoryLangCodeISO639_1: `${base}/dcc:mandatoryLangCodeISO639_1`, + uniqueIdentifier: `string(${base}/dcc:uniqueIdentifier)`, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + }, + receiptDate: `string(${base}/dcc:receiptDate)`, + beginPerformanceDate: `string(${base}/dcc:beginPerformanceDate)`, + endPerformanceDate: `string(${base}/dcc:endPerformanceDate)`, + performanceLocation: `string(${base}/dcc:performanceLocation)`, + }, +}; + +describe("GP_DCC_Temperature_Typical: CoreDataType", () => { + let dcc: DCCDocument, coreData: CoreDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + coreData = dcc.digitalCalibrationCertificate.administrativeData.coreData; + }); + + test("should get correct countryCodeISO3166_1 from XML", () => { + expect(coreData.countryCodeISO3166_1._text).toBe(select(xpath.coreData.countryCodeISO3166_1, dom)); + }); + + test("should get correct usedLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom); + expect(toTextArr(coreData.usedLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct mandatoryLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.mandatoryLangCodeISO639_1, dom); + expect(toTextArr(coreData.mandatoryLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct unique identifier from XML", () => { + expect(coreData.uniqueIdentifier._text).toBe(select(xpath.coreData.uniqueIdentifier, dom)); + }); + + test("should get correct identification issuer from XML", () => { + expect(coreData.identifications.identification[0].issuer._text).toBe(select(xpath.coreData.identifications.identification.issuer, dom)); + }); + + test("should get correct identification value from XML", () => { + expect(coreData.identifications.identification[0].value._text).toBe(select(xpath.coreData.identifications.identification.value, dom)); + }); + + test("should get correct identification name content from XML", () => { + const expected = <Element[]>select(xpath.coreData.identifications.identification.name.content, dom); + expect(toTextArr(coreData.identifications.identification[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct receipt date from XML", () => { + expect(coreData.receiptDate._text).toBe(select(xpath.coreData.receiptDate, dom)); + }); + test("should get correct begin performance date from XML", () => { + expect(coreData.beginPerformanceDate._text).toBe(select(xpath.coreData.beginPerformanceDate, dom)); + }); + test("should get correct end performance date from XML", () => { + expect(coreData.endPerformanceDate._text).toBe(select(xpath.coreData.endPerformanceDate, dom)); + }); + test("should get correct performance location from XML", () => { + expect(coreData.performanceLocation._text).toBe(select(xpath.coreData.performanceLocation, dom)); + }); + + /* test for setters */ + test("should set usedLangCodeISO639_1 correctly", () => { + fc.assert( + fc.property(string_ISO639_1(), (str) => { + // add new element to array + coreData.usedLangCodeISO639_1.push(new DCCXMLElement({ _text: str })); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).toContain(str); + expect(toTextContentArr(actual)).toContain(str); + }), + ); + }); + + test("should delete usedLangCodeISO639_1 correctly", () => { + const selection = toTextContentArr(<Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom)); + fc.assert( + fc.property(fc.constantFrom(...selection), (str) => { + // get index and remove element from array + const index = indexOf(coreData.usedLangCodeISO639_1, str); + coreData.usedLangCodeISO639_1.splice(index, 1); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).not.toContain(str); + expect(toTextContentArr(actual)).not.toContain(str); + }), + ); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Customer.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Customer.test.ts new file mode 100644 index 0000000..e03dd5c --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Customer.test.ts @@ -0,0 +1,77 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ContactType, DCCDocument, LocationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:customer"; +const xpath = { + customer: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:eMail)`, + phone: `string(${base}/dcc:phone)`, + fax: `string(${base}/dcc:fax)`, + location: { + city: `${base}/dcc:location/dcc:city[1]`, + countryCode: `${base}/dcc:location/dcc:countryCode[1]`, + postCode: `${base}/dcc:location/dcc:postCode[1]`, + postBoxOffice: `${base}/dcc:location/dcc:postBoxOffice[1]`, + state: `${base}/dcc:location/dcc:state[1]`, + street: `${base}/dcc:location/dcc:street[1]`, + streetNo: `${base}/dcc:location/dcc:streetNo[1]`, + further: `${base}/dcc:location/dcc:further[1]/dcc:content`, + positionCoordinates: `${base}/dcc:location/dcc:positionCoordinates[1]`, + }, + descriptionData: `${base}/dcc:descriptionData`, + _id: `${base}/@id`, + }, +}; + +describe("GP_DCC_Temperature_Typical: ContactType", () => { + let dcc: DCCDocument, customer: ContactType, location: LocationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + customer = dcc.digitalCalibrationCertificate.administrativeData.customer; + location = customer.location; /* TODO: check iff this variable is used anywhere */ + }); + + test("should get correct customer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.customer.name.content, dom); + expect(toTextArr(customer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct customer email address from XML", () => { + expect(customer.eMail._text).toBe(select(xpath.customer.email, dom)); + }); + + test("should get correct customer location city from XML", () => { + const expected = <Element[]>select(xpath.customer.location.city, dom); + expect(customer.location.city[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location county code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.countryCode, dom); + expect(customer.location.countryCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location post code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.postCode, dom); + expect(customer.location.postCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location further from XML", () => { + const expected = <Element[]>select(xpath.customer.location.further, dom); + + for (let i = 0; i < expected.length; i++) { + expect(customer.location.further[0].content[i]._text).toBe(expected[i].textContent); + } + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Items.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Items.test.ts new file mode 100644 index 0000000..dce1bac --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Items.test.ts @@ -0,0 +1,117 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ItemType, DCCDocument, IdentificationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:items"; +const xpath = { + items: { + item: { + name: { + content: `${base}/dcc:item[1]/dcc:name/dcc:content`, + }, + manufacturer: { + name: { + content: `${base}/dcc:item[1]/dcc:manufacturer/dcc:name/dcc:content`, + }, + }, + model: `string(${base}/dcc:item[1]/dcc:model)`, + + identifications: { + identification1: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + identification2: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:name/dcc:content`, + }, + }, + identification3: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:name/dcc:content`, + }, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: ItemType", () => { + let dcc: DCCDocument, item: ItemType, identification1, identification2, identification3: IdentificationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + item = dcc.digitalCalibrationCertificate.administrativeData.items.item[0]; + identification1 = item.identifications.identification[0]; + identification2 = item.identifications.identification[1]; + identification3 = item.identifications.identification[2]; + }); + + test("should get correct item name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.name.content, dom); + expect(toTextArr(item.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item manufacturer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.manufacturer.name.content, dom); + expect(toTextArr(item.manufacturer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item model from XML", () => { + expect(item.model._text).toBe(select(xpath.items.item.model, dom)); + }); + + test("should get correct identification 1 issuer from XML", () => { + expect(identification1.issuer._text).toBe(select(xpath.items.item.identifications.identification1.issuer, dom)); + }); + + test("should get correct identification 1 value from XML", () => { + expect(identification1.value._text).toBe(select(xpath.items.item.identifications.identification1.value, dom)); + }); + + test("should get correct identification 1 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification1.name.content, dom); + expect(toTextArr(identification1.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 2 issuer from XML", () => { + expect(identification2.issuer._text).toBe(select(xpath.items.item.identifications.identification2.issuer, dom)); + }); + + test("should get correct identification 2 value from XML", () => { + expect(identification2.value._text).toBe(select(xpath.items.item.identifications.identification2.value, dom)); + }); + + test("should get correct identification 2 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification2.name.content, dom); + expect(toTextArr(identification2.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 3 issuer from XML", () => { + expect(identification3.issuer._text).toBe(select(xpath.items.item.identifications.identification3.issuer, dom)); + }); + + test("should get correct identification 3 value from XML", () => { + expect(identification3.value._text).toBe(select(xpath.items.item.identifications.identification3.value, dom)); + }); + + test("should get correct identification 3 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification3.name.content, dom); + expect(toTextArr(identification3.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.RespPersons.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.RespPersons.test.ts new file mode 100644 index 0000000..583b3f8 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.RespPersons.test.ts @@ -0,0 +1,56 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { RespPersonType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:respPersons"; +const xpath = { + respPersons: { + respPerson1: { + person: { + name: { + content: `${base}/dcc:respPerson[1]/dcc:person/dcc:name/dcc:content`, + }, + }, + mainSigner: `string(${base}/dcc:respPerson[1]/dcc:mainSigner)`, + }, + respPerson2: { + person: { + name: { + content: `${base}/dcc:respPerson[2]/dcc:person/dcc:name/dcc:content`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: RespPersonType", () => { + let dcc: DCCDocument, respPerson1, respPerson2: RespPersonType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + respPerson1 = dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[0]; + respPerson2 = dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[1]; + }); + + test("should get correct responsible person 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.respPersons.respPerson1.person.name.content, dom); + expect(toTextArr(respPerson1.person.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct responsible person 1 main signer flag from XML", () => { + expect(respPerson1.mainSigner._text).toBe(select(xpath.respPersons.respPerson1.mainSigner, dom)); + }); + + test("should get correct responsible person 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.respPersons.respPerson2.person.name.content, dom); + expect(toTextArr(respPerson2.person.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.SoftwareListType.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.SoftwareListType.test.ts new file mode 100644 index 0000000..cb02695 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.SoftwareListType.test.ts @@ -0,0 +1,39 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { SoftwareListType, DCCDocument, SoftwareType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:dccSoftware/dcc:software"; +const xpath = { + software: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + release: `string(${base}/dcc:release)`, + _id: `${base}/@id`, + _refType: `${base}/@refType`, + }, +}; + +describe("GP_DCC_Temperature_Typical: DccSoftwareType", () => { + let dcc: DCCDocument, dccSoftware: SoftwareListType, software: SoftwareType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + dccSoftware = dcc.digitalCalibrationCertificate.administrativeData.dccSoftware; + software = dccSoftware.software[0]; + }); + + test("should get correct software name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.software.name.content, dom); + expect(toTextArr(software.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct software release version of software from XML", () => { + expect(software.release._text).toBe(select(xpath.software.release, dom)); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Statements.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Statements.test.ts new file mode 100644 index 0000000..0c5ae36 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/AdministrativeData.Statements.test.ts @@ -0,0 +1,213 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { StatementMetaDataType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:statements"; +const xpath = { + statements: { + statement1: { + norm: `string(${base}/dcc:statement[1]/dcc:norm)`, + reference: `string(${base}/dcc:statement[1]/dcc:reference)`, + declaration: { + content: `${base}/dcc:statement[1]/dcc:declaration/dcc:content`, + }, + refType: `string(${base}/dcc:statement[1]/@refType)`, + }, + statement2: { + declaration: { + content: `${base}/dcc:statement[2]/dcc:declaration/dcc:content`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:statement[2]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:statement[2]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:statement[2]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + }, + quantity2: { + name: { + content: `${base}/dcc:statement[2]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:statement[2]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:statement[2]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + }, + }, + refType: `string(${base}/dcc:statement[2]/@refType)`, + }, + statement3: { + declaration: { + content: `${base}/dcc:statement[3]/dcc:declaration/dcc:content`, + }, + respAuthority: { + name: { + content: `${base}/dcc:statement[3]/dcc:respAuthority/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:email)`, + location: { + city: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:location/dcc:city)`, + countryCode: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:location/dcc:countryCode)`, + postCode: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:location/dcc:postCode)`, + }, + }, + conformity: `string(${base}/dcc:statement[3]/dcc:conformity)`, + refType: `string(${base}/dcc:statement[3]/@refType)`, + }, + statement4: { + declaration: { + content: `${base}/dcc:statement[4]/dcc:declaration/dcc:content`, + }, + date: `string(${base}/dcc:statement[4]/dcc:date)`, + respAuthority: { + name: { + content: `${base}/dcc:statement[3]/dcc:respAuthority/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:email)`, + location: { + city: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:location/dcc:city)`, + countryCode: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:location/dcc:countryCode)`, + postCode: `string(${base}/dcc:statement[3]/dcc:respAuthority/dcc:location/dcc:postCode)`, + }, + }, + refType: `string(${base}/dcc:statement[4]/@refType)`, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: StatementMetaDataType", () => { + let dcc: DCCDocument, statement1, statement2, statement3, statement4: StatementMetaDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + statement1 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[0]; + statement2 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[1]; + statement3 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[2]; + statement4 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[3]; + }); + + test("should get correct statement 1 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement1.declaration.content, dom); + expect(toTextArr(statement1.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 1 norm model from XML", () => { + expect(statement1.norm[0]._text).toBe(select(xpath.statements.statement1.norm, dom)); + }); + + test("should get correct statement 1 reference from XML", () => { + expect(statement1.reference[0]._text).toBe(select(xpath.statements.statement1.reference, dom)); + }); + + test("should get correct statement 2 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement2.declaration.content, dom); + expect(toTextArr(statement2.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 2 data quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement2.data.quantity1.name.content, dom); + expect(toTextArr(statement2.data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 2 data quantity 1 si:value from XML", () => { + expect(statement2.data.quantity[0].real.value._text).toBe(select(xpath.statements.statement2.data.quantity1.si_real.si_value, dom)); + }); + + test("should get correct statement 2 data quantity 2 si:unit from XML", () => { + expect(statement2.data.quantity[0].real.unit._text).toBe(select(xpath.statements.statement2.data.quantity1.si_real.si_unit, dom)); + }); + + test("should get correct statement 2 data quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement2.data.quantity2.name.content, dom); + expect(toTextArr(statement2.data.quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 2 data quantity 2 si:value from XML", () => { + expect(statement2.data.quantity[1].real.value._text).toBe(select(xpath.statements.statement2.data.quantity2.si_real.si_value, dom)); + }); + + test("should get correct statement 2 data quantity 2 si:unit from XML", () => { + expect(statement2.data.quantity[1].real.unit._text).toBe(select(xpath.statements.statement2.data.quantity2.si_real.si_unit, dom)); + }); + + test("should get correct statement 2 refType from XML", () => { + expect(statement2._attr.refType).toBe(select(xpath.statements.statement2.refType, dom)); + }); + + test("should get correct statement 3 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement3.declaration.content, dom); + expect(toTextArr(statement3.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 3 responsible authority name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement3.respAuthority.name.content, dom); + expect(toTextArr(statement3.respAuthority.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* responsible authority 3 */ + test("should get correct statement 3 responsible authority email from XML", () => { + expect(statement3.respAuthority.eMail._text).toBe(select(xpath.statements.statement3.respAuthority.email, dom)); + }); + + test("should get correct statement 3 responsible authority location city from XML", () => { + expect(statement3.respAuthority.location.city[0]._text).toBe(select(xpath.statements.statement3.respAuthority.location.city, dom)); + }); + test("should get correct statement 3 responsible authority location country code from XML", () => { + expect(statement3.respAuthority.location.countryCode[0]._text).toBe(select(xpath.statements.statement3.respAuthority.location.countryCode, dom)); + }); + test("should get correct statement 3 responsible authority location post code from XML", () => { + expect(statement3.respAuthority.location.postCode[0]._text).toBe(select(xpath.statements.statement3.respAuthority.location.postCode, dom)); + }); + + test("should get correct statement 3 conformity from XML", () => { + expect(statement3.conformity._text).toBe(select(xpath.statements.statement3.conformity, dom)); + }); + + test("should get correct statement 3 refType from XML", () => { + expect(statement3._attr.refType).toBe(select(xpath.statements.statement3.refType, dom)); + }); + + test("should get correct statement 4 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement4.declaration.content, dom); + expect(toTextArr(statement4.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 4 date from XML", () => { + expect(statement4.date._text).toBe(select(xpath.statements.statement4.date, dom)); + }); + + /* responsible authority 4 */ + test("should get correct statement 4 responsible authority email from XML", () => { + expect(statement4.respAuthority.eMail._text).toBe(select(xpath.statements.statement4.respAuthority.email, dom)); + }); + + test("should get correct statement 4 responsible authority location city from XML", () => { + expect(statement4.respAuthority.location.city[0]._text).toBe(select(xpath.statements.statement4.respAuthority.location.city, dom)); + }); + test("should get correct statement 4 responsible authority location country code from XML", () => { + expect(statement4.respAuthority.location.countryCode[0]._text).toBe(select(xpath.statements.statement4.respAuthority.location.countryCode, dom)); + }); + test("should get correct statement 4 responsible authority location post code from XML", () => { + expect(statement4.respAuthority.location.postCode[0]._text).toBe(select(xpath.statements.statement4.respAuthority.location.postCode, dom)); + }); + + test("should get correct statement 4 refType from XML", () => { + expect(statement4._attr.refType).toBe(select(xpath.statements.statement4.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/DigitalCalibrationCertificateType.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/DigitalCalibrationCertificateType.test.ts new file mode 100644 index 0000000..110f096 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/DigitalCalibrationCertificateType.test.ts @@ -0,0 +1,21 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select } from "../../util"; + +const VERSION_XPATH = "string(/dcc:digitalCalibrationCertificate/@schemaVersion)"; + +describe("GP_DCC_Temperature_Typical: DigitalCalibrationCertificateType", () => { + let xml, dcc, dom; + + beforeEach(() => { + ({ xml, dcc, dom } = xmlEnv.recreateEnv()); + }); + + test("should get correct schemaVersion from XML", () => { + const expectedVersion = select(VERSION_XPATH, dom); + expect(dcc.digitalCalibrationCertificate._attr.schemaVersion).toBe(expectedVersion); + }); +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts new file mode 100644 index 0000000..436f8d3 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts @@ -0,0 +1,249 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, InfluenceConditionListType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:influenceConditions"; +const xpath = { + measurementResults: { + measurementResult: { + influenceConditions: { + influenceCondition1: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:name/dcc:content`, + }, + data: { + quantity: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + }, + }, + refType: `string(${base}/dcc:influenceCondition[1]//@refType)`, + }, + influenceCondition2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='en']`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[2]//@refType)`, + }, + influenceCondition3: { + name: { + content: `${base}/dcc:influenceCondition[3]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[3]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:influenceCondition[3]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:influenceCondition[3]/dcc:description/dcc:content[@lang='en']`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[3]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: InfluenceConditionListType", () => { + let dcc: DCCDocument, influenceConditions: InfluenceConditionListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + influenceConditions = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].influenceConditions; + }); + + test("should get correct influence condition 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity si:value from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 1 quantity si:unit from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.refType, dom), + ); + }); + + test("should get correct influence condition 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 1 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.refType, dom), + ); + }); + + test("should get correct influence condition 3 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 quantity 1 si:value from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 3 quantity 1 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 3 quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].data.quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 3 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 3 refType from XML", () => { + expect(influenceConditions.influenceCondition[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts new file mode 100644 index 0000000..856134e --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts @@ -0,0 +1,58 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, MeasuringEquipmentType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:measuringEquipments/dcc:measuringEquipment[1]"; +const xpath = { + measuringEquipments: { + measuringEquipment: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + }, + }, + refType: `string(${base}//@refType)`, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: MeasuringEquipmentType", () => { + let dcc: DCCDocument, measuringEquipment: MeasuringEquipmentType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measuringEquipment = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].measuringEquipments.measuringEquipment[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measuringEquipments.measuringEquipment.name.content, dom); + expect(toTextArr(measuringEquipment.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct measuring equipment 1 identification issuer from XML", () => { + expect(measuringEquipment.identifications.identification[0].issuer._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.issuer, dom), + ); + }); + + test("should get correct measuring equipment 1 identification value from XML", () => { + expect(measuringEquipment.identifications.identification[0].value._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.value, dom), + ); + }); + + test("should get correct measuring equipment 1 refType from XML", () => { + expect(measuringEquipment._attr.refType).toBe(select(xpath.measuringEquipments.measuringEquipment.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Name.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Name.test.ts new file mode 100644 index 0000000..892a1f3 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Name.test.ts @@ -0,0 +1,35 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, MeasurementResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults"; +const xpath = { + measurementResults: { + measurementResult: { + name: { + content: `${base}/dcc:measurementResult[1]/dcc:name/dcc:content`, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: MeasurementResultType", () => { + let dcc: DCCDocument, measurementResult: MeasurementResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measurementResult = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.name.content, dom); + expect(toTextArr(measurementResult.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Results.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Results.test.ts new file mode 100644 index 0000000..9efe9ae --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.Results.test.ts @@ -0,0 +1,302 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, ResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:results"; +const xpath = { + measurementResults: { + measurementResult: { + results: { + result: { + name: { + content: `${base}/dcc:result[1]/dcc:name/dcc:content`, + }, + data: { + list: { + quantity1: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + measurementMetaData: { + metaData: { + declaration: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:declaration/dcc:content`, + }, + data: { + quantity: { + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]//@refType)`, + }, + quantity3: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:name/dcc:content`, + }, + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:unitXMLList)`, + si_expandedUncXMLList: { + si_uncertaintyXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:uncertaintyXMLList)`, + si_coverageFactorXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageFactorXMLList)`, + si_coverageProbabilityXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageProbabilityXMLList)`, + si_distributionXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:distributionXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/@refType)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: ResultType", () => { + let dcc: DCCDocument, result: ResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + result = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].results.result[0]; + }); + + test("should get correct result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.name.content, dom); + expect(toTextArr(result.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:unitXMLList 2: from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 1 meta data declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.declaration.content, dom) + ); + expect(toTextArr(result.data.list[0].quantity[0].measurementMetaData.metaData[0].declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 meta data hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.data.quantity.si_hybrid.si_realListXMLList1 + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 1 meta data hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.data.quantity.si_hybrid.si_realListXMLList1 + .si_unitXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 1 meta data hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.data.quantity.si_hybrid.si_realListXMLList2 + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 1 meta data hybrid si:unitXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 2 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:unitXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 3 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[2].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 3 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 3 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 3 uncertainty list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.uncertaintyXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_uncertaintyXMLList, dom), + ); + }); + + test("should get correct result quantity 3 uncertainty coverage factor list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageFactorXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageFactorXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 uncertainty coverage probability list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageProbabilityXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageProbabilityXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 uncertainty distribution list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.distributionXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_distributionXMLList, + dom, + ), + ); + }); + + test("should get correct result refType from XML", () => { + expect(result._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.refType, dom)); + }); + + test("should get correct result data list refType from XML", () => { + expect(result.data.list[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.list.refType, dom)); + }); + + test("should get correct result quantity 1 refType from XML", () => { + expect(result.data.list[0].quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.refType, dom), + ); + }); + + test("should get correct result quantity 1 meta data refType from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.refType, dom), + ); + }); + + test("should get correct result quantity 2 refType from XML", () => { + expect(result.data.list[0].quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.refType, dom), + ); + }); + + test("should get correct result quantity 3 refType from XML", () => { + expect(result.data.list[0].quantity[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.UsedMethods.test.ts b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.UsedMethods.test.ts new file mode 100644 index 0000000..4738344 --- /dev/null +++ b/tests/DCC/GP_DCC_Temperature_Typical/MeasurementResults.MeasurementResult.UsedMethods.test.ts @@ -0,0 +1,81 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_Typical.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, UsedMethodListType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]"; +const xpath = { + measurementResults: { + measurementResult: { + usedMethods: { + usedMethod1: { + name: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:description/dcc:content[@lang='en']`, + }, + norm: `string(${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:norm[1])`, + refType: `string(${base}/dcc:usedMethods/dcc:usedMethod[1]//@refType)`, + }, + usedMethod2: { + name: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[2]/dcc:name/dcc:content`, + }, + norm: `string(${base}/dcc:usedMethods/dcc:usedMethod[2]/dcc:norm[1])`, + refType: `string(${base}/dcc:usedMethods/dcc:usedMethod[2]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_DCC_Temperature_Typical: UsedMethodListType", () => { + let dcc: DCCDocument, usedMethods: UsedMethodListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + usedMethods = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].usedMethods; + }); + + test("should get correct used method 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.name.content, dom); + expect(toTextArr(usedMethods.usedMethod[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 1 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.description.content, dom); + expect(toTextArr(usedMethods.usedMethod[0].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 1 norm from XML", () => { + expect(usedMethods.usedMethod[0].norm[0]._text).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.norm, dom)); + }); + + test("should get correct used method 1 refType from XML", () => { + expect(usedMethods.usedMethod[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.refType, dom)); + }); + + test("should get correct used method 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod2.name.content, dom); + expect(toTextArr(usedMethods.usedMethod[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 2 norm from XML", () => { + expect(usedMethods.usedMethod[1].norm[0]._text).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod2.norm, dom)); + }); + + test("should get correct used method 2 refType from XML", () => { + expect(usedMethods.usedMethod[1]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod2.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CalibrationLaboratory.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CalibrationLaboratory.test.ts new file mode 100644 index 0000000..9372426 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CalibrationLaboratory.test.ts @@ -0,0 +1,84 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { CalibrationLaboratoryType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:calibrationLaboratory/dcc:contact"; +const xpath = { + name: `string(${base}/dcc:name/dcc:content)`, + eMail: `string(${base}/dcc:eMail)`, + phone: `string(${base}/dcc:phone)`, + fax: `string(${base}/dcc:fax)`, + location: { + city: `${base}/dcc:location/dcc:city`, + countryCode: `${base}/dcc:location/dcc:countryCode`, + postCode: `${base}/dcc:location/dcc:postCode`, + street: `${base}/dcc:location/dcc:street`, + streetNo: `${base}/dcc:location/dcc:streetNo`, + further: `${base}/dcc:location/dcc:further/dcc:content`, + }, +}; + +describe("GP_Temperature_Complete_DCC: CalibrationLaboratoryType", () => { + let dcc: DCCDocument, calibrationLaboratory: CalibrationLaboratoryType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + calibrationLaboratory = dcc.digitalCalibrationCertificate.administrativeData.calibrationLaboratory; + }); + + test("should get correct name from XML", () => { + expect(calibrationLaboratory.contact.name.content[0]._text).toBe(select(xpath.name, dom)); + }); + + test("should get correct eMail from XML", () => { + expect(calibrationLaboratory.contact.eMail._text).toBe(select(xpath.eMail, dom)); + }); + + test("should get correct phone from XML", () => { + expect(calibrationLaboratory.contact.phone._text).toBe(select(xpath.phone, dom)); + }); + + test("should get correct fax from XML", () => { + expect(calibrationLaboratory.contact.fax._text).toBe(select(xpath.fax, dom)); + }); + + test("should get correct city from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.city, dom); + expect(toTextArr(calibrationLaboratory.contact.location.city)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct countryCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.countryCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.countryCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct postCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.postCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.postCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct street from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.street, dom); + expect(toTextArr(calibrationLaboratory.contact.location.street)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct streetNo from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.streetNo, dom); + expect(toTextArr(calibrationLaboratory.contact.location.streetNo)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct further element from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.further, dom); + expect(toTextArr(calibrationLaboratory.contact.location.further[0].content)).toEqual(toTextContentArr(expected)); + }); +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CoreDataType.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CoreDataType.test.ts new file mode 100644 index 0000000..9682017 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.CoreDataType.test.ts @@ -0,0 +1,128 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import * as fc from "fast-check"; +import { indexOf, select, toTextArr, toTextContentArr } from "../../util"; +import { CoreDataType, DCCDocument, DCCXMLElement } from "../../../src"; +import { string_ISO639_1 } from "../../Arbitraries"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:coreData"; +const xpath = { + coreData: { + countryCodeISO3166_1: `string(${base}/dcc:countryCodeISO3166_1)`, + usedLangCodeISO639_1: `${base}/dcc:usedLangCodeISO639_1`, + mandatoryLangCodeISO639_1: `${base}/dcc:mandatoryLangCodeISO639_1`, + uniqueIdentifier: `string(${base}/dcc:uniqueIdentifier)`, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + }, + receiptData: `string(${base}/dcc:receiptDate)`, + beginPerformanceDate: `string(${base}/dcc:beginPerformanceDate)`, + endPerformanceDate: `string(${base}/dcc:endPerformanceDate)`, + performanceLocation: `string(${base}/dcc:performanceLocation)`, + issueDate: `string(${base}/dcc:issueDate)`, + }, +}; + +describe("GP_Temperature_Complete_DCC: CoreDataType", () => { + let dcc: DCCDocument, coreData: CoreDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + coreData = dcc.digitalCalibrationCertificate.administrativeData.coreData; + }); + + test("should get correct countryCodeISO3166_1 from XML", () => { + expect(coreData.countryCodeISO3166_1._text).toBe(select(xpath.coreData.countryCodeISO3166_1, dom)); + }); + + test("should get correct usedLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom); + expect(toTextArr(coreData.usedLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct mandatoryLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.mandatoryLangCodeISO639_1, dom); + expect(toTextArr(coreData.mandatoryLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct unique identifier from XML", () => { + expect(coreData.uniqueIdentifier._text).toBe(select(xpath.coreData.uniqueIdentifier, dom)); + }); + + test("should get correct identification issuer from XML", () => { + expect(coreData.identifications.identification[0].issuer._text).toBe(select(xpath.coreData.identifications.identification.issuer, dom)); + }); + + test("should get correct identification value from XML", () => { + expect(coreData.identifications.identification[0].value._text).toBe(select(xpath.coreData.identifications.identification.value, dom)); + }); + + test("should get correct identification name content from XML", () => { + const expected = <Element[]>select(xpath.coreData.identifications.identification.name.content, dom); + expect(toTextArr(coreData.identifications.identification[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct receipt date from XML", () => { + expect(coreData.receiptDate._text).toBe(select(xpath.coreData.receiptData, dom)); + }); + + test("should get correct begin performance date from XML", () => { + expect(coreData.beginPerformanceDate._text).toBe(select(xpath.coreData.beginPerformanceDate, dom)); + }); + + test("should get correct end performance date from XML", () => { + expect(coreData.endPerformanceDate._text).toBe(select(xpath.coreData.endPerformanceDate, dom)); + }); + + test("should get correct performance location from XML", () => { + expect(coreData.performanceLocation._text).toBe(select(xpath.coreData.performanceLocation, dom)); + }); + + test("should get correct issue date from XML", () => { + expect(coreData.issueDate._text).toBe(select(xpath.coreData.issueDate, dom)); + }); + + /* test for setters */ + test("should set usedLangCodeISO639_1 correctly", () => { + fc.assert( + fc.property(string_ISO639_1(), (str) => { + // add new element to array + coreData.usedLangCodeISO639_1.push(new DCCXMLElement({ _text: str })); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).toContain(str); + expect(toTextContentArr(actual)).toContain(str); + }), + ); + }); + + test("should delete usedLangCodeISO639_1 correctly", () => { + const selection = toTextContentArr(<Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom)); + fc.assert( + fc.property(fc.constantFrom(...selection), (str) => { + // get index and remove element from array + const index = indexOf(coreData.usedLangCodeISO639_1, str); + coreData.usedLangCodeISO639_1.splice(index, 1); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).not.toContain(str); + expect(toTextContentArr(actual)).not.toContain(str); + }), + ); + }); +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Customer.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Customer.test.ts new file mode 100644 index 0000000..a11d2d1 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Customer.test.ts @@ -0,0 +1,70 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ContactType, DCCDocument, LocationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:customer"; +const xpath = { + customer: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:eMail)`, + location: { + city: `${base}/dcc:location/dcc:city[1]`, + countryCode: `${base}/dcc:location/dcc:countryCode[1]`, + postCode: `${base}/dcc:location/dcc:postCode[1]`, + further: `${base}/dcc:location/dcc:further[1]/dcc:content`, + }, + descriptionData: `${base}/dcc:descriptionData`, + _id: `${base}/@id`, + }, +}; + +describe("GP_Temperature_Complete_DCC: ContactType", () => { + let dcc: DCCDocument, customer: ContactType, location: LocationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + customer = dcc.digitalCalibrationCertificate.administrativeData.customer; + location = customer.location; /* TODO: check iff this variable is used anywhere */ + }); + + test("should get correct customer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.customer.name.content, dom); + expect(toTextArr(customer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct customer email address from XML", () => { + expect(customer.eMail._text).toBe(select(xpath.customer.email, dom)); + }); + + test("should get correct customer location city from XML", () => { + const expected = <Element[]>select(xpath.customer.location.city, dom); + expect(customer.location.city[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location county code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.countryCode, dom); + expect(customer.location.countryCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location post code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.postCode, dom); + expect(customer.location.postCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location further from XML", () => { + const expected = <Element[]>select(xpath.customer.location.further, dom); + + for (let i = 0; i < expected.length; i++) { + expect(customer.location.further[0].content[i]._text).toBe(expected[i].textContent); + } + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Items.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Items.test.ts new file mode 100644 index 0000000..062bf5b --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Items.test.ts @@ -0,0 +1,144 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ItemType, DCCDocument, IdentificationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:items"; +const xpath = { + items: { + item: { + name: { + content: `${base}/dcc:item[1]/dcc:name/dcc:content`, + }, + manufacturer: { + name: { + content: `${base}/dcc:item[1]/dcc:manufacturer/dcc:name/dcc:content`, + }, + }, + model: `string(${base}/dcc:item[1]/dcc:model)`, + identifications: { + identification1: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + identification2: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[2]/dcc:name/dcc:content`, + }, + }, + identification3: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[3]/dcc:name/dcc:content`, + }, + }, + }, + itemQuantities: { + itemQuantity: { + name: { + content: `${base}/dcc:item[1]/dcc:itemQuantities/dcc:itemQuantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:item[1]/dcc:itemQuantities/dcc:itemQuantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:item[1]/dcc:itemQuantities/dcc:itemQuantity[1]/si:real/si:unit)`, + }, + }, + }, + refType: `string(${base}/dcc:item[1]//@refType)`, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: ItemType", () => { + let dcc: DCCDocument, item: ItemType, identification1, identification2, identification3: IdentificationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + item = dcc.digitalCalibrationCertificate.administrativeData.items.item[0]; + identification1 = item.identifications.identification[0]; + identification2 = item.identifications.identification[1]; + identification3 = item.identifications.identification[2]; + }); + + test("should get correct item name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.name.content, dom); + expect(toTextArr(item.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item manufacturer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.manufacturer.name.content, dom); + expect(toTextArr(item.manufacturer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item model from XML", () => { + expect(item.model._text).toBe(select(xpath.items.item.model, dom)); + }); + + test("should get correct identification 1 issuer from XML", () => { + expect(identification1.issuer._text).toBe(select(xpath.items.item.identifications.identification1.issuer, dom)); + }); + + test("should get correct identification 1 value from XML", () => { + expect(identification1.value._text).toBe(select(xpath.items.item.identifications.identification1.value, dom)); + }); + + test("should get correct identification 1 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification1.name.content, dom); + expect(toTextArr(identification1.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 2 issuer from XML", () => { + expect(identification2.issuer._text).toBe(select(xpath.items.item.identifications.identification2.issuer, dom)); + }); + + test("should get correct identification 2 value from XML", () => { + expect(identification2.value._text).toBe(select(xpath.items.item.identifications.identification2.value, dom)); + }); + + test("should get correct identification 2 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification2.name.content, dom); + expect(toTextArr(identification2.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification 3 issuer from XML", () => { + expect(identification3.issuer._text).toBe(select(xpath.items.item.identifications.identification3.issuer, dom)); + }); + + test("should get correct identification 3 value from XML", () => { + expect(identification3.value._text).toBe(select(xpath.items.item.identifications.identification3.value, dom)); + }); + + test("should get correct identification 3 name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.identifications.identification3.name.content, dom); + expect(toTextArr(identification3.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item quantity name content from XML", () => { + const expected = <Element[]>select(xpath.items.item.itemQuantities.itemQuantity.name.content, dom); + expect(toTextArr(item.itemQuantities.itemQuantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item quantity real value from XML", () => { + expect(item.itemQuantities.itemQuantity[0].real.value._text).toBe(select(xpath.items.item.itemQuantities.itemQuantity.si_real.si_value, dom)); + }); + + test("should get correct item quantity real unit from XML", () => { + expect(item.itemQuantities.itemQuantity[0].real.unit._text).toBe(select(xpath.items.item.itemQuantities.itemQuantity.si_real.si_unit, dom)); + }); + + test("should get correct item refType from XML", () => { + expect(item._attr.refType).toBe(select(xpath.items.item.refType, dom)); + }); + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RefTypeDefinitons.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RefTypeDefinitons.test.ts new file mode 100644 index 0000000..0400f0b --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RefTypeDefinitons.test.ts @@ -0,0 +1,72 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, RefTypeDefinitionType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:refTypeDefinitions/dcc:refTypeDefinition[1]"; +const xpath = { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + description: { + name: { + content: `${base}/dcc:description/dcc:name/dcc:content`, + }, + content: `${base}/dcc:description/dcc:content`, + }, + namespace: `string(${base}/dcc:namespace)`, + link: `string(${base}/dcc:link)`, + release: `string(${base}/dcc:release)`, + value: `string(${base}/dcc:value)`, + procedure: `string(${base}/dcc:procedure)`, +}; + +describe("GP_Temperature_Complete_DCC: RefTypeDefinitionType", () => { + let dcc: DCCDocument, refTypeDefinition: RefTypeDefinitionType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + refTypeDefinition = dcc.digitalCalibrationCertificate.administrativeData.refTypeDefinitions.refTypeDefinition[0]; + }); + + test("should get correct name from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.name.content, dom); + expect(toTextArr(refTypeDefinition.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct description name from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.description.name.content, dom); + expect(toTextArr(refTypeDefinition.description.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.description.content, dom); + expect(toTextArr(refTypeDefinition.description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct namespace from XML", () => { + expect(refTypeDefinition.namespace._text).toBe(select(xpath.namespace, dom)); + }); + + test("should get correct link from XML", () => { + expect(refTypeDefinition.link._text).toBe(select(xpath.link, dom)); + }); + + test("should get correct release from XML", () => { + expect(refTypeDefinition.release._text).toBe(select(xpath.release, dom)); + }); + + test("should get correct value from XML", () => { + expect(refTypeDefinition.value._text).toBe(select(xpath.value, dom)); + }); + + test("should get correct procedure from XML", () => { + expect(refTypeDefinition.procedure._text).toBe(select(xpath.procedure, dom)); + }); +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RespPersons.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RespPersons.test.ts new file mode 100644 index 0000000..768e9e2 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.RespPersons.test.ts @@ -0,0 +1,56 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { RespPersonType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:respPersons"; +const xpath = { + respPersons: { + respPerson1: { + person: { + name: { + content: `${base}/dcc:respPerson[1]/dcc:person/dcc:name/dcc:content`, + }, + }, + mainSigner: `string(${base}/dcc:respPerson[1]/dcc:mainSigner)`, + }, + respPerson2: { + person: { + name: { + content: `${base}/dcc:respPerson[2]/dcc:person/dcc:name/dcc:content`, + }, + }, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: RespPersonType", () => { + let dcc: DCCDocument, respPerson1, respPerson2: RespPersonType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + respPerson1 = dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[0]; + respPerson2 = dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[1]; + }); + + test("should get correct responsible person 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.respPersons.respPerson1.person.name.content, dom); + expect(toTextArr(respPerson1.person.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct responsible person 1 main signer flag from XML", () => { + expect(respPerson1.mainSigner._text).toBe(select(xpath.respPersons.respPerson1.mainSigner, dom)); + }); + + test("should get correct responsible person 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.respPersons.respPerson2.person.name.content, dom); + expect(toTextArr(respPerson2.person.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.SoftwareListType.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.SoftwareListType.test.ts new file mode 100644 index 0000000..39aadae --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.SoftwareListType.test.ts @@ -0,0 +1,60 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { SoftwareListType, DCCDocument, SoftwareType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:dccSoftware/dcc:software"; +const xpath = { + software: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + release: `string(${base}/dcc:release)`, + type: `string(${base}/dcc:type)`, + description: { + name: { + content: `${base}/dcc:description/dcc:name/dcc:content`, + }, + content: `${base}/dcc:description/dcc:content`, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: DccSoftwareType", () => { + let dcc: DCCDocument, dccSoftware: SoftwareListType, software: SoftwareType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + dccSoftware = dcc.digitalCalibrationCertificate.administrativeData.dccSoftware; + software = dccSoftware.software[0]; + }); + + test("should get correct software name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.software.name.content, dom); + expect(toTextArr(software.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct software release version of software from XML", () => { + expect(software.release._text).toBe(select(xpath.software.release, dom)); + }); + + test("should get correct software type of software from XML", () => { + expect(software.type._text).toBe(select(xpath.software.type, dom)); + }); + + test("should get correct description name content of software from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.software.description.name.content, dom); + expect(toTextArr(software.description.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct description content of software from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.software.description.content, dom); + expect(toTextArr(software.description.content)).toEqual(toTextContentArr(expected)); + }); +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Statements.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Statements.test.ts new file mode 100644 index 0000000..10288f8 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/AdministrativeData.Statements.test.ts @@ -0,0 +1,127 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { StatementMetaDataType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:statements"; +const xpath = { + statements: { + statement1: { + declaration: { + content: `${base}/dcc:statement[1]/dcc:declaration/dcc:content`, + }, + respAuthority: { + name: { + content: `${base}/dcc:statement[1]/dcc:respAuthority/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:eMail)`, + location: { + city: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:location/dcc:city)`, + countryCode: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:location/dcc:countryCode)`, + postCode: `string(${base}/dcc:statement[1]/dcc:respAuthority/dcc:location/dcc:postCode)`, + }, + }, + conformity: `string(${base}/dcc:statement[1]/dcc:conformity)`, + refType: `string(${base}/dcc:statement[1]/@refType)`, + }, + statement2: { + declaration: { + content: `${base}/dcc:statement[2]/dcc:declaration/dcc:content`, + }, + date: `string(${base}/dcc:statement[2]/dcc:date)`, + respAuthority: { + name: { + content: `${base}/dcc:statement[2]/dcc:respAuthority/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:eMail)`, + location: { + city: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:location/dcc:city)`, + countryCode: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:location/dcc:countryCode)`, + postCode: `string(${base}/dcc:statement[2]/dcc:respAuthority/dcc:location/dcc:postCode)`, + }, + }, + refType: `string(${base}/dcc:statement[2]/@refType)`, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: StatementMetaDataType", () => { + let dcc: DCCDocument, statement1, statement2: StatementMetaDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + statement1 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[0]; + statement2 = dcc.digitalCalibrationCertificate.administrativeData.statements.statement[1]; + }); + + test("should get correct statement 1 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement1.declaration.content, dom); + expect(toTextArr(statement1.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + /* responsible authority 1 */ + test("should get correct statement 1 responsible authority name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement1.respAuthority.name.content, dom); + expect(toTextArr(statement1.respAuthority.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 1 responsible authority email from XML", () => { + expect(statement1.respAuthority.eMail._text).toBe(select(xpath.statements.statement1.respAuthority.email, dom)); + }); + + test("should get correct statement 1 responsible authority location city from XML", () => { + expect(statement1.respAuthority.location.city[0]._text).toBe(select(xpath.statements.statement1.respAuthority.location.city, dom)); + }); + test("should get correct statement 1 responsible authority location country code from XML", () => { + expect(statement1.respAuthority.location.countryCode[0]._text).toBe(select(xpath.statements.statement1.respAuthority.location.countryCode, dom)); + }); + test("should get correct statement 1 responsible authority location post code from XML", () => { + expect(statement1.respAuthority.location.postCode[0]._text).toBe(select(xpath.statements.statement1.respAuthority.location.postCode, dom)); + }); + + test("should get correct statement 1 conformity from XML", () => { + expect(statement1.conformity._text).toBe(select(xpath.statements.statement1.conformity, dom)); + }); + + test("should get correct statement 2 declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement2.declaration.content, dom); + expect(toTextArr(statement2.declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 2 refType from XML", () => { + expect(statement2.date._text).toBe(select(xpath.statements.statement2.date, dom)); + }); + + /* responsible authority 2 */ + test("should get correct statement 2 responsible authority name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.statements.statement2.respAuthority.name.content, dom); + expect(toTextArr(statement2.respAuthority.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement 2 responsible authority email from XML", () => { + expect(statement2.respAuthority.eMail._text).toBe(select(xpath.statements.statement2.respAuthority.email, dom)); + }); + + test("should get correct statement 2 responsible authority location city from XML", () => { + expect(statement2.respAuthority.location.city[0]._text).toBe(select(xpath.statements.statement2.respAuthority.location.city, dom)); + }); + test("should get correct statement 2 responsible authority location country code from XML", () => { + expect(statement2.respAuthority.location.countryCode[0]._text).toBe(select(xpath.statements.statement2.respAuthority.location.countryCode, dom)); + }); + test("should get correct statement 2 responsible authority location post code from XML", () => { + expect(statement2.respAuthority.location.postCode[0]._text).toBe(select(xpath.statements.statement2.respAuthority.location.postCode, dom)); + }); + + test("should get correct statement 2 refType from XML", () => { + expect(statement2._attr.refType).toBe(select(xpath.statements.statement2.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/DigitalCalibrationCertificateType.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/DigitalCalibrationCertificateType.test.ts new file mode 100644 index 0000000..ae1ad14 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/DigitalCalibrationCertificateType.test.ts @@ -0,0 +1,21 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select } from "../../util"; + +const VERSION_XPATH = "string(/dcc:digitalCalibrationCertificate/@schemaVersion)"; + +describe("GP_Temperature_Complete_DCC: DigitalCalibrationCertificateType", () => { + let xml, dcc, dom; + + beforeEach(() => { + ({ xml, dcc, dom } = xmlEnv.recreateEnv()); + }); + + test("should get correct schemaVersion from XML", () => { + const expectedVersion = select(VERSION_XPATH, dom); + expect(dcc.digitalCalibrationCertificate._attr.schemaVersion).toBe(expectedVersion); + }); +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts new file mode 100644 index 0000000..6d8fbac --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts @@ -0,0 +1,218 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, InfluenceConditionListType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:influenceConditions"; +const xpath = { + measurementResults: { + measurementResult: { + influenceConditions: { + influenceCondition1: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[1]/dcc:description/dcc:content`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[1]//@refType)`, + }, + influenceCondition2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='en']`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[2]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: InfluenceConditionListType", () => { + let dcc: DCCDocument, influenceConditions: InfluenceConditionListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + influenceConditions = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].influenceConditions; + }); + + test("should get correct influence condition 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity si:value from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 1 quantity si:unit from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 1 quantity 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity1.refType, dom), + ); + }); + + test("should get correct influence condition 1 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 1 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 1 quantity 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity2.refType, dom), + ); + }); + + test("should get correct influence condition 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.refType, dom), + ); + }); + + test("should get correct influence condition 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 1 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 quantity 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.refType, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.refType, dom), + ); + }); + + test("should get correct influence condition 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts new file mode 100644 index 0000000..86b8a4d --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts @@ -0,0 +1,58 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, MeasuringEquipmentType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:measuringEquipments/dcc:measuringEquipment[1]"; +const xpath = { + measuringEquipments: { + measuringEquipment: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + }, + }, + refType: `string(${base}//@refType)`, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: MeasuringEquipmentType", () => { + let dcc: DCCDocument, measuringEquipment: MeasuringEquipmentType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measuringEquipment = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].measuringEquipments.measuringEquipment[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measuringEquipments.measuringEquipment.name.content, dom); + expect(toTextArr(measuringEquipment.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct measuring equipment 1 identification issuer from XML", () => { + expect(measuringEquipment.identifications.identification[0].issuer._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.issuer, dom), + ); + }); + + test("should get correct measuring equipment 1 identification value from XML", () => { + expect(measuringEquipment.identifications.identification[0].value._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.value, dom), + ); + }); + + test("should get correct measuring equipment 1 refType from XML", () => { + expect(measuringEquipment._attr.refType).toBe(select(xpath.measuringEquipments.measuringEquipment.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Name.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Name.test.ts new file mode 100644 index 0000000..f5f95f7 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Name.test.ts @@ -0,0 +1,35 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, MeasurementResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults"; +const xpath = { + measurementResults: { + measurementResult: { + name: { + content: `${base}/dcc:measurementResult[1]/dcc:name/dcc:content`, + }, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: MeasurementResultType", () => { + let dcc: DCCDocument, measurementResult: MeasurementResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measurementResult = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.name.content, dom); + expect(toTextArr(measurementResult.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Results.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Results.test.ts new file mode 100644 index 0000000..7b01f47 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.Results.test.ts @@ -0,0 +1,737 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, ResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:results"; +const xpath = { + measurementResults: { + measurementResult: { + results: { + result: { + name: { + content: `${base}/dcc:result[1]/dcc:name/dcc:content`, + }, + data: { + list: { + quantity1: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]//@refType)`, + }, + quantity3: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:name/dcc:content`, + }, + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:unitXMLList)`, + si_expandedUncXMLList: { + si_uncertaintyXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:uncertaintyXMLList)`, + si_coverageFactorXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageFactorXMLList)`, + si_coverageProbabilityXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageProbabilityXMLList)`, + si_distributionXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:distributionXMLList)`, + }, + }, + measurementMetaData: { + metaData: { + declaration: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData[1]/dcc:declaration/dcc:name/dcc:content`, + }, + }, + conformityXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:conformityXMLList)`, + data: { + quantity1: { + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:realListXMLList/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:realListXMLList/si:unitXMLList)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[2]/si:realListXMLList/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[2]/si:realListXMLList/si:unitXMLList)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:measurementMetaData/dcc:metaData//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/@refType)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list//@refType)`, + }, + quantity1: { + noQuantity: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:quantity[1]/dcc:noQuantity/dcc:name/dcc:content`, + }, + content: `${base}/dcc:result[1]/dcc:data/dcc:quantity[1]/dcc:noQuantity/dcc:content`, + file: { + fileName: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[1]/dcc:noQuantity/dcc:file[1]/dcc:fileName)`, + mimeType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[1]/dcc:noQuantity/dcc:file[1]/dcc:mimeType)`, + dataBase64: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[1]/dcc:noQuantity/dcc:file[1]/dcc:dataBase64)`, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[1]/dcc:noQuantity/dcc:file[1]//@refType)`, + }, + formula: { + latex: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[1]/dcc:noQuantity/dcc:formula[1]/dcc:latex)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + charsXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[2]/dcc:charsXMLList)`, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[2]//@refType)`, + }, + quantity3: { + si_constant: { + si_label: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[3]/si:constant/si:label)`, + si_value: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[3]/si:constant/si:value)`, + si_unit: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[3]/si:constant/si:unit)`, + si_dateTime: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[3]/si:constant/si:dateTime)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[3]//@refType)`, + }, + quantity4: { + si_real: { + si_label: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[4]/si:real/si:label)`, + si_value: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[4]/si:real/si:value)`, + si_unit: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[4]/si:real/si:unit)`, + si_dateTime: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[4]/si:real/si:dateTime)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[4]//@refType)`, + }, + quantity5: { + si_realListXMLList: { + si_labelXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[5]/si:realListXMLList/si:labelXMLList)`, + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[5]/si:realListXMLList/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[5]/si:realListXMLList/si:unitXMLList)`, + si_dateTimeXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[5]/si:realListXMLList/si:dateTimeXMLList)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[5]//@refType)`, + }, + quantity6: { + si_hybrid: { + si_constant1: { + si_label: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[1]/si:label)`, + si_value: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[1]/si:value)`, + si_unit: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[1]/si:unit)`, + si_dateTime: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[1]/si:dateTime)`, + }, + si_constant2: { + si_label: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[2]/si:label)`, + si_value: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[2]/si:value)`, + si_unit: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[2]/si:unit)`, + si_dateTime: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]/si:hybrid/si:constant[2]/si:dateTime)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[6]//@refType)`, + }, + quantity7: { + si_hybrid: { + si_real1: { + si_label: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[1]/si:label)`, + si_value: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[1]/si:value)`, + si_unit: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[1]/si:unit)`, + si_dateTime: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[1]/si:dateTime)`, + }, + si_real2: { + si_label: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[2]/si:label)`, + si_value: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[2]/si:value)`, + si_unit: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[2]/si:unit)`, + si_dateTime: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]/si:hybrid/si:real[2]/si:dateTime)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[7]//@refType)`, + }, + quantity8: { + si_hybrid: { + si_realListXMLList1: { + si_labelXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[1]/si:labelXMLList)`, + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + si_dateTimeXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[1]/si:dateTimeXMLList)`, + }, + si_realListXMLList2: { + si_labelXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[2]/si:labelXMLList)`, + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + si_dateTimeXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]/si:hybrid/si:realListXMLList[2]/si:dateTimeXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:quantity[8]//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: ResultType", () => { + let dcc: DCCDocument, result: ResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + result = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].results.result[0]; + }); + + test("should get correct result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.name.content, dom); + expect(toTextArr(result.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result list quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result list quantity 1 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result list quantity 1 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result list quantity 1 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result list quantity 1 hybrid si:unitXMLList 2: from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result list quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result list quantity 2 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result list quantity 2 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result list quantity 2 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result list quantity 2 hybrid si:unitXMLList 2: from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result list quantity 3 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[2].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result list quantity 3 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_valueXMLList, dom), + ); + }); + + test("should get correct result list quantity 3 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_unitXMLList, dom), + ); + }); + + test("should get correct result list quantity 3 uncertainty list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.uncertaintyXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_uncertaintyXMLList, dom), + ); + }); + + test("should get correct result list quantity 3 uncertainty coverage factor list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageFactorXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageFactorXMLList, + dom, + ), + ); + }); + + test("should get correct result list quantity 3 uncertainty coverage probability list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageProbabilityXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageProbabilityXMLList, + dom, + ), + ); + }); + + test("should get correct result list quantity 3 uncertainty distribution list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.distributionXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_distributionXMLList, + dom, + ), + ); + }); + + test("should get correct result list quantity 3 meta data declaration name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.declaration.name.content, dom) + ); + expect(toTextArr(result.data.list[0].quantity[2].measurementMetaData.metaData[0].declaration.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result list quantity 3 meta data conformityXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].conformityXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.conformityXMLList, dom), + ); + }); + + test("should get correct result list quantity 3 meta data quantity 1 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[0].realListXMLList.valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity1.si_realListXMLList + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result list quantity 3 meta data quantity 1 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[0].realListXMLList.unitXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity1.si_realListXMLList + .si_unitXMLList, + dom, + ), + ); + }); + + test("should get correct result list quantity 3 meta data quantity 2 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[1].realListXMLList.valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity2.si_realListXMLList + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result list quantity 3 meta data quantity 2 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[1].realListXMLList.valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity2.si_realListXMLList + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result list quantity 3 meta data quantity 2 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0].data.quantity[1].realListXMLList.unitXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.data.quantity2.si_realListXMLList + .si_unitXMLList, + dom, + ), + ); + }); + + test("should get correct result refType from XML", () => { + expect(result._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.refType, dom)); + }); + + test("should get correct result data list refType from XML", () => { + expect(result.data.list[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.list.refType, dom)); + }); + + test("should get correct result list quantity 1 refType from XML", () => { + expect(result.data.list[0].quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.refType, dom), + ); + }); + + test("should get correct result list quantity2 refType from XML", () => { + expect(result.data.list[0].quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.refType, dom), + ); + }); + + test("should get correct result list quantity3 refType from XML", () => { + expect(result.data.list[0].quantity[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.refType, dom), + ); + }); + + test("should get correct result list quantity 3 meta data refType from XML", () => { + expect(result.data.list[0].quantity[2].measurementMetaData.metaData[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.measurementMetaData.metaData.refType, dom), + ); + }); + + test("should get correct result list quantity 2 refType from XML", () => { + expect(result.data.list[0].quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.refType, dom), + ); + }); + + test("should get correct result list quantity 3 refType from XML", () => { + expect(result.data.list[0].quantity[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.refType, dom), + ); + }); + + test("should get correct result no quantity name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.name.content, dom); + expect(toTextArr(result.data.quantity[0].noQuantity.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result no quantity content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.content, dom); + expect(toTextArr(result.data.quantity[0].noQuantity.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result no quantity file fileName from XML", () => { + expect(result.data.quantity[0].noQuantity.file[0].fileName._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.file.fileName, dom), + ); + }); + + test("should get correct result no quantity file mimeType from XML", () => { + expect(result.data.quantity[0].noQuantity.file[0].mimeType._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.file.mimeType, dom), + ); + }); + + test("should get correct result no quantity file dataBase64 from XML", () => { + expect(result.data.quantity[0].noQuantity.file[0].dataBase64._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.file.dataBase64, dom), + ); + }); + + test("should get correct result no quantity file refType from XML", () => { + expect(result.data.quantity[0].noQuantity.file[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.file.refType, dom), + ); + }); + + test("should get correct result no quantity formula latex from XML", () => { + expect(result.data.quantity[0].noQuantity.formula[0].latex._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.formula.latex, dom), + ); + }); + + test("should get correct result no quantity file refType from XML", () => { + expect(result.data.quantity[0].noQuantity.file[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity1.noQuantity.file.refType, dom), + ); + }); + + test("should get correct result charsXMLList value from XML", () => { + expect(result.data.quantity[1].charsXMLList._text).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity2.charsXMLList, dom)); + }); + + test("should get correct result const label from XML", () => { + expect(result.data.quantity[2].constant.label._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity3.si_constant.si_label, dom), + ); + }); + + test("should get correct result const value from XML", () => { + expect(result.data.quantity[2].constant.value._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity3.si_constant.si_value, dom), + ); + }); + + test("should get correct result const unit from XML", () => { + expect(result.data.quantity[2].constant.unit._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity3.si_constant.si_unit, dom), + ); + }); + + test("should get correct result const dateTime from XML", () => { + expect(result.data.quantity[2].constant.dateTime._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity3.si_constant.si_dateTime, dom), + ); + }); + + test("should get correct result real label from XML", () => { + expect(result.data.quantity[3].real.label._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity4.si_real.si_label, dom), + ); + }); + + test("should get correct result real value from XML", () => { + expect(result.data.quantity[3].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity4.si_real.si_value, dom), + ); + }); + + test("should get correct result real unit from XML", () => { + expect(result.data.quantity[3].real.unit._text).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity4.si_real.si_unit, dom)); + }); + + test("should get correct result real dateTime from XML", () => { + expect(result.data.quantity[3].real.dateTime._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity4.si_real.si_dateTime, dom), + ); + }); + + test("should get correct result realListXMLList label list from XML", () => { + expect(result.data.quantity[4].realListXMLList.labelXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity5.si_realListXMLList.si_labelXMLList, dom), + ); + }); + + test("should get correct result realListXMLList value list from XML", () => { + expect(result.data.quantity[4].realListXMLList.valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity5.si_realListXMLList.si_valueXMLList, dom), + ); + }); + + test("should get correct result realListXMLList unit list from XML", () => { + expect(result.data.quantity[4].realListXMLList.unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity5.si_realListXMLList.si_unitXMLList, dom), + ); + }); + + test("should get correct result realListXMLList dateTime list from XML", () => { + expect(result.data.quantity[4].realListXMLList.dateTimeXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity5.si_realListXMLList.si_dateTimeXMLList, dom), + ); + }); + + test("should get correct result hybrid const 1 label from XML", () => { + expect(result.data.quantity[5].hybrid.constant[0].label._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant1.si_label, dom), + ); + }); + + test("should get correct result hybrid const 1 value from XML", () => { + expect(result.data.quantity[5].hybrid.constant[0].value._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant1.si_value, dom), + ); + }); + + test("should get correct result hybrid const 1 unit from XML", () => { + expect(result.data.quantity[5].hybrid.constant[0].unit._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant1.si_unit, dom), + ); + }); + + test("should get correct result hybrid const 1 dateTime from XML", () => { + expect(result.data.quantity[5].hybrid.constant[0].dateTime._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant1.si_dateTime, dom), + ); + }); + + test("should get correct result hybrid const 2 label from XML", () => { + expect(result.data.quantity[5].hybrid.constant[1].label._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant2.si_label, dom), + ); + }); + + test("should get correct result hybrid const 2 value from XML", () => { + expect(result.data.quantity[5].hybrid.constant[1].value._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant2.si_value, dom), + ); + }); + + test("should get correct result hybrid const 2 unit from XML", () => { + expect(result.data.quantity[5].hybrid.constant[1].unit._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant2.si_unit, dom), + ); + }); + + test("should get correct result hybrid const 2 dateTime from XML", () => { + expect(result.data.quantity[5].hybrid.constant[1].dateTime._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity6.si_hybrid.si_constant2.si_dateTime, dom), + ); + }); + + test("should get correct result hybrid real 1 label from XML", () => { + expect(result.data.quantity[6].hybrid.real[0].label._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real1.si_label, dom), + ); + }); + + test("should get correct result hybrid real 1 value from XML", () => { + expect(result.data.quantity[6].hybrid.real[0].value._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real1.si_value, dom), + ); + }); + + test("should get correct result hybrid real 1 unit from XML", () => { + expect(result.data.quantity[6].hybrid.real[0].unit._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real1.si_unit, dom), + ); + }); + + test("should get correct result hybrid real 1 dateTime from XML", () => { + expect(result.data.quantity[6].hybrid.real[0].dateTime._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real1.si_dateTime, dom), + ); + }); + + test("should get correct result hybrid real 2 label from XML", () => { + expect(result.data.quantity[6].hybrid.real[1].label._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real2.si_label, dom), + ); + }); + + test("should get correct result hybrid real 2 value from XML", () => { + expect(result.data.quantity[6].hybrid.real[1].value._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real2.si_value, dom), + ); + }); + + test("should get correct result hybrid real 2 unit from XML", () => { + expect(result.data.quantity[6].hybrid.real[1].unit._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real2.si_unit, dom), + ); + }); + + test("should get correct result hybrid real 2 dateTime from XML", () => { + expect(result.data.quantity[6].hybrid.real[1].dateTime._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity7.si_hybrid.si_real2.si_dateTime, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 1 label from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[0].labelXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList1.si_labelXMLList, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 1 value from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 1 unit from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 1 dateTime from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[0].dateTimeXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList1.si_dateTimeXMLList, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 2 label from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[1].labelXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList2.si_labelXMLList, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 2 value from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 2 unit from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result hybrid realListXMLList 2 dateTime from XML", () => { + expect(result.data.quantity[7].hybrid.realListXMLList[1].dateTimeXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.quantity8.si_hybrid.si_realListXMLList2.si_dateTimeXMLList, dom), + ); + }); + + test("should get correct result no quantity refType from XML", () => { + expect(result.data.quantity[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity1.refType, dom)); + }); + + test("should get correct result charsXMLList refType from XML", () => { + expect(result.data.quantity[1]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity2.refType, dom)); + }); + + test("should get correct result const refType from XML", () => { + expect(result.data.quantity[2]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity3.refType, dom)); + }); + + test("should get correct result real refType from XML", () => { + expect(result.data.quantity[3]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity4.refType, dom)); + }); + + test("should get correct result realListXMLList refType from XML", () => { + expect(result.data.quantity[4]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity5.refType, dom)); + }); + + test("should get correct result hybrid const refType from XML", () => { + expect(result.data.quantity[5]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity6.refType, dom)); + }); + + test("should get correct result hybrid real refType from XML", () => { + expect(result.data.quantity[6]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity7.refType, dom)); + }); + + test("should get correct result hybrid realListXMLList refType from XML", () => { + expect(result.data.quantity[7]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.quantity8.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts new file mode 100644 index 0000000..d16b268 --- /dev/null +++ b/tests/DCC/GP_Temperatur_v3.2.0_DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts @@ -0,0 +1,44 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, UsedMethodListType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]"; +const xpath = { + measurementResults: { + measurementResult: { + usedMethods: { + usedMethod1: { + name: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:name/dcc:content`, + }, + refType: `string(${base}/dcc:usedMethods/dcc:usedMethod[1]//@refType)`, + }, + }, + }, + }, +}; + +describe("GP_Temperature_Complete_DCC: UsedMethodListType", () => { + let dcc: DCCDocument, usedMethods: UsedMethodListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + usedMethods = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].usedMethods; + }); + + test("should get correct used method 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.name.content, dom); + expect(toTextArr(usedMethods.usedMethod[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 1 refType from XML", () => { + expect(usedMethods.usedMethod[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts b/tests/DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts new file mode 100644 index 0000000..5f4974e --- /dev/null +++ b/tests/DCC/MeasurementResults.MeasurementResult.InfluenceConditions.test.ts @@ -0,0 +1,249 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { DCCDocument, InfluenceConditionListType } from "../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:influenceConditions"; +const xpath = { + measurementResults: { + measurementResult: { + influenceConditions: { + influenceCondition1: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:name/dcc:content`, + }, + data: { + quantity: { + name: { + content: `${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[1]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + }, + }, + refType: `string(${base}/dcc:influenceCondition[1]//@refType)`, + }, + influenceCondition2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:influenceCondition[2]/dcc:description/dcc:content[@lang='en']`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[2]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[2]//@refType)`, + }, + influenceCondition3: { + name: { + content: `${base}/dcc:influenceCondition[3]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:influenceCondition[3]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:influenceCondition[3]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:influenceCondition[3]/dcc:description/dcc:content[@lang='en']`, + }, + data: { + quantity1: { + name: { + content: `${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_real: { + si_value: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]/si:real/si:value)`, + si_unit: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]/si:real/si:unit)`, + }, + refType: `string(${base}/dcc:influenceCondition[3]/dcc:data/dcc:quantity[2]//@refType)`, + }, + }, + refType: `string(${base}/dcc:influenceCondition[3]//@refType)`, + }, + }, + }, + }, +}; + +describe("InfluenceConditionListType", () => { + let dcc: DCCDocument, influenceConditions: InfluenceConditionListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + influenceConditions = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].influenceConditions; + }); + + test("should get correct influence condition 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[0].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 1 quantity si:value from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 1 quantity si:unit from XML", () => { + expect(influenceConditions.influenceCondition[0].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.data.quantity.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 1 refType from XML", () => { + expect(influenceConditions.influenceCondition[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition1.refType, dom), + ); + }); + + test("should get correct influence condition 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 1 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 1 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[1].data.quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 2 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 2 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[1].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 2 refType from XML", () => { + expect(influenceConditions.influenceCondition[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition2.refType, dom), + ); + }); + + test("should get correct influence condition 3 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.description.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity1.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].data.quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 quantity 1 si:value from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[0].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity1.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 3 quantity 1 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[0].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity1.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 3 quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity2.name.content, dom); + expect(toTextArr(influenceConditions.influenceCondition[2].data.quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct influence condition 3 quantity 2 si:value from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[1].real.value._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity2.si_real.si_value, dom), + ); + }); + + test("should get correct influence condition 3 quantity 2 si:unit from XML", () => { + expect(influenceConditions.influenceCondition[2].data.quantity[1].real.unit._text).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.data.quantity2.si_real.si_unit, dom), + ); + }); + + test("should get correct influence condition 3 refType from XML", () => { + expect(influenceConditions.influenceCondition[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.influenceConditions.influenceCondition3.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts b/tests/DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts new file mode 100644 index 0000000..8107d84 --- /dev/null +++ b/tests/DCC/MeasurementResults.MeasurementResult.MeasuringEquipments.test.ts @@ -0,0 +1,58 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { DCCDocument, MeasuringEquipmentType } from "../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:measuringEquipments/dcc:measuringEquipment[1]"; +const xpath = { + measuringEquipments: { + measuringEquipment: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + }, + }, + refType: `string(${base}//@refType)`, + }, + }, +}; + +describe("MeasuringEquipmentType", () => { + let dcc: DCCDocument, measuringEquipment: MeasuringEquipmentType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measuringEquipment = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].measuringEquipments.measuringEquipment[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measuringEquipments.measuringEquipment.name.content, dom); + expect(toTextArr(measuringEquipment.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct measuring equipment 1 identification issuer from XML", () => { + expect(measuringEquipment.identifications.identification[0].issuer._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.issuer, dom), + ); + }); + + test("should get correct measuring equipment 1 identification value from XML", () => { + expect(measuringEquipment.identifications.identification[0].value._text).toBe( + select(xpath.measuringEquipments.measuringEquipment.identifications.identification.value, dom), + ); + }); + + test("should get correct measuring equipment 1 refType from XML", () => { + expect(measuringEquipment._attr.refType).toBe(select(xpath.measuringEquipments.measuringEquipment.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/MeasurementResults.MeasurementResult.Name.test.ts b/tests/DCC/MeasurementResults.MeasurementResult.Name.test.ts new file mode 100644 index 0000000..1828f27 --- /dev/null +++ b/tests/DCC/MeasurementResults.MeasurementResult.Name.test.ts @@ -0,0 +1,35 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { DCCDocument, MeasurementResultType } from "../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults"; +const xpath = { + measurementResults: { + measurementResult: { + name: { + content: `${base}/dcc:measurementResult[1]/dcc:name/dcc:content`, + }, + }, + }, +}; + +describe("MeasurementResultType", () => { + let dcc: DCCDocument, measurementResult: MeasurementResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measurementResult = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.name.content, dom); + expect(toTextArr(measurementResult.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/MeasurementResults.MeasurementResult.Results.test.ts b/tests/DCC/MeasurementResults.MeasurementResult.Results.test.ts new file mode 100644 index 0000000..64536b7 --- /dev/null +++ b/tests/DCC/MeasurementResults.MeasurementResult.Results.test.ts @@ -0,0 +1,302 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { DCCDocument, ResultType } from "../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:results"; +const xpath = { + measurementResults: { + measurementResult: { + results: { + result: { + name: { + content: `${base}/dcc:result[1]/dcc:name/dcc:content`, + }, + data: { + list: { + quantity1: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + measurementMetaData: { + metaData: { + declaration: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:declaration/dcc:content`, + }, + data: { + quantity: { + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData/dcc:data/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:measurementMetaData/dcc:metaData//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]//@refType)`, + }, + quantity2: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[2]//@refType)`, + }, + quantity3: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/dcc:name/dcc:content`, + }, + si_realListXMLList: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:unitXMLList)`, + si_expandedUncXMLList: { + si_uncertaintyXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:uncertaintyXMLList)`, + si_coverageFactorXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageFactorXMLList)`, + si_coverageProbabilityXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:coverageProbabilityXMLList)`, + si_distributionXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/si:realListXMLList[1]/si:expandedUncXMLList/si:distributionXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[3]/@refType)`, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]//@refType)`, + }, + }, + }, + }, +}; + +describe("ResultType", () => { + let dcc: DCCDocument, result: ResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + result = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].results.result[0]; + }); + + test("should get correct result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.name.content, dom); + expect(toTextArr(result.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 1 hybrid si:unitXMLList 2: from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 1 meta data declaration content from XML", () => { + // get expected list from example xml + const expected = <Element[]>( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.declaration.content, dom) + ); + expect(toTextArr(result.data.list[0].quantity[0].measurementMetaData.metaData[0].declaration.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 1 meta data hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.data.quantity.si_hybrid.si_realListXMLList1 + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 1 meta data hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.data.quantity.si_hybrid.si_realListXMLList1 + .si_unitXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 1 meta data hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.data.quantity.si_hybrid.si_realListXMLList2 + .si_valueXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 1 meta data hybrid si:unitXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0].data.quantity[0].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 2 hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 2 hybrid si:unitXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[1].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 3 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.name.content, dom); + expect(toTextArr(result.data.list[0].quantity[2].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity 3 si:valueXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity 3 si:unitXMLList from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity 3 uncertainty list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.uncertaintyXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_uncertaintyXMLList, dom), + ); + }); + + test("should get correct result quantity 3 uncertainty coverage factor list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageFactorXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageFactorXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 uncertainty coverage probability list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.coverageProbabilityXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_coverageProbabilityXMLList, + dom, + ), + ); + }); + + test("should get correct result quantity 3 uncertainty distribution list from XML", () => { + expect(result.data.list[0].quantity[2].realListXMLList.expandedUncXMLList.distributionXMLList._text).toBe( + select( + xpath.measurementResults.measurementResult.results.result.data.list.quantity3.si_realListXMLList.si_expandedUncXMLList.si_distributionXMLList, + dom, + ), + ); + }); + + test("should get correct result refType from XML", () => { + expect(result._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.refType, dom)); + }); + + test("should get correct result data list refType from XML", () => { + expect(result.data.list[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.list.refType, dom)); + }); + + test("should get correct result quantity 1 refType from XML", () => { + expect(result.data.list[0].quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.refType, dom), + ); + }); + + test("should get correct result quantity 1 meta data refType from XML", () => { + expect(result.data.list[0].quantity[0].measurementMetaData.metaData[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity1.measurementMetaData.metaData.refType, dom), + ); + }); + + test("should get correct result quantity 2 refType from XML", () => { + expect(result.data.list[0].quantity[1]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity2.refType, dom), + ); + }); + + test("should get correct result quantity 3 refType from XML", () => { + expect(result.data.list[0].quantity[2]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity3.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts b/tests/DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts new file mode 100644 index 0000000..54cdf56 --- /dev/null +++ b/tests/DCC/MeasurementResults.MeasurementResult.UsedMethods.test.ts @@ -0,0 +1,81 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { DCCDocument, MeasurementResultType, UsedMethodListType, UsedMethodType } from "../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]"; +const xpath = { + measurementResults: { + measurementResult: { + usedMethods: { + usedMethod1: { + name: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:name/dcc:content`, + }, + description: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:description/dcc:content`, + contentDE: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:description/dcc:content[@lang='de']`, + contentEN: `${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:description/dcc:content[@lang='en']`, + }, + norm: `string(${base}/dcc:usedMethods/dcc:usedMethod[1]/dcc:norm[1])`, + refType: `string(${base}/dcc:usedMethods/dcc:usedMethod[1]//@refType)`, + }, + usedMethod2: { + name: { + content: `${base}/dcc:usedMethods/dcc:usedMethod[2]/dcc:name/dcc:content`, + }, + norm: `string(${base}/dcc:usedMethods/dcc:usedMethod[2]/dcc:norm[1])`, + refType: `string(${base}/dcc:usedMethods/dcc:usedMethod[2]//@refType)`, + }, + }, + }, + }, +}; + +describe("UsedMethodListType", () => { + let dcc: DCCDocument, usedMethods: UsedMethodListType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + usedMethods = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].usedMethods; + }); + + test("should get correct used method 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.name.content, dom); + expect(toTextArr(usedMethods.usedMethod[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 1 description content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.description.content, dom); + expect(toTextArr(usedMethods.usedMethod[0].description.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 1 norm from XML", () => { + expect(usedMethods.usedMethod[0].norm[0]._text).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.norm, dom)); + }); + + test("should get correct used method 1 refType from XML", () => { + expect(usedMethods.usedMethod[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod1.refType, dom)); + }); + + test("should get correct used method 2 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.usedMethods.usedMethod2.name.content, dom); + expect(toTextArr(usedMethods.usedMethod[1].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct used method 2 norm from XML", () => { + expect(usedMethods.usedMethod[1].norm[0]._text).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod2.norm, dom)); + }); + + test("should get correct used method 2 refType from XML", () => { + expect(usedMethods.usedMethod[1]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.usedMethods.usedMethod2.refType, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/Test_DCC_Minimal/AdministrativeData.CalibrationLaboratory.test.ts b/tests/DCC/Test_DCC_Minimal/AdministrativeData.CalibrationLaboratory.test.ts new file mode 100644 index 0000000..3529e3b --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/AdministrativeData.CalibrationLaboratory.test.ts @@ -0,0 +1,34 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { CalibrationLaboratoryType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:calibrationLaboratory/dcc:contact"; +const xpath = { + name: `string(${base}/dcc:name/dcc:content)`, + location: { + city: `${base}/dcc:location/dcc:city`, + }, +}; + +describe("Test_DCC_Minimal: CalibrationLaboratoryType", () => { + let dcc: DCCDocument, calibrationLaboratory: CalibrationLaboratoryType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + calibrationLaboratory = dcc.digitalCalibrationCertificate.administrativeData.calibrationLaboratory; + }); + + test("should get correct name from XML", () => { + expect(calibrationLaboratory.contact.name.content[0]._text).toBe(select(xpath.name, dom)); + }); + + test("should get correct city from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.city, dom); + expect(toTextArr(calibrationLaboratory.contact.location.city)).toEqual(toTextContentArr(expected)); + }); +}); diff --git a/tests/DCC/Test_DCC_Minimal/AdministrativeData.CoreDataType.test.ts b/tests/DCC/Test_DCC_Minimal/AdministrativeData.CoreDataType.test.ts new file mode 100644 index 0000000..e9ca47c --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/AdministrativeData.CoreDataType.test.ts @@ -0,0 +1,116 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import * as fc from "fast-check"; +import { indexOf, select, toTextArr, toTextContentArr } from "../../util"; +import { CoreDataType, DCCDocument, DCCXMLElement } from "../../../src"; +import { string_ISO639_1 } from "../../Arbitraries"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:coreData"; +const xpath = { + coreData: { + countryCodeISO3166_1: `string(${base}/dcc:countryCodeISO3166_1)`, + usedLangCodeISO639_1: `${base}/dcc:usedLangCodeISO639_1`, + mandatoryLangCodeISO639_1: `${base}/dcc:mandatoryLangCodeISO639_1`, + uniqueIdentifier: `string(${base}/dcc:uniqueIdentifier)`, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + }, + beginPerformanceDate: `string(${base}/dcc:beginPerformanceDate)`, + endPerformanceDate: `string(${base}/dcc:endPerformanceDate)`, + performanceLocation: `string(${base}/dcc:performanceLocation)`, + }, +}; + +describe("Test_DCC_Minimal: CoreDataType", () => { + let dcc: DCCDocument, coreData: CoreDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + coreData = dcc.digitalCalibrationCertificate.administrativeData.coreData; + }); + + test("should get correct countryCodeISO3166_1 from XML", () => { + expect(coreData.countryCodeISO3166_1._text).toBe(select(xpath.coreData.countryCodeISO3166_1, dom)); + }); + + test("should get correct usedLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom); + expect(toTextArr(coreData.usedLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct mandatoryLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.mandatoryLangCodeISO639_1, dom); + expect(toTextArr(coreData.mandatoryLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct unique identifier from XML", () => { + expect(coreData.uniqueIdentifier._text).toBe(select(xpath.coreData.uniqueIdentifier, dom)); + }); + + test("should get correct identification issuer from XML", () => { + expect(coreData.identifications.identification[0].issuer._text).toBe(select(xpath.coreData.identifications.identification.issuer, dom)); + }); + + test("should get correct identification value from XML", () => { + expect(coreData.identifications.identification[0].value._text).toBe(select(xpath.coreData.identifications.identification.value, dom)); + }); + + test("should get correct identification name content from XML", () => { + const expected = <Element[]>select(xpath.coreData.identifications.identification.name.content, dom); + expect(toTextArr(coreData.identifications.identification[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct begin performance date from XML", () => { + expect(coreData.beginPerformanceDate._text).toBe(select(xpath.coreData.beginPerformanceDate, dom)); + }); + test("should get correct end performance date from XML", () => { + expect(coreData.endPerformanceDate._text).toBe(select(xpath.coreData.endPerformanceDate, dom)); + }); + test("should get correct performance location from XML", () => { + expect(coreData.performanceLocation._text).toBe(select(xpath.coreData.performanceLocation, dom)); + }); + + /* test for setters */ + test("should set usedLangCodeISO639_1 correctly", () => { + fc.assert( + fc.property(string_ISO639_1(), (str) => { + // add new element to array + coreData.usedLangCodeISO639_1.push(new DCCXMLElement({ _text: str })); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).toContain(str); + expect(toTextContentArr(actual)).toContain(str); + }), + ); + }); + + test("should delete usedLangCodeISO639_1 correctly", () => { + const selection = toTextContentArr(<Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom)); + fc.assert( + fc.property(fc.constantFrom(...selection), (str) => { + // get index and remove element from array + const index = indexOf(coreData.usedLangCodeISO639_1, str); + coreData.usedLangCodeISO639_1.splice(index, 1); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).not.toContain(str); + expect(toTextContentArr(actual)).not.toContain(str); + }), + ); + }); +}); diff --git a/tests/DCC/Test_DCC_Minimal/AdministrativeData.Customer.test.ts b/tests/DCC/Test_DCC_Minimal/AdministrativeData.Customer.test.ts new file mode 100644 index 0000000..3888155 --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/AdministrativeData.Customer.test.ts @@ -0,0 +1,42 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ContactType, DCCDocument, LocationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:customer"; +const xpath = { + customer: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + location: { + city: `${base}/dcc:location/dcc:city[1]`, + }, + }, +}; + +describe("Test_DCC_Minimal: ContactType", () => { + let dcc: DCCDocument, customer: ContactType, location: LocationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + customer = dcc.digitalCalibrationCertificate.administrativeData.customer; + location = customer.location; /* TODO: check iff this variable is used anywhere */ + }); + + test("should get correct customer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.customer.name.content, dom); + expect(toTextArr(customer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct customer location city from XML", () => { + const expected = <Element[]>select(xpath.customer.location.city, dom); + expect(customer.location.city[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/Test_DCC_Minimal/AdministrativeData.Items.test.ts b/tests/DCC/Test_DCC_Minimal/AdministrativeData.Items.test.ts new file mode 100644 index 0000000..958427c --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/AdministrativeData.Items.test.ts @@ -0,0 +1,64 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { ItemType, DCCDocument, IdentificationType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:items"; +const xpath = { + items: { + item: { + name: { + content: `${base}/dcc:item[1]/dcc:name/dcc:content`, + }, + manufacturer: { + name: { + content: `${base}/dcc:item[1]/dcc:manufacturer/dcc:name/dcc:content`, + }, + }, + identifications: { + identification: { + issuer: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:item[1]/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + }, + }, + }, +}; + +describe("Test_DCC_Minimal: ItemType", () => { + let dcc: DCCDocument, item: ItemType, identification: IdentificationType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + item = dcc.digitalCalibrationCertificate.administrativeData.items.item[0]; + identification = item.identifications.identification[0]; + }); + + test("should get correct item name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.name.content, dom); + expect(toTextArr(item.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct item manufacturer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.items.item.manufacturer.name.content, dom); + expect(toTextArr(item.manufacturer.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct identification issuer from XML", () => { + expect(identification.issuer._text).toBe(select(xpath.items.item.identifications.identification.issuer, dom)); + }); + + test("should get correct identification value from XML", () => { + expect(identification.value._text).toBe(select(xpath.items.item.identifications.identification.value, dom)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/Test_DCC_Minimal/AdministrativeData.RespPersons.test.ts b/tests/DCC/Test_DCC_Minimal/AdministrativeData.RespPersons.test.ts new file mode 100644 index 0000000..7c74d61 --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/AdministrativeData.RespPersons.test.ts @@ -0,0 +1,37 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { RespPersonType, DCCDocument } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:respPersons"; +const xpath = { + respPersons: { + respPerson: { + person: { + name: { + content: `${base}/dcc:respPerson[1]/dcc:person/dcc:name/dcc:content`, + }, + }, + }, + }, +}; + +describe("Test_DCC_Minimal: RespPersonType", () => { + let dcc: DCCDocument, respPerson: RespPersonType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + respPerson = dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[0]; + }); + + test("should get correct responsible person 1 name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.respPersons.respPerson.person.name.content, dom); + expect(toTextArr(respPerson.person.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/Test_DCC_Minimal/AdministrativeData.SoftwareListType.test.ts b/tests/DCC/Test_DCC_Minimal/AdministrativeData.SoftwareListType.test.ts new file mode 100644 index 0000000..3577e44 --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/AdministrativeData.SoftwareListType.test.ts @@ -0,0 +1,41 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { SoftwareListType, DCCDocument, SoftwareType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:dccSoftware/dcc:software"; +const xpath = { + software: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + release: `string(${base}/dcc:release)`, + type: `string(${base}/dcc:type)`, + description: `${base}/dcc:description`, + _id: `${base}/@id`, + _refType: `${base}/@refType`, + }, +}; + +describe("Test_DCC_Minimal: DccSoftwareType", () => { + let dcc: DCCDocument, dccSoftware: SoftwareListType, software: SoftwareType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + dccSoftware = dcc.digitalCalibrationCertificate.administrativeData.dccSoftware; + software = dccSoftware.software[0]; + }); + + test("should get correct software name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.software.name.content, dom); + expect(toTextArr(software.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct software release version of software from XML", () => { + expect(software.release._text).toBe(select(xpath.software.release, dom)); + }); +}); diff --git a/tests/DCC/Test_DCC_Minimal/DigitalCalibrationCertificateType.test.ts b/tests/DCC/Test_DCC_Minimal/DigitalCalibrationCertificateType.test.ts new file mode 100644 index 0000000..1f0006a --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/DigitalCalibrationCertificateType.test.ts @@ -0,0 +1,21 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select } from "../../util"; + +const VERSION_XPATH = "string(/dcc:digitalCalibrationCertificate/@schemaVersion)"; + +describe("Test_DCC_Minimal: DigitalCalibrationCertificateType", () => { + let xml, dcc, dom; + + beforeEach(() => { + ({ xml, dcc, dom } = xmlEnv.recreateEnv()); + }); + + test("should get correct schemaVersion from XML", () => { + const expectedVersion = select(VERSION_XPATH, dom); + expect(dcc.digitalCalibrationCertificate._attr.schemaVersion).toBe(expectedVersion); + }); +}); diff --git a/tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Name.test.ts b/tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Name.test.ts new file mode 100644 index 0000000..bd50cc0 --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Name.test.ts @@ -0,0 +1,35 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, MeasurementResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults"; +const xpath = { + measurementResults: { + measurementResult: { + name: { + content: `${base}/dcc:measurementResult[1]/dcc:name/dcc:content`, + }, + }, + }, +}; + +describe("Test_DCC_Minimal: MeasurementResultType", () => { + let dcc: DCCDocument, measurementResult: MeasurementResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + measurementResult = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0]; + }); + + test("should get correct measurement result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.name.content, dom); + expect(toTextArr(measurementResult.name.content)).toEqual(toTextContentArr(expected)); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Results.test.ts b/tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Results.test.ts new file mode 100644 index 0000000..06a0973 --- /dev/null +++ b/tests/DCC/Test_DCC_Minimal/MeasurementResults.MeasurementResult.Results.test.ts @@ -0,0 +1,100 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/Test_DCC_Minimal.xml + */ + +import { select, toTextArr, toTextContentArr } from "../../util"; +import { DCCDocument, ResultType } from "../../../src"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:measurementResults/dcc:measurementResult[1]/dcc:results"; +const xpath = { + measurementResults: { + measurementResult: { + results: { + result: { + name: { + content: `${base}/dcc:result[1]/dcc:name/dcc:content`, + }, + data: { + list: { + quantity: { + name: { + content: `${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/dcc:name/dcc:content`, + }, + si_hybrid: { + si_realListXMLList1: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[1]/si:unitXMLList)`, + }, + si_realListXMLList2: { + si_valueXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:valueXMLList)`, + si_unitXMLList: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]/si:hybrid/si:realListXMLList[2]/si:unitXMLList)`, + }, + }, + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list/dcc:quantity[1]//@refType)`, + }, + + refType: `string(${base}/dcc:result[1]/dcc:data/dcc:list//@refType)`, + }, + }, + refType: `string(${base}/dcc:result[1]//@refType)`, + }, + }, + }, + }, +}; + +describe("Test_DCC_Minimal: ResultType", () => { + let dcc: DCCDocument, result: ResultType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + result = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].results.result[0]; + }); + + test("should get correct result name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.measurementResults.measurementResult.results.result.name.content, dom); + expect(toTextArr(result.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct result quantity hybrid si:valueXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity.si_hybrid.si_realListXMLList1.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity hybrid si:unitXMLList 1 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[0].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity.si_hybrid.si_realListXMLList1.si_unitXMLList, dom), + ); + }); + + test("should get correct result quantity hybrid si:valueXMLList 2 from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].valueXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity.si_hybrid.si_realListXMLList2.si_valueXMLList, dom), + ); + }); + + test("should get correct result quantity hybrid si:unitXMLList 2: from XML", () => { + expect(result.data.list[0].quantity[0].hybrid.realListXMLList[1].unitXMLList._text).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity.si_hybrid.si_realListXMLList2.si_unitXMLList, dom), + ); + }); + + test("should get correct result refType from XML", () => { + expect(result._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.refType, dom)); + }); + + test("should get correct result data list refType from XML", () => { + expect(result.data.list[0]._attr.refType).toBe(select(xpath.measurementResults.measurementResult.results.result.data.list.refType, dom)); + }); + + test("should get correct result quantity 1 refType from XML", () => { + expect(result.data.list[0].quantity[0]._attr.refType).toBe( + select(xpath.measurementResults.measurementResult.results.result.data.list.quantity.refType, dom), + ); + }); + + /* TODO: setters */ +}); diff --git a/tests/DCC/common/AdministrativeData/CalibrationLaboratory.ts b/tests/DCC/common/AdministrativeData/CalibrationLaboratory.ts new file mode 100644 index 0000000..25a455d --- /dev/null +++ b/tests/DCC/common/AdministrativeData/CalibrationLaboratory.ts @@ -0,0 +1,78 @@ +import { select, toTextArr, toTextContentArr } from "../../../util"; +import { CalibrationLaboratoryType, DCCDocument } from "../../../../src"; +import { testRichContentType } from "../Types/RichContentType"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:calibrationLaboratory/dcc:contact"; +const xpath = { + name: `${base}/dcc:name`, + eMail: `string(${base}/dcc:eMail)`, + phone: `string(${base}/dcc:phone)`, + fax: `string(${base}/dcc:fax)`, + location: { + city: `${base}/dcc:location/dcc:city`, + countryCode: `${base}/dcc:location/dcc:countryCode`, + postCode: `${base}/dcc:location/dcc:postCode`, + street: `${base}/dcc:location/dcc:street`, + streetNo: `${base}/dcc:location/dcc:streetNo`, + further: `${base}/dcc:location/dcc:further/dcc:content`, + }, +}; + +export const testCalibrationLaboratory = () => { + describe("CalibrationLaboratoryType", () => { + let dcc: DCCDocument, calibrationLaboratory: CalibrationLaboratoryType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + calibrationLaboratory = dcc.digitalCalibrationCertificate.administrativeData.calibrationLaboratory; + }); + + test("should get correct name from XML", () => { + testRichContentType(xpath.name, calibrationLaboratory.contact.name, dom); + }); + + test("should get correct eMail from XML", () => { + expect(calibrationLaboratory.contact.eMail._text).toBe(select(xpath.eMail, dom)); + }); + + test("should get correct phone from XML", () => { + expect(calibrationLaboratory.contact.phone._text).toBe(select(xpath.phone, dom)); + }); + + test("should get correct city from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.city, dom); + expect(toTextArr(calibrationLaboratory.contact.location.city)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct countryCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.countryCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.countryCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct postCode from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.postCode, dom); + expect(toTextArr(calibrationLaboratory.contact.location.postCode)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct street from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.street, dom); + expect(toTextArr(calibrationLaboratory.contact.location.street)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct streetNo from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.streetNo, dom); + expect(toTextArr(calibrationLaboratory.contact.location.streetNo)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct further element from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.location.further, dom); + expect(toTextArr(calibrationLaboratory.contact.location.further[0].content)).toEqual(toTextContentArr(expected)); + }); + }); +}; diff --git a/tests/DCC/common/AdministrativeData/CoreDataType.ts b/tests/DCC/common/AdministrativeData/CoreDataType.ts new file mode 100644 index 0000000..ea974a5 --- /dev/null +++ b/tests/DCC/common/AdministrativeData/CoreDataType.ts @@ -0,0 +1,117 @@ +import * as fc from "fast-check"; +import { indexOf, select, toTextArr, toTextContentArr } from "../../../util"; +import { CoreDataType, DCCDocument, DCCXMLElement } from "../../../../src"; +import { string_ISO639_1 } from "../../../Arbitraries"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:coreData"; +const xpath = { + coreData: { + countryCodeISO3166_1: `string(${base}/dcc:countryCodeISO3166_1)`, + usedLangCodeISO639_1: `${base}/dcc:usedLangCodeISO639_1`, + mandatoryLangCodeISO639_1: `${base}/dcc:mandatoryLangCodeISO639_1`, + uniqueIdentifier: `string(${base}/dcc:uniqueIdentifier)`, + identifications: { + identification: { + issuer: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:issuer)`, + value: `string(${base}/dcc:identifications/dcc:identification[1]/dcc:value)`, + name: { + content: `${base}/dcc:identifications/dcc:identification[1]/dcc:name/dcc:content`, + }, + }, + }, + receiptDate: `string(${base}/dcc:receiptDate)`, + beginPerformanceDate: `string(${base}/dcc:beginPerformanceDate)`, + endPerformanceDate: `string(${base}/dcc:endPerformanceDate)`, + performanceLocation: `string(${base}/dcc:performanceLocation)`, + }, +}; + +export const testCoreData = () => { + describe("CoreDataType", () => { + let dcc: DCCDocument, coreData: CoreDataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + coreData = dcc.digitalCalibrationCertificate.administrativeData.coreData; + }); + + test("should get correct countryCodeISO3166_1 from XML", () => { + expect(coreData.countryCodeISO3166_1._text).toBe(select(xpath.coreData.countryCodeISO3166_1, dom)); + }); + + test("should get correct usedLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom); + expect(toTextArr(coreData.usedLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct mandatoryLangCodeISO639_1 from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.coreData.mandatoryLangCodeISO639_1, dom); + expect(toTextArr(coreData.mandatoryLangCodeISO639_1)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct unique identifier from XML", () => { + expect(coreData.uniqueIdentifier._text).toBe(select(xpath.coreData.uniqueIdentifier, dom)); + }); + + test("should get correct identification issuer from XML", () => { + expect(coreData.identifications.identification[0].issuer._text).toBe(select(xpath.coreData.identifications.identification.issuer, dom)); + }); + + test("should get correct identification value from XML", () => { + expect(coreData.identifications.identification[0].value._text).toBe(select(xpath.coreData.identifications.identification.value, dom)); + }); + + test("should get correct identification name content from XML", () => { + const expected = <Element[]>select(xpath.coreData.identifications.identification.name.content, dom); + expect(toTextArr(coreData.identifications.identification[0].name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct receipt date from XML", () => { + expect(coreData.receiptDate._text).toBe(select(xpath.coreData.receiptDate, dom)); + }); + test("should get correct begin performance date from XML", () => { + expect(coreData.beginPerformanceDate._text).toBe(select(xpath.coreData.beginPerformanceDate, dom)); + }); + test("should get correct end performance date from XML", () => { + expect(coreData.endPerformanceDate._text).toBe(select(xpath.coreData.endPerformanceDate, dom)); + }); + test("should get correct performance location from XML", () => { + expect(coreData.performanceLocation._text).toBe(select(xpath.coreData.performanceLocation, dom)); + }); + + /* test for setters */ + test("should set usedLangCodeISO639_1 correctly", () => { + fc.assert( + fc.property(string_ISO639_1(), (str) => { + // add new element to array + coreData.usedLangCodeISO639_1.push(new DCCXMLElement({ _text: str })); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).toContain(str); + expect(toTextContentArr(actual)).toContain(str); + }), + ); + }); + + test("should delete usedLangCodeISO639_1 correctly", () => { + const selection = toTextContentArr(<Element[]>select(xpath.coreData.usedLangCodeISO639_1, dom)); + fc.assert( + fc.property(fc.constantFrom(...selection), (str) => { + // get index and remove element from array + const index = indexOf(coreData.usedLangCodeISO639_1, str); + coreData.usedLangCodeISO639_1.splice(index, 1); + + // get actual list from xml + const actual = <Element[]>select(xpath.coreData.usedLangCodeISO639_1, dcc); + + expect(toTextArr(coreData.usedLangCodeISO639_1)).not.toContain(str); + expect(toTextContentArr(actual)).not.toContain(str); + }), + ); + }); + }); +}; diff --git a/tests/DCC/common/AdministrativeData/RespPersons.ts b/tests/DCC/common/AdministrativeData/RespPersons.ts new file mode 100644 index 0000000..88495a0 --- /dev/null +++ b/tests/DCC/common/AdministrativeData/RespPersons.ts @@ -0,0 +1,19 @@ +import { select } from "../../../util"; +import { testRespPersonType } from "../Types/RespPersonType"; + +const base = "/dcc:digitalCalibrationCertificate/dcc:administrativeData/dcc:respPersons"; +const xpath = { + respPerson: `${base}/dcc:respPerson`, +}; +export const testRespPersonListType = () => { + describe("RespPersonListType", () => { + const { dom } = xmlEnv.recreateEnv(); + + const expectedRespPersons = <Element[]>select(xpath.respPerson, dom); + for (let i = 0; i < expectedRespPersons.length; i++) { + testRespPersonType(`${xpath.respPerson}[${i + 1}]`, (dcc) => dcc.digitalCalibrationCertificate.administrativeData.respPersons.respPerson[i]); + } + + /* TODO: setters */ + }); +}; diff --git a/tests/DCC/common/Types/ContactType.ts b/tests/DCC/common/Types/ContactType.ts new file mode 100644 index 0000000..07b0d21 --- /dev/null +++ b/tests/DCC/common/Types/ContactType.ts @@ -0,0 +1,72 @@ +import { ContactNotStrictType, ContactType, DCCDocument } from "../../../../src"; +import { select, toTextArr, toTextContentArr, undefinedIfEmpty } from "../../../util"; + +export const testContactType = (base: string, contactTypeFn: (dcc: DCCDocument) => ContactType | ContactNotStrictType) => { + const xpath = { + customer: { + name: { + content: `${base}/dcc:name/dcc:content`, + }, + email: `string(${base}/dcc:eMail)`, + phone: `string(${base}/dcc:phone)`, + fax: `string(${base}/dcc:fax)`, + location: { + city: `${base}/dcc:location/dcc:city[1]`, + countryCode: `${base}/dcc:location/dcc:countryCode[1]`, + postCode: `${base}/dcc:location/dcc:postCode[1]`, + postBoxOffice: `${base}/dcc:location/dcc:postBoxOffice[1]`, + state: `${base}/dcc:location/dcc:state[1]`, + street: `${base}/dcc:location/dcc:street[1]`, + streetNo: `${base}/dcc:location/dcc:streetNo[1]`, + further: `${base}/dcc:location/dcc:further[1]/dcc:content`, + positionCoordinates: `${base}/dcc:location/dcc:positionCoordinates[1]`, + }, + descriptionData: `${base}/dcc:descriptionData`, + _id: `${base}/@id`, + }, + }; + + describe("ContactType", () => { + let dcc: DCCDocument, contactType: ContactType | ContactNotStrictType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + contactType = contactTypeFn(dcc); + }); + + test("should get correct customer name content from XML", () => { + // get expected list from example xml + const expected = <Element[]>select(xpath.customer.name.content, dom); + expect(toTextArr(contactType.name.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct customer email address from XML", () => { + expect(contactType.eMail?._text).toBe(undefinedIfEmpty(select(xpath.customer.email, dom))); + }); + + test("should get correct customer location city from XML", () => { + const expected = <Element[]>select(xpath.customer.location.city, dom); + expect(contactType.location?.city[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location county code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.countryCode, dom); + expect(contactType.location?.countryCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location post code from XML", () => { + const expected = <Element[]>select(xpath.customer.location.postCode, dom); + expect(contactType.location?.postCode[0]._text).toEqual(toTextContentArr(expected)[0]); + }); + + test("should get correct customer location further from XML", () => { + const expected = <Element[]>select(xpath.customer.location.further, dom); + + for (let i = 0; i < expected.length; i++) { + expect(contactType.location?.further[0].content[i]._text).toBe(expected[i].textContent); + } + }); + + /* TODO: setters */ + }); +}; diff --git a/tests/DCC/common/Types/DataType.ts b/tests/DCC/common/Types/DataType.ts new file mode 100644 index 0000000..e39bb76 --- /dev/null +++ b/tests/DCC/common/Types/DataType.ts @@ -0,0 +1,23 @@ +import { DataType, DCCDocument } from "../../../../src"; +import { select, toTextArr, toTextContentArr, undefinedIfEmpty } from "../../../util"; + +export const testDataType = (base: string, dataTypeFn: (dcc: DCCDocument) => DataType) => { + const xpath = { + text: `${base}/dcc:text`, + quantity: `${base}/dcc:quantity`, + list: `${base}/dcc:list`, + }; + + describe("DataType", () => { + let dcc: DCCDocument, dataType: DataType, dom; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + dataType = dataTypeFn(dcc); + }); + + test("noop", () => {}); + + // TODO(Statement): quantity with real + }); +}; diff --git a/tests/DCC/common/Types/RespPersonType.ts b/tests/DCC/common/Types/RespPersonType.ts new file mode 100644 index 0000000..4284f9e --- /dev/null +++ b/tests/DCC/common/Types/RespPersonType.ts @@ -0,0 +1,28 @@ +import { DCCDocument, RespPersonType } from "../../../../src"; +import { select, undefinedIfEmpty } from "../../../util"; +import { testContactType } from "./ContactType"; + +export const testRespPersonType = (base: string, respPersonTypeFn: (dcc: DCCDocument) => RespPersonType) => { + const xpath = { + person: `${base}/dcc:person`, + mainSigner: `string(${base}/dcc:mainSigner)`, + }; + + describe("RespPersonType", () => { + let dcc: DCCDocument, respPersonType: RespPersonType, dom; + ({ dcc, dom } = xmlEnv.recreateEnv()); + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + respPersonType = respPersonTypeFn(dcc); + }); + + testContactType(xpath.person, (dcc) => respPersonTypeFn(dcc).person); + + test("should get correct responsible person main signer flag from XML", () => { + expect(respPersonType.mainSigner?._text).toBe(undefinedIfEmpty(select(xpath.mainSigner, dom))); + }); + + /* TODO: setters */ + }); +}; diff --git a/tests/DCC/common/Types/RichContentType.ts b/tests/DCC/common/Types/RichContentType.ts new file mode 100644 index 0000000..cf873f0 --- /dev/null +++ b/tests/DCC/common/Types/RichContentType.ts @@ -0,0 +1,25 @@ +import { JSDOM } from "jsdom"; +import * as _ from "lodash"; +import { RichContentType } from "../../../../src"; +import { select } from "../../../util"; + +const testContent = (base: string, richContent: RichContentType, dom: JSDOM) => { + const elements = <Element[]>select(`${base}/dcc:content`, dom); + // get expected langs from xml, filter out empty strings + const langs = _.uniq(elements.map((x) => x.getAttribute("lang")).filter((x) => x)); + if(langs.length > 0) { + // check content for each lang if there are any + for (const lang of langs) { + expect(richContent.getContent(lang)._text).toBe(select(`string(${base}/dcc:content[@lang="${lang}"])`, dom)); + } + } else { + // check content if there are no langs + expect(richContent.getContent()._text).toBe(select(`string(${base}/dcc:content)`, dom)); + } +} + +export const testRichContentType = (base: string, richContent: RichContentType, dom: JSDOM) => { + testContent(base, richContent, dom); + // TODO: test file + // TODO: test formula +}; diff --git a/tests/DCC/common/Types/StatementListType.ts b/tests/DCC/common/Types/StatementListType.ts new file mode 100644 index 0000000..254fda4 --- /dev/null +++ b/tests/DCC/common/Types/StatementListType.ts @@ -0,0 +1,18 @@ +import { select } from "../../../util"; +import { testStatementMetaDataType } from "./StatementMetaDataType"; +import { DCCDocument, StatementListType } from "../../../../src"; + +export const testStatementListType = (base, statementListTypeFn: (dcc: DCCDocument) => StatementListType) => { + const xpath = { + statement: `${base}/dcc:statement`, + }; + + describe("StatementListType", () => { + const { dom } = xmlEnv.recreateEnv(); + + const expectedStatements = <Element[]>select(xpath.statement, dom); + for (let i = 0; i < expectedStatements.length; i++) { + testStatementMetaDataType(i, `${xpath.statement}[${i + 1}]`, (dcc) => statementListTypeFn(dcc).statement[i]); + } + }); +}; diff --git a/tests/DCC/common/Types/StatementMetaDataType.ts b/tests/DCC/common/Types/StatementMetaDataType.ts new file mode 100644 index 0000000..5e09d86 --- /dev/null +++ b/tests/DCC/common/Types/StatementMetaDataType.ts @@ -0,0 +1,72 @@ +import { DCCDocument, StatementMetaDataType } from "../../../../src"; +import { select, toTextArr, toTextContentArr, undefinedIfEmpty } from "../../../util"; +import { testContactType } from "./ContactType"; +import { testDataType } from "./DataType"; + +export const testStatementMetaDataType = (name, base: string, statementMetaDataTypeFn: (dcc: DCCDocument) => StatementMetaDataType) => { + const xpath = { + norm: `${base}/dcc:norm`, + reference: `${base}/dcc:reference`, + declaration: { + content: `${base}/dcc:declaration/dcc:content`, + }, + conformity: `string(${base}/dcc:conformity)`, + date: `string(${base}/dcc:date)`, + respAuthority: `${base}/dcc:respAuthority`, + data: `${base}/dcc:data`, + + refType: `string(${base}/@refType)`, + }; + + describe(`StatementMetaDataType ${name}`, () => { + let dcc: DCCDocument, statementMetaDataType: StatementMetaDataType, dom; + ({ dcc, dom } = xmlEnv.recreateEnv()); + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + statementMetaDataType = statementMetaDataTypeFn(dcc); + }); + + const hasContact = <boolean>select(`boolean(${xpath.respAuthority})`, dom); + if (hasContact) { + testContactType(xpath.respAuthority, (dcc) => statementMetaDataTypeFn(dcc).respAuthority); + } + + const hasData = <boolean>select(`boolean(${xpath.data})`, dom); + if (hasData) { + testDataType(xpath.data, (dcc) => statementMetaDataTypeFn(dcc).data); + } + + test("should get correct statement declaration content from XML", () => { + const expected = <Element[]>select(xpath.declaration.content, dom); + expect(toTextArr(statementMetaDataType.declaration?.content)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement norm model from XML", () => { + const expected = <Element[]>select(xpath.norm, dom); + expect(toTextArr(statementMetaDataType.norm)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement reference from XML", () => { + const expected = <Element[]>select(xpath.reference, dom); + expect(toTextArr(statementMetaDataType.reference)).toEqual(toTextContentArr(expected)); + }); + + test("should get correct statement refType from XML", () => { + const expected = select(xpath.refType, dom); + expect(statementMetaDataType._attr.refType).toBe(undefinedIfEmpty(expected)); + }); + + test("should get correct statement conformity from XML", () => { + const expected = select(xpath.conformity, dom); + expect(statementMetaDataType.conformity?._text).toBe(undefinedIfEmpty(expected)); + }); + + test("should get correct statement date from XML", () => { + const expected = select(xpath.date, dom); + expect(statementMetaDataType.date?._text).toBe(undefinedIfEmpty(expected)); + }); + + /* TODO: setters */ + }); +}; diff --git a/tests/DCCDocument.test.ts b/tests/DCCDocument.test.ts index 3e1d889..06dccbf 100644 --- a/tests/DCCDocument.test.ts +++ b/tests/DCCDocument.test.ts @@ -1,12 +1,20 @@ -import { DCCDocument } from "../src"; -import { xml } from "./Resources/example.xml"; -import { expect } from "chai"; -import { describe, it } from "mocha"; - -describe("DCCDocument", - () => { - it("should not modify XML", () => { - let dcc = DCCDocument.fromXml(xml); - expect(dcc.toXML()).to.be.equal(xml); - }); +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/example.xml + */ + +describe("DCCDocument", () => { + let xml, dcc; + + beforeEach(() => { + ({ xml, dcc } = xmlEnv.recreateEnv()); + }); + + test("fromXml() and toXml() should not modify XML", () => { + // fix line endings, they are always LF + xml = xml.replace(/\r\n|\r|\n/g, "\n"); + + // fromXml() is part of the XMLEnvironment + expect(dcc.toXML()).toBe(xml); }); +}); diff --git a/tests/GP_Temperature/CharsXMLList.test.ts b/tests/GP_Temperature/CharsXMLList.test.ts new file mode 100644 index 0000000..ac10b24 --- /dev/null +++ b/tests/GP_Temperature/CharsXMLList.test.ts @@ -0,0 +1,25 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select } from "../util"; +import { DCCDocument } from "../../src"; + +const base = "//dcc:quantity[@refType='test_charsXMLList']"; +const xpath = { + charsXMLList: `string(${base}/dcc:charsXMLList)`, +}; + +describe("CharsXMLList", () => { + let dcc: DCCDocument, dom, result; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + result = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].results.result[0]; + }); + + test("should get correct charsXMLList from XML", () => { + expect(result.data.quantity[1].charsXMLList._text).toBe(select(xpath.charsXMLList, dom)); + }); +}); diff --git a/tests/GP_Temperature/noQuantity.test.ts b/tests/GP_Temperature/noQuantity.test.ts new file mode 100644 index 0000000..8b8bc09 --- /dev/null +++ b/tests/GP_Temperature/noQuantity.test.ts @@ -0,0 +1,56 @@ +/** + * @jest-environment ./tests/XMLEnvironment.ts + * @xml ./tests/resources/GP_Temperature_v3.2.0_DCC.xml + */ + +import { select, toTextArr, toTextContentArr } from "../util"; +import { DCCDocument } from "../../src"; + +const base = "//dcc:quantity[@refType='test_noQuantity']/dcc:noQuantity"; +const xpath = { + noQuantity: { + name: { + content: `string(${base}/dcc:name/dcc:content)`, + }, + content: `string(${base}/dcc:content)`, + file: { + fileName: `string(${base}/dcc:file/dcc:fileName)`, + mimeType: `string(${base}/dcc:file/dcc:mimeType)`, + dataBase64: `string(${base}/dcc:file/dcc:dataBase64)`, + }, + formula: { + latex: `string(${base}/dcc:formula/dcc:latex)`, + }, + }, +}; + +describe("noQuantity", () => { + let dcc: DCCDocument, dom, result; + + beforeEach(() => { + ({ dcc, dom } = xmlEnv.recreateEnv()); + result = dcc.digitalCalibrationCertificate.measurementResults.measurementResult[0].results.result[0]; + }); + + test("should get correct name from XML", () => { + const expected = <Element[]>select(xpath.noQuantity.name.content, dom); + + expect(toTextArr(result.data.quantity[0].noQuantity.name.content)[0]).toBe(expected); + }); + + test("should get correct content from XML", () => { + expect(result.data.quantity[0].noQuantity.content[0]._text).toBe(select(xpath.noQuantity.content, dom)); + }); + + test("should get correct fileName from XML", () => { + expect(result.data.quantity[0].noQuantity.file[0].fileName._text).toBe(select(xpath.noQuantity.file.fileName, dom)); + }); + + test("should get correct mimeType from XML", () => { + expect(result.data.quantity[0].noQuantity.file[0].mimeType._text).toBe(select(xpath.noQuantity.file.mimeType, dom)); + }); + + test("should get correct latex formula from XML", () => { + expect(result.data.quantity[0].noQuantity.formula[0].latex._text).toBe(select(xpath.noQuantity.formula.latex, dom)); + }); +}); diff --git a/tests/XMLEnvironment.ts b/tests/XMLEnvironment.ts new file mode 100644 index 0000000..10160de --- /dev/null +++ b/tests/XMLEnvironment.ts @@ -0,0 +1,44 @@ +import * as fs from "fs/promises"; +import { DCCDocument } from "../src"; +import NodeEnvironment from "jest-environment-node"; +import { JSDOM } from "jsdom"; + +export default class XMLEnvironment extends NodeEnvironment { + xmlPath: string; + xml: string; + + constructor(config, context) { + super(config, context); + const xmlPath = context.docblockPragmas["xml"]; + if (xmlPath && typeof xmlPath === "string") { + this.xmlPath = xmlPath; + } + } + + async setup() { + await super.setup(); + if (this.xmlPath) { + this.xml = await this.readFile(this.xmlPath); + } + this.global.xmlEnv = this; + } + + recreateEnv(): { xml: string; dcc: DCCDocument; dom: JSDOM } { + return { + xml: this.xml, + dcc: this.xml ? DCCDocument.fromXml(this.xml) : DCCDocument.createEmpty(), + dom: new JSDOM(this.xml, { contentType: "application/xml" }), + }; + } + + async readFile(path: string) { + // check if file exists + if ((await fs.stat(path)).isFile()) { + return await fs.readFile(path, { encoding: "utf-8" }); + } else { + throw new Error(`File ${path} does not exist.`); + } + } +} + +export const TestEnvironment = XMLEnvironment; diff --git a/tests/index.d.ts b/tests/index.d.ts new file mode 100644 index 0000000..facbc06 --- /dev/null +++ b/tests/index.d.ts @@ -0,0 +1,12 @@ +import XMLEnvironment from "./XMLEnvironment"; + +declare let xmlEnv: XMLEnvironment; + +declare global { + let xmlEnv: XMLEnvironment; + namespace NodeJS { + interface Global { + xmlEnv: XMLEnvironment; + } + } +} diff --git a/tests/resources/GP_Temperature_Simplified.xml b/tests/resources/GP_Temperature_Simplified.xml new file mode 100644 index 0000000..7d299d4 --- /dev/null +++ b/tests/resources/GP_Temperature_Simplified.xml @@ -0,0 +1,352 @@ +<?xml version="1.0" encoding="utf-8"?> +<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcc="https://ptb.de/dcc" xmlns:si="https://ptb.de/si" xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.2.0/dcc.xsd" schemaVersion="3.2.0"> + <dcc:administrativeData> + <dcc:dccSoftware> + <dcc:software> + <dcc:name> + <dcc:content>Notepad++ (32-bit)</dcc:content> + </dcc:name> + <dcc:release>v 8.2</dcc:release> + </dcc:software> + </dcc:dccSoftware> + <dcc:coreData> + <dcc:countryCodeISO3166_1>DE</dcc:countryCodeISO3166_1> + <dcc:usedLangCodeISO639_1>en</dcc:usedLangCodeISO639_1> + <dcc:usedLangCodeISO639_1>de</dcc:usedLangCodeISO639_1> + <dcc:mandatoryLangCodeISO639_1>en</dcc:mandatoryLangCodeISO639_1> + <dcc:uniqueIdentifier>GP_DCC_temperature_minimal_1.2</dcc:uniqueIdentifier> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-coreData</dcc:value> + <dcc:name> + <dcc:content lang="de">Auftrags Nr.</dcc:content> + <dcc:content lang="en">Order no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + <dcc:beginPerformanceDate>1957-08-13</dcc:beginPerformanceDate> + <dcc:endPerformanceDate>1957-08-13</dcc:endPerformanceDate> + <dcc:performanceLocation>laboratory</dcc:performanceLocation> + </dcc:coreData> + <dcc:items> + <dcc:item> + <dcc:name> + <dcc:content lang="de">Temperatur-Fühler</dcc:content> + <dcc:content lang="en">Temperature sensor</dcc:content> + </dcc:name> + <dcc:manufacturer> + <dcc:name> + <dcc:content>String</dcc:content> + </dcc:name> + </dcc:manufacturer> + <dcc:model>String</dcc:model> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Serien Nr.</dcc:content> + <dcc:content lang="en">Serial no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>customer</dcc:issuer> + <dcc:value>string-customer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Messmittel Nr.</dcc:content> + <dcc:content lang="en">Measurement equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Equipment Nr.</dcc:content> + <dcc:content lang="en">Equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + </dcc:item> + </dcc:items> + <dcc:calibrationLaboratory> + <dcc:contact> + <dcc:name> + <dcc:content>Kalibrierfirma GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kalibrierfirma.xx</dcc:eMail> + <dcc:phone>+49 123 4567-89</dcc:phone> + <dcc:fax>+49 123 4567-90</dcc:fax> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:street>Musterstraße</dcc:street> + <dcc:streetNo>1</dcc:streetNo> + <dcc:further> + <dcc:content>www.kalibrierfirma.xx</dcc:content> + </dcc:further> + </dcc:location> + </dcc:contact> + </dcc:calibrationLaboratory> + <dcc:respPersons> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michaela Musterfrau</dcc:content> + </dcc:name> + </dcc:person> + <dcc:mainSigner>true</dcc:mainSigner> + </dcc:respPerson> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michael Mustermann</dcc:content> + </dcc:name> + </dcc:person> + </dcc:respPerson> + </dcc:respPersons> + <dcc:customer> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:further> + <dcc:content lang="de">Kunden Nr. 1024418</dcc:content> + <dcc:content lang="en">Customer ID no. 1024418</dcc:content> + </dcc:further> + </dcc:location> + </dcc:customer> + <dcc:statements> + <dcc:statement refType="basic_conformity"> + <dcc:declaration> + <dcc:content lang="de">Die Konformitätsaussage erfolgt anhand der Vorgaben des Kunden. Sie sind im DCC mit aufgeführt.</dcc:content> + <dcc:content lang="en">The conformity statement is made on the basis of the customer's specifications. They are listed in the DCC.</dcc:content> + </dcc:declaration> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + <dcc:conformity>pass</dcc:conformity> + </dcc:statement> + <dcc:statement refType="basic_recalibration"> + <dcc:declaration> + <dcc:content lang="de">Datum, wann nach der Festlegung durch den Kunden spätestens der Kalibriergegenstand rekalibriert werden soll:</dcc:content> + <dcc:content lang="en">Date when the calibration item is to be recalibrated at the latest according to the customer's specification:</dcc:content> + </dcc:declaration> + <dcc:date>1959-10-22</dcc:date> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + </dcc:statement> + </dcc:statements> + </dcc:administrativeData> + <dcc:measurementResults> + <dcc:measurementResult> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measurement results</dcc:content> + </dcc:name> + <dcc:usedMethods> + <dcc:usedMethod refType="gp_temperatureSensor"> + <dcc:name> + <dcc:content lang="de">Kalibrierung von Temperaturmessfühlern</dcc:content> + <dcc:content lang="en">Calibration of temperature sensors</dcc:content> + </dcc:name> + </dcc:usedMethod> + </dcc:usedMethods> + <dcc:measuringEquipments> + <dcc:measuringEquipment refType="basic_normalUsed"> + <dcc:name> + <dcc:content lang="de">Pt 100 Widerstandsthermometer</dcc:content> + <dcc:content lang="en">Pt 100 thermometer</dcc:content> + </dcc:name> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-measuringEquipment-1</dcc:value> + </dcc:identification> + </dcc:identifications> + </dcc:measuringEquipment> + </dcc:measuringEquipments> + <dcc:influenceConditions> + <dcc:influenceCondition refType="basic_temperature"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung Temperatur</dcc:content> + <dcc:content lang="en">Ambient condition temperature</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_temperatureMin"> + <dcc:name> + <dcc:content lang="de">Temperatur min</dcc:content> + <dcc:content lang="en">temperature min</dcc:content> + </dcc:name> + <si:real> + <si:value>293</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_temperatureMax"> + <dcc:name> + <dcc:content lang="de">Temperatur max</dcc:content> + <dcc:content lang="en">temperature max</dcc:content> + </dcc:name> + <si:real> + <si:value>299</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + <dcc:influenceCondition refType="basic_humidityRelative"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung relative Luftfeuchte</dcc:content> + <dcc:content lang="en">Ambient condition relative humidity</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_humidityRelativeMin"> + <dcc:name> + <dcc:content lang="de">Feuchte min</dcc:content> + <dcc:content lang="en">humidity min</dcc:content> + </dcc:name> + <si:real> + <si:value>0.20</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_humidityRelativeMax"> + <dcc:name> + <dcc:content lang="de">Feuchte max</dcc:content> + <dcc:content lang="en">humidity max</dcc:content> + </dcc:name> + <si:real> + <si:value>0.70</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + </dcc:influenceConditions> + <dcc:results> + <dcc:result refType="gp_measuringResult1"> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measuring results</dcc:content> + </dcc:name> + <dcc:data> + <dcc:list refType="gp_table1"> + <dcc:quantity refType="basic_referenceValue"> + <dcc:name> + <dcc:content lang="de">Bezugswert</dcc:content> + <dcc:content lang="en">Reference value</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.098 99.971 175.103 250.169 320.004</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="basic_measuredValue"> + <dcc:name> + <dcc:content lang="de">Angezeigter Messwert Kalibriergegenstand</dcc:content> + <dcc:content lang="en">Indicated measured value probe</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.32 373.21 448.36 523.31 593.07</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.17 100.06 175.21 250.16 319.92</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="basic_measurementError"> + <dcc:name> + <dcc:content lang="de">Messabweichung</dcc:content> + <dcc:content lang="en">Measurement error</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.072 0.089 0.107 -0.009 -0.084</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + <si:expandedUncXMLList> + <si:uncertaintyXMLList>0.061</si:uncertaintyXMLList> + <si:coverageFactorXMLList>2</si:coverageFactorXMLList> + <si:coverageProbabilityXMLList>0.95</si:coverageProbabilityXMLList> + <si:distributionXMLList>normal</si:distributionXMLList> + </si:expandedUncXMLList> + </si:realListXMLList> + <dcc:measurementMetaData> + <dcc:metaData refType="basic_conformity"> + <dcc:declaration> + <dcc:name> + <dcc:content lang="de">Konformität</dcc:content> + <dcc:content lang="en">Conformity</dcc:content> + </dcc:name> + </dcc:declaration> + <dcc:conformityXMLList>pass</dcc:conformityXMLList> + <dcc:data> + <dcc:quantity refType="basic_acceptanceLimitLower"> + <dcc:name> + <dcc:content lang="de">Unteres Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Lower acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>-0.23 -0.23 -0.23 -0.30 -0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + <dcc:quantity refType="basic_acceptanceLimitUpper"> + <dcc:name> + <dcc:content lang="de">Oberes Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Upper acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.23 0.23 0.23 0.30 0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + </dcc:data> + </dcc:metaData> + </dcc:measurementMetaData> + </dcc:quantity> + </dcc:list> + </dcc:data> + </dcc:result> + </dcc:results> + </dcc:measurementResult> + </dcc:measurementResults> +</dcc:digitalCalibrationCertificate> \ No newline at end of file diff --git a/tests/resources/GP_Temperature_Simplified_variant.xml b/tests/resources/GP_Temperature_Simplified_variant.xml new file mode 100644 index 0000000..6001e42 --- /dev/null +++ b/tests/resources/GP_Temperature_Simplified_variant.xml @@ -0,0 +1,365 @@ +<?xml version="1.0" encoding="utf-8"?> +<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcc="https://ptb.de/dcc" xmlns:si="https://ptb.de/si" xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.2.0/dcc.xsd" schemaVersion="3.2.0"> + <dcc:administrativeData> + <dcc:dccSoftware> + <dcc:software> + <dcc:name> + <dcc:content>Notepad++ (32-bit)</dcc:content> + </dcc:name> + <dcc:release>v 8.2</dcc:release> + </dcc:software> + </dcc:dccSoftware> + <dcc:coreData> + <dcc:countryCodeISO3166_1>DE</dcc:countryCodeISO3166_1> + <dcc:usedLangCodeISO639_1>en</dcc:usedLangCodeISO639_1> + <dcc:usedLangCodeISO639_1>de</dcc:usedLangCodeISO639_1> + <dcc:mandatoryLangCodeISO639_1>en</dcc:mandatoryLangCodeISO639_1> + <dcc:uniqueIdentifier>GP_DCC_temperature_minimal_1.2</dcc:uniqueIdentifier> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-coreData</dcc:value> + <dcc:name> + <dcc:content lang="de">Auftrags Nr.</dcc:content> + <dcc:content lang="en">Order no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + <dcc:beginPerformanceDate>1957-08-13</dcc:beginPerformanceDate> + <dcc:endPerformanceDate>1957-08-13</dcc:endPerformanceDate> + <dcc:performanceLocation>laboratory</dcc:performanceLocation> + </dcc:coreData> + <dcc:items> + <dcc:item> + <dcc:name> + <dcc:content lang="de">Temperatur-Fühler</dcc:content> + <dcc:content lang="en">Temperature sensor</dcc:content> + </dcc:name> + <dcc:equipmentClass> + <dcc:reference>1.2.3.4.5</dcc:reference> + <dcc:classID>12345</dcc:classID> + </dcc:equipmentClass> + <dcc:manufacturer> + <dcc:name> + <dcc:content>String</dcc:content> + </dcc:name> + </dcc:manufacturer> + <dcc:model>String</dcc:model> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Serien Nr.</dcc:content> + <dcc:content lang="en">Serial no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>customer</dcc:issuer> + <dcc:value>string-customer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Messmittel Nr.</dcc:content> + <dcc:content lang="en">Measurement equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Equipment Nr.</dcc:content> + <dcc:content lang="en">Equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + </dcc:item> + </dcc:items> + <dcc:calibrationLaboratory> + <dcc:contact> + <dcc:name> + <dcc:content>Kalibrierfirma GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kalibrierfirma.xx</dcc:eMail> + <dcc:phone>+49 123 4567-89</dcc:phone> + <dcc:fax>+49 123 4567-90</dcc:fax> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:street>Musterstraße</dcc:street> + <dcc:streetNo>1</dcc:streetNo> + <dcc:further> + <dcc:content>www.kalibrierfirma.xx</dcc:content> + </dcc:further> + </dcc:location> + </dcc:contact> + </dcc:calibrationLaboratory> + <dcc:respPersons> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michaela Musterfrau</dcc:content> + </dcc:name> + </dcc:person> + <dcc:mainSigner>true</dcc:mainSigner> + </dcc:respPerson> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michael Mustermann</dcc:content> + </dcc:name> + </dcc:person> + </dcc:respPerson> + </dcc:respPersons> + <dcc:customer> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:further> + <dcc:content lang="de">Kunden Nr. 1024418</dcc:content> + <dcc:content lang="en">Customer ID no. 1024418</dcc:content> + </dcc:further> + </dcc:location> + </dcc:customer> + <dcc:statements> + <dcc:statement refType="basic_conformity"> + <dcc:declaration> + <dcc:content lang="de">Die Konformitätsaussage erfolgt anhand der Vorgaben des Kunden. Sie sind im DCC mit aufgeführt.</dcc:content> + <dcc:content lang="en">The conformity statement is made on the basis of the customer's specifications. They are listed in the DCC.</dcc:content> + </dcc:declaration> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + <dcc:conformity>pass</dcc:conformity> + </dcc:statement> + <dcc:statement refType="basic_recalibration"> + <dcc:declaration> + <dcc:content lang="de">Datum, wann nach der Festlegung durch den Kunden spätestens der Kalibriergegenstand rekalibriert werden soll:</dcc:content> + <dcc:content lang="en">Date when the calibration item is to be recalibrated at the latest according to the customer's specification:</dcc:content> + </dcc:declaration> + <dcc:date>1959-10-22</dcc:date> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + </dcc:statement> + <dcc:statement> + <dcc:countryCodeISO3166_1>DE</dcc:countryCodeISO3166_1> + <dcc:countryCodeISO3166_1>US</dcc:countryCodeISO3166_1> + <dcc:convention>abcde</dcc:convention> + <dcc:traceable>true</dcc:traceable> + <dcc:period>P1Y2M3DT10H30M</dcc:period> + <dcc:nonSIDefinition>abcde_definition</dcc:nonSIDefinition> + <dcc:nonSIUnit>abcde_unit</dcc:nonSIUnit> + </dcc:statement> + </dcc:statements> + </dcc:administrativeData> + <dcc:measurementResults> + <dcc:measurementResult> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measurement results</dcc:content> + </dcc:name> + <dcc:usedMethods> + <dcc:usedMethod refType="gp_temperatureSensor"> + <dcc:name> + <dcc:content lang="de">Kalibrierung von Temperaturmessfühlern</dcc:content> + <dcc:content lang="en">Calibration of temperature sensors</dcc:content> + </dcc:name> + </dcc:usedMethod> + </dcc:usedMethods> + <dcc:measuringEquipments> + <dcc:measuringEquipment refType="basic_normalUsed"> + <dcc:name> + <dcc:content lang="de">Pt 100 Widerstandsthermometer</dcc:content> + <dcc:content lang="en">Pt 100 thermometer</dcc:content> + </dcc:name> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-measuringEquipment-1</dcc:value> + </dcc:identification> + </dcc:identifications> + </dcc:measuringEquipment> + </dcc:measuringEquipments> + <dcc:influenceConditions> + <dcc:influenceCondition refType="basic_temperature"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung Temperatur</dcc:content> + <dcc:content lang="en">Ambient condition temperature</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_temperatureMin"> + <dcc:name> + <dcc:content lang="de">Temperatur min</dcc:content> + <dcc:content lang="en">temperature min</dcc:content> + </dcc:name> + <si:real> + <si:value>293</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_temperatureMax"> + <dcc:name> + <dcc:content lang="de">Temperatur max</dcc:content> + <dcc:content lang="en">temperature max</dcc:content> + </dcc:name> + <si:real> + <si:value>299</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + <dcc:influenceCondition refType="basic_humidityRelative"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung relative Luftfeuchte</dcc:content> + <dcc:content lang="en">Ambient condition relative humidity</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_humidityRelativeMin"> + <dcc:name> + <dcc:content lang="de">Feuchte min</dcc:content> + <dcc:content lang="en">humidity min</dcc:content> + </dcc:name> + <si:real> + <si:value>0.20</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_humidityRelativeMax"> + <dcc:name> + <dcc:content lang="de">Feuchte max</dcc:content> + <dcc:content lang="en">humidity max</dcc:content> + </dcc:name> + <si:real> + <si:value>0.70</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + </dcc:influenceConditions> + <dcc:results> + <dcc:result refType="gp_measuringResult1"> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measuring results</dcc:content> + </dcc:name> + <dcc:data> + <dcc:list refType="gp_table1"> + <dcc:quantity refType="basic_referenceValue"> + <dcc:name> + <dcc:content lang="de">Bezugswert</dcc:content> + <dcc:content lang="en">Reference value</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.098 99.971 175.103 250.169 320.004</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="basic_measuredValue"> + <dcc:name> + <dcc:content lang="de">Angezeigter Messwert Kalibriergegenstand</dcc:content> + <dcc:content lang="en">Indicated measured value probe</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.32 373.21 448.36 523.31 593.07</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.17 100.06 175.21 250.16 319.92</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="basic_measurementError"> + <dcc:name> + <dcc:content lang="de">Messabweichung</dcc:content> + <dcc:content lang="en">Measurement error</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.072 0.089 0.107 -0.009 -0.084</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + <si:expandedUncXMLList> + <si:uncertaintyXMLList>0.061</si:uncertaintyXMLList> + <si:coverageFactorXMLList>2</si:coverageFactorXMLList> + <si:coverageProbabilityXMLList>0.95</si:coverageProbabilityXMLList> + <si:distributionXMLList>normal</si:distributionXMLList> + </si:expandedUncXMLList> + </si:realListXMLList> + <dcc:measurementMetaData> + <dcc:metaData refType="basic_conformity"> + <dcc:declaration> + <dcc:name> + <dcc:content lang="de">Konformität</dcc:content> + <dcc:content lang="en">Conformity</dcc:content> + </dcc:name> + </dcc:declaration> + <dcc:conformityXMLList>pass</dcc:conformityXMLList> + <dcc:data> + <dcc:quantity refType="basic_acceptanceLimitLower"> + <dcc:name> + <dcc:content lang="de">Unteres Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Lower acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>-0.23 -0.23 -0.23 -0.30 -0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + <dcc:quantity refType="basic_acceptanceLimitUpper"> + <dcc:name> + <dcc:content lang="de">Oberes Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Upper acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.23 0.23 0.23 0.30 0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + </dcc:data> + </dcc:metaData> + </dcc:measurementMetaData> + </dcc:quantity> + </dcc:list> + </dcc:data> + </dcc:result> + </dcc:results> + </dcc:measurementResult> + </dcc:measurementResults> +</dcc:digitalCalibrationCertificate> diff --git a/tests/resources/GP_Temperature_Typical.xml b/tests/resources/GP_Temperature_Typical.xml new file mode 100644 index 0000000..817bffb --- /dev/null +++ b/tests/resources/GP_Temperature_Typical.xml @@ -0,0 +1,441 @@ +<?xml version="1.0" encoding="utf-8"?> +<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcc="https://ptb.de/dcc" xmlns:si="https://ptb.de/si" xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.2.0/dcc.xsd" schemaVersion="3.2.0"> + <dcc:administrativeData> + <dcc:dccSoftware> + <dcc:software> + <dcc:name> + <dcc:content>Notepad++ (32-bit)</dcc:content> + </dcc:name> + <dcc:release>v 8.2</dcc:release> + </dcc:software> + </dcc:dccSoftware> + <dcc:coreData> + <dcc:countryCodeISO3166_1>DE</dcc:countryCodeISO3166_1> + <dcc:usedLangCodeISO639_1>en</dcc:usedLangCodeISO639_1> + <dcc:usedLangCodeISO639_1>de</dcc:usedLangCodeISO639_1> + <dcc:mandatoryLangCodeISO639_1>en</dcc:mandatoryLangCodeISO639_1> + <dcc:uniqueIdentifier>GP_DCC_temperature_typical_1.2</dcc:uniqueIdentifier> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-coreData</dcc:value> + <dcc:name> + <dcc:content lang="de">Auftrags Nr.</dcc:content> + <dcc:content lang="en">Order no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + <dcc:receiptDate>1957-08-13</dcc:receiptDate> + <dcc:beginPerformanceDate>1957-08-13</dcc:beginPerformanceDate> + <dcc:endPerformanceDate>1957-08-13</dcc:endPerformanceDate> + <dcc:performanceLocation>laboratory</dcc:performanceLocation> + </dcc:coreData> + <dcc:items> + <dcc:item> + <dcc:name> + <dcc:content lang="de">Temperatur-Fühler</dcc:content> + <dcc:content lang="en">Temperature sensor</dcc:content> + </dcc:name> + <dcc:manufacturer> + <dcc:name> + <dcc:content>String</dcc:content> + </dcc:name> + </dcc:manufacturer> + <dcc:model>String</dcc:model> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Serien Nr.</dcc:content> + <dcc:content lang="en">Serial no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>customer</dcc:issuer> + <dcc:value>string-customer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Messmittel Nr.</dcc:content> + <dcc:content lang="en">Measurement equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Equipment Nr.</dcc:content> + <dcc:content lang="en">Equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + </dcc:item> + </dcc:items> + <dcc:calibrationLaboratory> + <dcc:contact> + <dcc:name> + <dcc:content>Kalibrierfirma GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kalibrierfirma.xx</dcc:eMail> + <dcc:phone>+49 123 4567-89</dcc:phone> + <dcc:fax>+49 123 4567-90</dcc:fax> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:street>Musterstraße</dcc:street> + <dcc:streetNo>1</dcc:streetNo> + <dcc:further> + <dcc:content>www.kalibrierfirma.xx</dcc:content> + </dcc:further> + </dcc:location> + </dcc:contact> + </dcc:calibrationLaboratory> + <dcc:respPersons> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michaela Musterfrau</dcc:content> + </dcc:name> + </dcc:person> + <dcc:mainSigner>true</dcc:mainSigner> + </dcc:respPerson> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michael Mustermann</dcc:content> + </dcc:name> + </dcc:person> + </dcc:respPerson> + </dcc:respPersons> + <dcc:customer> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:further> + <dcc:content lang="de">Kunden Nr. 1024418</dcc:content> + <dcc:content lang="en">Customer ID no. 1024418</dcc:content> + </dcc:further> + </dcc:location> + </dcc:customer> + <dcc:statements> + <dcc:statement> + <dcc:norm>ISO/IEC 17025:2018-03</dcc:norm> + <dcc:reference>7.8.4.3</dcc:reference> + <dcc:declaration> + <dcc:content lang="de">Die Ergebnisse gelten zum Zeitpunkt der Kalibrierung. Es obliegt dem Antragsteller, zu gegebener Zeit eine Rekalibrierung zu veranlassen.</dcc:content> + <dcc:content lang="en">The results refer only to the object calibrated in this DCC. The measurement results are valid at the time of calibration. The applicant is responsible for arranging a recalibration in due time.</dcc:content> + </dcc:declaration> + </dcc:statement> + <dcc:statement refType="basic_validityRange"> + <dcc:declaration> + <dcc:content lang="de">Angabe des Temperaturbereichs, in dem kalibriert wurde:</dcc:content> + <dcc:content lang="en">Specification of the temperature range in which calibration was performed:</dcc:content> + </dcc:declaration> + <dcc:data> + <dcc:quantity refType="basic_validityRangeMin"> + <dcc:name> + <dcc:content lang="de">Unteres Limit</dcc:content> + <dcc:content lang="en">Lower limit</dcc:content> + </dcc:name> + <si:real> + <si:value>306</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_validityRangeMax"> + <dcc:name> + <dcc:content lang="de">Oberes Limit</dcc:content> + <dcc:content lang="en">Upper limit</dcc:content> + </dcc:name> + <si:real> + <si:value>593</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:statement> + <dcc:statement refType="basic_conformity"> + <dcc:declaration> + <dcc:content lang="de">Die Konformitätsaussage erfolgt anhand der Vorgaben des Kunden. Sie sind im DCC mit aufgeführt.</dcc:content> + <dcc:content lang="en">The conformity statement is made on the basis of the customer's specifications. They are listed in the DCC.</dcc:content> + </dcc:declaration> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + <dcc:conformity>pass</dcc:conformity> + </dcc:statement> + <dcc:statement refType="basic_recalibration"> + <dcc:declaration> + <dcc:content lang="de">Datum, wann nach der Festlegung durch den Kunden spätestens der Kalibriergegenstand rekalibriert werden soll:</dcc:content> + <dcc:content lang="en">Date when the calibration item is to be recalibrated at the latest according to the customer's specification:</dcc:content> + </dcc:declaration> + <dcc:date>1959-10-22</dcc:date> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + </dcc:statement> + </dcc:statements> + </dcc:administrativeData> + <dcc:measurementResults> + <dcc:measurementResult> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measurement results</dcc:content> + </dcc:name> + <dcc:usedMethods> + <dcc:usedMethod refType="basic_uncertainty"> + <dcc:name> + <dcc:content lang="de">Erweiterte Messunsicherheit</dcc:content> + <dcc:content lang="en">Expanded uncertainty</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Angegeben ist die erweiterte Messunsicherheit, die sich aus der Standardmessunsicherheit durch Multiplikation mit dem Erweiterungsfaktor k=2 ergibt. Sie wurde gemäß dem „Guide to the Expression of Uncertainty in Measurement (GUM)“ ermittelt. Der Wert der Messgröße liegt dann im Regelfall mit einer Wahrscheinlichkeit von annähernd 95 % im zugeordneten Überdeckungsintervall.</dcc:content> + <dcc:content lang="en">The expanded uncertainty was calculated from the contributions of uncertainty originating from the standards used, from the weighings and the air buoyancy corrections. The reported uncertainty does not include an estimate of long-term variations.</dcc:content> + </dcc:description> + <dcc:norm>GUM</dcc:norm> + </dcc:usedMethod> + <dcc:usedMethod refType="gp_temperatureSensor"> + <dcc:name> + <dcc:content lang="de">Kalibrierung von Temperaturmessfühlern</dcc:content> + <dcc:content lang="en">Calibration of temperature sensors</dcc:content> + </dcc:name> + <dcc:norm>DKD-R 5-1:2018</dcc:norm> + </dcc:usedMethod> + </dcc:usedMethods> + <dcc:measuringEquipments> + <dcc:measuringEquipment refType="basic_normalUsed"> + <dcc:name> + <dcc:content lang="de">Pt 100 Widerstandsthermometer</dcc:content> + <dcc:content lang="en">Pt 100 thermometer</dcc:content> + </dcc:name> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-measuringEquipment-1</dcc:value> + </dcc:identification> + </dcc:identifications> + </dcc:measuringEquipment> + </dcc:measuringEquipments> + <dcc:influenceConditions> + <dcc:influenceCondition refType="gp_immersionDepth"> + <dcc:name> + <dcc:content lang="de">Eintauchtiefe im Wasserbad</dcc:content> + <dcc:content lang="en">Immersion depth in water bath</dcc:content> + </dcc:name> + <dcc:data> + <dcc:quantity> + <dcc:name> + <dcc:content lang="de">Eintauchtiefe</dcc:content> + <dcc:content lang="en">Immersion depth</dcc:content> + </dcc:name> + <si:real> + <si:value>0.1</si:value> + <si:unit>\metre</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + <dcc:influenceCondition refType="basic_temperature"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung Temperatur</dcc:content> + <dcc:content lang="en">Ambient condition temperature</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_temperatureMin"> + <dcc:name> + <dcc:content lang="de">Temperatur min</dcc:content> + <dcc:content lang="en">temperature min</dcc:content> + </dcc:name> + <si:real> + <si:value>293</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_temperatureMax"> + <dcc:name> + <dcc:content lang="de">Temperatur max</dcc:content> + <dcc:content lang="en">temperature max</dcc:content> + </dcc:name> + <si:real> + <si:value>299</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + <dcc:influenceCondition refType="basic_humidityRelative"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung relative Luftfeuchte</dcc:content> + <dcc:content lang="en">Ambient condition relative humidity</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_humidityRelativeMin"> + <dcc:name> + <dcc:content lang="de">Feuchte min</dcc:content> + <dcc:content lang="en">humidity min</dcc:content> + </dcc:name> + <si:real> + <si:value>0.20</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_humidityRelativeMax"> + <dcc:name> + <dcc:content lang="de">Feuchte max</dcc:content> + <dcc:content lang="en">humidity max</dcc:content> + </dcc:name> + <si:real> + <si:value>0.70</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + </dcc:influenceConditions> + <dcc:results> + <dcc:result refType="gp_measuringResult1"> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measuring results</dcc:content> + </dcc:name> + <dcc:data> + <dcc:list refType="gp_table1"> + <dcc:quantity refType="basic_referenceValue"> + <dcc:name> + <dcc:content lang="de">Bezugswert</dcc:content> + <dcc:content lang="en">Reference value</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.098 99.971 175.103 250.169 320.004</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + <dcc:measurementMetaData> + <dcc:metaData refType="basic_calibrationValue"> + <dcc:declaration> + <dcc:content lang="de">Kalibrierpunkt</dcc:content> + <dcc:content lang="en">Calibration value</dcc:content> + </dcc:declaration> + <dcc:data> + <dcc:quantity> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306 373 448 523 593</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>32.85 99.85 174.85 249.85 319.85</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + </dcc:data> + </dcc:metaData> + </dcc:measurementMetaData> + </dcc:quantity> + <dcc:quantity refType="basic_measuredValue"> + <dcc:name> + <dcc:content lang="de">Angezeigter Messwert Kalibriergegenstand</dcc:content> + <dcc:content lang="en">Indicated measured value probe</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.32 373.21 448.36 523.31 593.07</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.17 100.06 175.21 250.16 319.92</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="basic_measurementError"> + <dcc:name> + <dcc:content lang="de">Messabweichung</dcc:content> + <dcc:content lang="en">Measurement error</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.072 0.089 0.107 -0.009 -0.084</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + <si:expandedUncXMLList> + <si:uncertaintyXMLList>0.061</si:uncertaintyXMLList> + <si:coverageFactorXMLList>2</si:coverageFactorXMLList> + <si:coverageProbabilityXMLList>0.95</si:coverageProbabilityXMLList> + <si:distributionXMLList>normal</si:distributionXMLList> + </si:expandedUncXMLList> + </si:realListXMLList> + <dcc:measurementMetaData> + <dcc:metaData refType="basic_conformity"> + <dcc:declaration> + <dcc:name> + <dcc:content lang="de">Konformität</dcc:content> + <dcc:content lang="en">Conformity</dcc:content> + </dcc:name> + </dcc:declaration> + <dcc:conformityXMLList>pass</dcc:conformityXMLList> + <dcc:data> + <dcc:quantity refType="basic_acceptanceLimitLower"> + <dcc:name> + <dcc:content lang="de">Unteres Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Lower acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>-0.23 -0.23 -0.23 -0.30 -0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + <dcc:quantity refType="basic_acceptanceLimitUpper"> + <dcc:name> + <dcc:content lang="de">Oberes Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Upper acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.23 0.23 0.23 0.30 0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + </dcc:data> + </dcc:metaData> + </dcc:measurementMetaData> + </dcc:quantity> + </dcc:list> + </dcc:data> + </dcc:result> + </dcc:results> + </dcc:measurementResult> + </dcc:measurementResults> +</dcc:digitalCalibrationCertificate> \ No newline at end of file diff --git a/tests/resources/GP_Temperature_v3.2.0_DCC.xml b/tests/resources/GP_Temperature_v3.2.0_DCC.xml new file mode 100644 index 0000000..6cf833b --- /dev/null +++ b/tests/resources/GP_Temperature_v3.2.0_DCC.xml @@ -0,0 +1,540 @@ +<?xml version="1.0" encoding="UTF-8"?> +<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcc="https://ptb.de/dcc" xmlns:si="https://ptb.de/si" xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.2.0/dcc.xsd" schemaVersion="3.2.0"> + <dcc:administrativeData> + <dcc:dccSoftware> + <dcc:software> + <dcc:name> + <dcc:content>Notepad++ (32-bit)</dcc:content> + </dcc:name> + <dcc:release>v 8.2</dcc:release> + <dcc:type>application</dcc:type> + <dcc:description> + <dcc:name> + <dcc:content>Open source text editor</dcc:content> + </dcc:name> + <dcc:content>https://notepad-plus-plus.org/downloads/</dcc:content> + </dcc:description> + </dcc:software> + </dcc:dccSoftware> + <dcc:refTypeDefinitions> + <dcc:refTypeDefinition> + <dcc:name> + <dcc:content>Cross-Community refType Definition</dcc:content> + </dcc:name> + <dcc:description> + <dcc:name> + <dcc:content>Description name ABC</dcc:content> + </dcc:name> + <dcc:content>Description ABC</dcc:content> + </dcc:description> + <dcc:namespace>basic</dcc:namespace> + <dcc:link>https://www.ptb.de/dcc/refType/basic/draft_basic.xml</dcc:link> + <dcc:release>0.1</dcc:release> + <dcc:value>Value ABC</dcc:value> + <dcc:procedure>Procedure ABC</dcc:procedure> + </dcc:refTypeDefinition> + </dcc:refTypeDefinitions> + <dcc:coreData> + <dcc:countryCodeISO3166_1>DE</dcc:countryCodeISO3166_1> + <dcc:usedLangCodeISO639_1>en</dcc:usedLangCodeISO639_1> + <dcc:usedLangCodeISO639_1>de</dcc:usedLangCodeISO639_1> + <dcc:mandatoryLangCodeISO639_1>en</dcc:mandatoryLangCodeISO639_1> + <dcc:uniqueIdentifier>GP_DCC_temperature_minimal_1.1_Complete</dcc:uniqueIdentifier> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-coreData</dcc:value> + <dcc:name> + <dcc:content lang="de">Auftrags Nr.</dcc:content> + <dcc:content lang="en">Order no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + <dcc:receiptDate>1957-08-13</dcc:receiptDate> + <dcc:beginPerformanceDate>1957-08-13</dcc:beginPerformanceDate> + <dcc:endPerformanceDate>1957-08-13</dcc:endPerformanceDate> + <dcc:performanceLocation>laboratory</dcc:performanceLocation> + <dcc:issueDate>2022-12-31</dcc:issueDate> + <!-- TODO: dcc:previousReport --> + </dcc:coreData> + <dcc:items> + <dcc:item refType="test_items"> + <dcc:name> + <dcc:content lang="de">Temperatur-Fühler</dcc:content> + <dcc:content lang="en">Temperature sensor</dcc:content> + </dcc:name> + <dcc:manufacturer> + <dcc:name> + <dcc:content>String</dcc:content> + </dcc:name> + </dcc:manufacturer> + <dcc:model>String</dcc:model> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Serien Nr.</dcc:content> + <dcc:content lang="en">Serial no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>customer</dcc:issuer> + <dcc:value>string-customer-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Messmittel Nr.</dcc:content> + <dcc:content lang="en">Measurement equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-item</dcc:value> + <dcc:name> + <dcc:content lang="de">Equipment Nr.</dcc:content> + <dcc:content lang="en">Equipment no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + <dcc:itemQuantities> + <dcc:itemQuantity> + <dcc:name> + <dcc:content lang="de">Name der ItemQuantity</dcc:content> + <dcc:content lang="en">Name of the item quantity</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content>Membrandurchmesser</dcc:content> + </dcc:description> + <si:real> + <si:value>0.05</si:value> + <si:unit>\metre</si:unit> + </si:real> + </dcc:itemQuantity> + <dcc:itemQuantity> + <dcc:description> + <dcc:content>Membranstärke</dcc:content> + </dcc:description> + <si:real> + <si:value>0.0003</si:value> + <si:unit>\metre</si:unit> + </si:real> + </dcc:itemQuantity> + </dcc:itemQuantities> + </dcc:item> + </dcc:items> + <dcc:calibrationLaboratory> + <dcc:contact> + <dcc:name> + <dcc:content>Kalibrierfirma GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kalibrierfirma.xx</dcc:eMail> + <dcc:phone>+49 123 4567-89</dcc:phone> + <dcc:fax>+49 123 4567-90</dcc:fax> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:street>Musterstraße</dcc:street> + <dcc:streetNo>1</dcc:streetNo> + <dcc:further> + <dcc:content>www.kalibrierfirma.xx</dcc:content> + </dcc:further> + </dcc:location> + </dcc:contact> + <dcc:cryptElectronicSeal>true</dcc:cryptElectronicSeal> + <dcc:cryptElectronicSignature>false</dcc:cryptElectronicSignature> + <dcc:cryptElectronicTimeStamp>true</dcc:cryptElectronicTimeStamp> + </dcc:calibrationLaboratory> + <dcc:respPersons> + <dcc:respPerson refType="test_respPerson"> + <dcc:person> + <dcc:name> + <dcc:content>Michaela Musterfrau</dcc:content> + </dcc:name> + </dcc:person> + <dcc:mainSigner>true</dcc:mainSigner> + </dcc:respPerson> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michael Mustermann</dcc:content> + </dcc:name> + </dcc:person> + </dcc:respPerson> + </dcc:respPersons> + <dcc:customer> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + <dcc:further> + <dcc:content lang="de">Kunden Nr. 1024418</dcc:content> + <dcc:content lang="en">Customer ID no. 1024418</dcc:content> + </dcc:further> + </dcc:location> + </dcc:customer> + <dcc:statements> + <dcc:statement refType="basic_conformity"> + <dcc:name> + <dcc:content lang="de">Name der Konformitätsaussage</dcc:content> + <dcc:content lang="en">Name of conformity statement</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Beschreibung der Konformitätsaussage</dcc:content> + <dcc:content lang="en">Description of conformity statement</dcc:content> + </dcc:description> + <dcc:declaration> + <dcc:content lang="de">Die Konformitätsaussage erfolgt anhand der Vorgaben des Kunden. Sie sind im DCC mit aufgeführt.</dcc:content> + <dcc:content lang="en">The conformity statement is made on the basis of the customer's specifications. They are listed in the DCC.</dcc:content> + </dcc:declaration> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + <dcc:conformity>pass</dcc:conformity> + <dcc:data> + <dcc:quantity> + <dcc:name> + <dcc:content lang="de">Übertragungskoeffizient Phasenverschiebung</dcc:content> + <dcc:content lang="en">en</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>-0.02 -0.03 -0.02 -0.02 -0.01</si:valueXMLList> + <si:unitXMLList>\degree</si:unitXMLList> + <si:expandedUncXMLList> + <si:uncertaintyXMLList>0.3 0.3 0.3 0.3 0.3</si:uncertaintyXMLList> + <si:coverageFactorXMLList>2</si:coverageFactorXMLList> + <si:coverageProbabilityXMLList>0.95</si:coverageProbabilityXMLList> + <si:distributionXMLList>normal</si:distributionXMLList> + </si:expandedUncXMLList> + </si:realListXMLList> + <dcc:measurementMetaData> + <dcc:metaData> + <dcc:declaration> + <dcc:content lang="de">Kommentar ist gültig für den dritten Eintrag.</dcc:content> + </dcc:declaration> + <dcc:validXMLList>false false true false false</dcc:validXMLList> + </dcc:metaData> + </dcc:measurementMetaData> + </dcc:quantity> + </dcc:data> + </dcc:statement> + <dcc:statement refType="basic_recalibration"> + <dcc:declaration> + <dcc:content lang="de">Datum, wann nach der Festlegung durch den Kunden spätestens der Kalibriergegenstand rekalibriert werden soll:</dcc:content> + <dcc:content lang="en">Date when the calibration item is to be recalibrated at the latest according to the customer's specification:</dcc:content> + </dcc:declaration> + <dcc:date>1959-10-22</dcc:date> + <dcc:respAuthority> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:eMail>info@kunde.xx</dcc:eMail> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + <dcc:countryCode>DE</dcc:countryCode> + <dcc:postCode>00900</dcc:postCode> + </dcc:location> + </dcc:respAuthority> + </dcc:statement> + </dcc:statements> + </dcc:administrativeData> + <dcc:measurementResults> + <dcc:measurementResult> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measurement results</dcc:content> + </dcc:name> + <dcc:usedMethods> + <dcc:usedMethod refType="gp_temperatureSensor"> + <dcc:name> + <dcc:content lang="de">Kalibrierung von Temperaturmessfühlern</dcc:content> + <dcc:content lang="en">Calibration of temperature sensors</dcc:content> + </dcc:name> + </dcc:usedMethod> + </dcc:usedMethods> + <dcc:measuringEquipments> + <dcc:measuringEquipment refType="basic_normalUsed"> + <dcc:name> + <dcc:content lang="de">Pt 100 Widerstandsthermometer</dcc:content> + <dcc:content lang="en">Pt 100 thermometer</dcc:content> + </dcc:name> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-measuringEquipment-1</dcc:value> + </dcc:identification> + </dcc:identifications> + </dcc:measuringEquipment> + </dcc:measuringEquipments> + <dcc:influenceConditions> + <dcc:influenceCondition refType="basic_temperature"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung Temperatur</dcc:content> + <dcc:content lang="en">Ambient condition temperature</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_temperatureMin"> + <dcc:name> + <dcc:content lang="de">Temperatur min</dcc:content> + <dcc:content lang="en">temperature min</dcc:content> + </dcc:name> + <si:real> + <si:value>293</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_temperatureMax"> + <dcc:name> + <dcc:content lang="de">Temperatur max</dcc:content> + <dcc:content lang="en">temperature max</dcc:content> + </dcc:name> + <si:real> + <si:value>299</si:value> + <si:unit>\kelvin</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + <dcc:influenceCondition refType="basic_humidityRelative"> + <dcc:name> + <dcc:content lang="de">Umgebungsbedingung relative Luftfeuchte</dcc:content> + <dcc:content lang="en">Ambient condition relative humidity</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Diese Werte wurden nicht gemessen, sondern wurden anhand der typischen Wetterbedingungen zu einer Jahreszeit angegeben. [^1]</dcc:content> + <dcc:content lang="en">These values were not measured, but were given based on typical weather conditions at a time of year. [^1]</dcc:content> + </dcc:description> + <dcc:data> + <dcc:quantity refType="basic_humidityRelativeMin"> + <dcc:name> + <dcc:content lang="de">Feuchte min</dcc:content> + <dcc:content lang="en">humidity min</dcc:content> + </dcc:name> + <si:real> + <si:value>0.20</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + <dcc:quantity refType="basic_humidityRelativeMax"> + <dcc:name> + <dcc:content lang="de">Feuchte max</dcc:content> + <dcc:content lang="en">humidity max</dcc:content> + </dcc:name> + <si:real> + <si:value>0.70</si:value> + <si:unit>\one</si:unit> + </si:real> + </dcc:quantity> + </dcc:data> + </dcc:influenceCondition> + </dcc:influenceConditions> + <dcc:results> + <dcc:result refType="gp_measuringResult1"> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measuring results</dcc:content> + </dcc:name> + <dcc:data> + <dcc:list refType="gp_table1"> + <dcc:quantity refType="basic_referenceValue"> + <dcc:name> + <dcc:content lang="de">Bezugswert</dcc:content> + <dcc:content lang="en">Reference value</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.098 99.971 175.103 250.169 320.004</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="basic_measuredValue"> + <dcc:name> + <dcc:content lang="de">Angezeigter Messwert Kalibriergegenstand</dcc:content> + <dcc:content lang="en">Indicated measured value probe</dcc:content> + </dcc:name> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.32 373.21 448.36 523.31 593.07</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.17 100.06 175.21 250.16 319.92</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="basic_measurementError"> + <dcc:name> + <dcc:content lang="de">Messabweichung</dcc:content> + <dcc:content lang="en">Measurement error</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.072 0.089 0.107 -0.009 -0.084</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + <si:expandedUncXMLList> + <si:uncertaintyXMLList>0.061</si:uncertaintyXMLList> + <si:coverageFactorXMLList>2</si:coverageFactorXMLList> + <si:coverageProbabilityXMLList>0.95</si:coverageProbabilityXMLList> + <si:distributionXMLList>normal</si:distributionXMLList> + </si:expandedUncXMLList> + </si:realListXMLList> + <dcc:measurementMetaData> + <dcc:metaData refType="basic_conformity"> + <dcc:name> + <dcc:content lang="de">Metadaten 1</dcc:content> + <dcc:content lang="en">Meta data 1</dcc:content> + </dcc:name> + <dcc:description> + <dcc:content lang="de">Beschreibung der Metadaten 1</dcc:content> + <dcc:content lang="en">Description of Meta data 1</dcc:content> + </dcc:description> + <dcc:declaration> + <dcc:name> + <dcc:content lang="de">Konformität</dcc:content> + <dcc:content lang="en">Conformity</dcc:content> + </dcc:name> + </dcc:declaration> + <dcc:conformityXMLList>pass</dcc:conformityXMLList> + <dcc:data> + <dcc:quantity refType="basic_acceptanceLimitLower"> + <dcc:name> + <dcc:content lang="de">Unteres Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Lower acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>-0.23 -0.23 -0.23 -0.30 -0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + <dcc:quantity refType="basic_acceptanceLimitUpper"> + <dcc:name> + <dcc:content lang="de">Oberes Akzeptanzlimit</dcc:content> + <dcc:content lang="en">Upper acceptance limit</dcc:content> + </dcc:name> + <si:realListXMLList> + <si:valueXMLList>0.23 0.23 0.23 0.30 0.30</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + </dcc:quantity> + </dcc:data> + </dcc:metaData> + </dcc:measurementMetaData> + </dcc:quantity> + </dcc:list> + <dcc:quantity refType="test_noQuantity"> + <dcc:noQuantity> + <dcc:name> + <dcc:content>Example name</dcc:content> + </dcc:name> + <dcc:content>Example text</dcc:content> + <dcc:file refType="examplePicture"> + <dcc:fileName>examplePicture.png</dcc:fileName> + <dcc:mimeType>image/png</dcc:mimeType> + <dcc:dataBase64>iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAEDmlDQ1BrQ0dDb2xvclNwYWNlR2VuZXJpY1JHQgAAOI2NVV1oHFUUPpu5syskzoPUpqaSDv41lLRsUtGE2uj+ZbNt3CyTbLRBkMns3Z1pJjPj/KRpKT4UQRDBqOCT4P9bwSchaqvtiy2itFCiBIMo+ND6R6HSFwnruTOzu5O4a73L3PnmnO9+595z7t4LkLgsW5beJQIsGq4t5dPis8fmxMQ6dMF90A190C0rjpUqlSYBG+PCv9rt7yDG3tf2t/f/Z+uuUEcBiN2F2Kw4yiLiZQD+FcWyXYAEQfvICddi+AnEO2ycIOISw7UAVxieD/Cyz5mRMohfRSwoqoz+xNuIB+cj9loEB3Pw2448NaitKSLLRck2q5pOI9O9g/t/tkXda8Tbg0+PszB9FN8DuPaXKnKW4YcQn1Xk3HSIry5ps8UQ/2W5aQnxIwBdu7yFcgrxPsRjVXu8HOh0qao30cArp9SZZxDfg3h1wTzKxu5E/LUxX5wKdX5SnAzmDx4A4OIqLbB69yMesE1pKojLjVdoNsfyiPi45hZmAn3uLWdpOtfQOaVmikEs7ovj8hFWpz7EV6mel0L9Xy23FMYlPYZenAx0yDB1/PX6dledmQjikjkXCxqMJS9WtfFCyH9XtSekEF+2dH+P4tzITduTygGfv58a5VCTH5PtXD7EFZiNyUDBhHnsFTBgE0SQIA9pfFtgo6cKGuhooeilaKH41eDs38Ip+f4At1Rq/sjr6NEwQqb/I/DQqsLvaFUjvAx+eWirddAJZnAj1DFJL0mSg/gcIpPkMBkhoyCSJ8lTZIxk0TpKDjXHliJzZPO50dR5ASNSnzeLvIvod0HG/mdkmOC0z8VKnzcQ2M/Yz2vKldduXjp9bleLu0ZWn7vWc+l0JGcaai10yNrUnXLP/8Jf59ewX+c3Wgz+B34Df+vbVrc16zTMVgp9um9bxEfzPU5kPqUtVWxhs6OiWTVW+gIfywB9uXi7CGcGW/zk98k/kmvJ95IfJn/j3uQ+4c5zn3Kfcd+AyF3gLnJfcl9xH3OfR2rUee80a+6vo7EK5mmXUdyfQlrYLTwoZIU9wsPCZEtP6BWGhAlhL3p2N6sTjRdduwbHsG9kq32sgBepc+xurLPW4T9URpYGJ3ym4+8zA05u44QjST8ZIoVtu3qE7fWmdn5LPdqvgcZz8Ww8BWJ8X3w0PhQ/wnCDGd+LvlHs8dRy6bLLDuKMaZ20tZrqisPJ5ONiCq8yKhYM5cCgKOu66Lsc0aYOtZdo5QCwezI4wm9J/v0X23mlZXOfBjj8Jzv3WrY5D+CsA9D7aMs2gGfjve8ArD6mePZSeCfEYt8CONWDw8FXTxrPqx/r9Vt4biXeANh8vV7/+/16ffMD1N8AuKD/A/8leAvFY9bLAAAAOGVYSWZNTQAqAAAACAABh2kABAAAAAEAAAAaAAAAAAACoAIABAAAAAEAAAAUoAMABAAAAAEAAAAUAAAAAJEV0scAAAAtSURBVDgRY2RgYPgPxFQDTFQzCWrQqIGUh+hoGI6GIRkhMJpsyAg0NC0jMAwBzu4BJ2FWhpgAAAAASUVORK5CYII=</dcc:dataBase64> + </dcc:file> + <dcc:formula> + <dcc:latex>E = mc^2</dcc:latex> + </dcc:formula> + </dcc:noQuantity> + </dcc:quantity> + <dcc:quantity refType="test_charsXMLList"> + <dcc:charsXMLList>A B C D E F</dcc:charsXMLList> + </dcc:quantity> + <dcc:quantity refType="test_constant"> + <si:constant> + <si:label>exampleLabel</si:label> + <si:value>306.248</si:value> + <si:unit>\kelvin</si:unit> + <si:dateTime>1111-11-11T11:11:11</si:dateTime> + </si:constant> + </dcc:quantity> + <dcc:quantity refType="test_real"> + <si:real> + <si:label>exampleLabel</si:label> + <si:value>306.248</si:value> + <si:unit>\kelvin</si:unit> + <si:dateTime>1111-11-11T11:11:11</si:dateTime> + </si:real> + </dcc:quantity> + <dcc:quantity refType="test_realListXMLList"> + <si:realListXMLList> + <si:labelXMLList>exampleLabel</si:labelXMLList> + <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + <si:dateTimeXMLList>1111-11-11T11:11:11 1111-11-11T11:11:12 1111-11-11T11:11:13 1111-11-11T11:11:14 1111-11-11T11:11:15</si:dateTimeXMLList> + </si:realListXMLList> + </dcc:quantity> + <dcc:quantity refType="test_hybridConstant"> + <si:hybrid> + <si:constant> + <si:label>exampleLabel</si:label> + <si:value>306.248</si:value> + <si:unit>\kelvin</si:unit> + <si:dateTime>1111-11-11T11:11:11</si:dateTime> + </si:constant> + <si:constant> + <si:label>exampleLabel</si:label> + <si:value>33.098</si:value> + <si:unit>\degreecelsius</si:unit> + <si:dateTime>1111-11-11T11:11:11</si:dateTime> + </si:constant> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="test_hybridReal"> + <si:hybrid> + <si:real> + <si:label>exampleLabel</si:label> + <si:value>306.248</si:value> + <si:unit>\kelvin</si:unit> + <si:dateTime>1111-11-11T11:11:11</si:dateTime> + </si:real> + <si:real> + <si:label>exampleLabel</si:label> + <si:value>33.098</si:value> + <si:unit>\degreecelsius</si:unit> + <si:dateTime>1111-11-11T11:11:11</si:dateTime> + </si:real> + </si:hybrid> + </dcc:quantity> + <dcc:quantity refType="test_hybridRealListXMLList"> + <si:hybrid> + <si:realListXMLList> + <si:labelXMLList>exampleLabel</si:labelXMLList> + <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + <si:dateTimeXMLList>1111-11-11T11:11:11 1111-11-11T11:11:12 1111-11-11T11:11:13 1111-11-11T11:11:14 1111-11-11T11:11:15</si:dateTimeXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:labelXMLList>exampleLabel</si:labelXMLList> + <si:valueXMLList>33.098 99.971 175.103 250.169 320.004</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + <si:dateTimeXMLList>1111-11-11T11:11:11 1111-11-11T11:11:12 1111-11-11T11:11:13 1111-11-11T11:11:14 1111-11-11T11:11:15</si:dateTimeXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + </dcc:data> + </dcc:result> + </dcc:results> + </dcc:measurementResult> + </dcc:measurementResults> +</dcc:digitalCalibrationCertificate> \ No newline at end of file diff --git a/tests/resources/Test_DCC_Minimal.xml b/tests/resources/Test_DCC_Minimal.xml new file mode 100644 index 0000000..7707aa1 --- /dev/null +++ b/tests/resources/Test_DCC_Minimal.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="utf-8"?> +<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcc="https://ptb.de/dcc" xmlns:si="https://ptb.de/si" xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.2.0/dcc.xsd" schemaVersion="3.2.0"> + <dcc:administrativeData> + <dcc:dccSoftware> + <dcc:software> + <dcc:name> + <dcc:content>Notepad++ (32-bit)</dcc:content> + </dcc:name> + <dcc:release>v 8.2</dcc:release> + </dcc:software> + </dcc:dccSoftware> + <dcc:coreData> + <dcc:countryCodeISO3166_1>DE</dcc:countryCodeISO3166_1> + <dcc:usedLangCodeISO639_1>en</dcc:usedLangCodeISO639_1> + <dcc:mandatoryLangCodeISO639_1>en</dcc:mandatoryLangCodeISO639_1> + <dcc:uniqueIdentifier>Test_DCC_Minimal</dcc:uniqueIdentifier> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>calibrationLaboratory</dcc:issuer> + <dcc:value>string-calibrationLaboratory-coreData</dcc:value> + <dcc:name> + <dcc:content lang="en">Order no.</dcc:content> + </dcc:name> + </dcc:identification> + </dcc:identifications> + <dcc:beginPerformanceDate>1957-08-13</dcc:beginPerformanceDate> + <dcc:endPerformanceDate>1957-08-13</dcc:endPerformanceDate> + <dcc:performanceLocation>laboratory</dcc:performanceLocation> + </dcc:coreData> + <dcc:items> + <dcc:item> + <dcc:name> + <dcc:content lang="de">Temperatur-Fühler</dcc:content> + <dcc:content lang="en">Temperature sensor</dcc:content> + </dcc:name> + <dcc:manufacturer> + <dcc:name> + <dcc:content>String</dcc:content> + </dcc:name> + </dcc:manufacturer> + <dcc:identifications> + <dcc:identification> + <dcc:issuer>manufacturer</dcc:issuer> + <dcc:value>string-manufacturer-item</dcc:value> + </dcc:identification> + </dcc:identifications> + </dcc:item> + </dcc:items> + <dcc:calibrationLaboratory> + <dcc:contact> + <dcc:name> + <dcc:content>Kalibrierfirma GmbH</dcc:content> + </dcc:name> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + </dcc:location> + </dcc:contact> + </dcc:calibrationLaboratory> + <dcc:respPersons> + <dcc:respPerson> + <dcc:person> + <dcc:name> + <dcc:content>Michaela Musterfrau</dcc:content> + </dcc:name> + </dcc:person> + </dcc:respPerson> + </dcc:respPersons> + <dcc:customer> + <dcc:name> + <dcc:content>Kunde GmbH</dcc:content> + </dcc:name> + <dcc:location> + <dcc:city>Musterstadt</dcc:city> + </dcc:location> + </dcc:customer> + </dcc:administrativeData> + <dcc:measurementResults> + <dcc:measurementResult> + <dcc:name> + <dcc:content lang="en">Measurement results</dcc:content> + </dcc:name> + <dcc:results> + <dcc:result refType="gp_measuringResult1"> + <dcc:name> + <dcc:content lang="de">Messergebnisse</dcc:content> + <dcc:content lang="en">Measuring results</dcc:content> + </dcc:name> + <dcc:data> + <dcc:list refType="gp_table1"> + <dcc:quantity refType="basic_referenceValue"> + <si:hybrid> + <si:realListXMLList> + <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> + </si:realListXMLList> + <si:realListXMLList> + <si:valueXMLList>33.098 99.971 175.103 250.169 320.004</si:valueXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> + </si:realListXMLList> + </si:hybrid> + </dcc:quantity> + </dcc:list> + </dcc:data> + </dcc:result> + </dcc:results> + </dcc:measurementResult> + </dcc:measurementResults> +</dcc:digitalCalibrationCertificate> \ No newline at end of file diff --git a/tests/Resources/example.xml.ts b/tests/resources/example.xml similarity index 93% rename from tests/Resources/example.xml.ts rename to tests/resources/example.xml index 5bacaef..e4dec5e 100644 --- a/tests/Resources/example.xml.ts +++ b/tests/resources/example.xml @@ -1,4 +1,5 @@ -const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcc="https://ptb.de/dcc" xmlns:si="https://ptb.de/si" xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.1.2/dcc.xsd" schemaVersion="3.1.2"> +<?xml version="1.0" encoding="UTF-8"?> +<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcc="https://ptb.de/dcc" xmlns:si="https://ptb.de/si" xsi:schemaLocation="https://ptb.de/dcc https://ptb.de/dcc/v3.2.0/dcc.xsd" schemaVersion="3.2.0"> <dcc:administrativeData> <dcc:dccSoftware> <dcc:software> @@ -143,7 +144,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:real> <si:value>306</si:value> - <si:unit>\\kelvin</si:unit> + <si:unit>\kelvin</si:unit> </si:real> </dcc:quantity> <dcc:quantity refType="basic_validityRangeMax"> @@ -153,7 +154,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:real> <si:value>593</si:value> - <si:unit>\\kelvin</si:unit> + <si:unit>\kelvin</si:unit> </si:real> </dcc:quantity> </dcc:data> @@ -250,7 +251,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:real> <si:value>0.1</si:value> - <si:unit>\\metre</si:unit> + <si:unit>\metre</si:unit> </si:real> </dcc:quantity> </dcc:data> @@ -272,7 +273,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:real> <si:value>293</si:value> - <si:unit>\\kelvin</si:unit> + <si:unit>\kelvin</si:unit> </si:real> </dcc:quantity> <dcc:quantity refType="basic_temperatureMax"> @@ -282,7 +283,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:real> <si:value>299</si:value> - <si:unit>\\kelvin</si:unit> + <si:unit>\kelvin</si:unit> </si:real> </dcc:quantity> </dcc:data> @@ -304,7 +305,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:real> <si:value>0.20</si:value> - <si:unit>\\one</si:unit> + <si:unit>\one</si:unit> </si:real> </dcc:quantity> <dcc:quantity refType="basic_humidityRelativeMax"> @@ -314,7 +315,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:real> <si:value>0.70</si:value> - <si:unit>\\one</si:unit> + <si:unit>\one</si:unit> </si:real> </dcc:quantity> </dcc:data> @@ -336,11 +337,11 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 <si:hybrid> <si:realListXMLList> <si:valueXMLList>306.248 373.121 448.253 523.319 593.154</si:valueXMLList> - <si:unitXMLList>\\kelvin</si:unitXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> </si:realListXMLList> <si:realListXMLList> <si:valueXMLList>33.098 99.971 175.103 250.169 320.004</si:valueXMLList> - <si:unitXMLList>\\degreecelsius</si:unitXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> </si:realListXMLList> </si:hybrid> <dcc:measurementMetaData> @@ -354,11 +355,11 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 <si:hybrid> <si:realListXMLList> <si:valueXMLList>306 373 448 523 593</si:valueXMLList> - <si:unitXMLList>\\kelvin</si:unitXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> </si:realListXMLList> <si:realListXMLList> <si:valueXMLList>32.85 99.85 174.85 249.85 319.85</si:valueXMLList> - <si:unitXMLList>\\degreecelsius</si:unitXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> </si:realListXMLList> </si:hybrid> </dcc:quantity> @@ -374,11 +375,11 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 <si:hybrid> <si:realListXMLList> <si:valueXMLList>306.32 373.21 448.36 523.31 593.07</si:valueXMLList> - <si:unitXMLList>\\kelvin</si:unitXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> </si:realListXMLList> <si:realListXMLList> <si:valueXMLList>33.17 100.06 175.21 250.16 319.92</si:valueXMLList> - <si:unitXMLList>\\degreecelsius</si:unitXMLList> + <si:unitXMLList>\degreecelsius</si:unitXMLList> </si:realListXMLList> </si:hybrid> </dcc:quantity> @@ -389,7 +390,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:realListXMLList> <si:valueXMLList>0.072 0.089 0.107 -0.009 -0.084</si:valueXMLList> - <si:unitXMLList>\\kelvin</si:unitXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> <si:expandedUncXMLList> <si:uncertaintyXMLList>0.061</si:uncertaintyXMLList> <si:coverageFactorXMLList>2</si:coverageFactorXMLList> @@ -414,7 +415,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:realListXMLList> <si:valueXMLList>-0.23 -0.23 -0.23 -0.30 -0.30</si:valueXMLList> - <si:unitXMLList>\\kelvin</si:unitXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> </si:realListXMLList> </dcc:quantity> <dcc:quantity refType="basic_acceptanceLimitUpper"> @@ -424,7 +425,7 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:name> <si:realListXMLList> <si:valueXMLList>0.23 0.23 0.23 0.30 0.30</si:valueXMLList> - <si:unitXMLList>\\kelvin</si:unitXMLList> + <si:unitXMLList>\kelvin</si:unitXMLList> </si:realListXMLList> </dcc:quantity> </dcc:data> @@ -437,7 +438,4 @@ const dcc = `<dcc:digitalCalibrationCertificate xmlns:xsi="http://www.w3.org/200 </dcc:results> </dcc:measurementResult> </dcc:measurementResults> -</dcc:digitalCalibrationCertificate>`; - -export const xml = `<?xml version="1.0" encoding="UTF-8"?> -${dcc}`; +</dcc:digitalCalibrationCertificate> \ No newline at end of file diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 0000000..6ddab7a --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "ES6", + "declaration": true, + "module": "commonjs" + }, +} diff --git a/tests/util.ts b/tests/util.ts new file mode 100644 index 0000000..cbabf5d --- /dev/null +++ b/tests/util.ts @@ -0,0 +1,36 @@ +import * as xpathTs from "xpath-ts"; +import { JSDOM } from "jsdom"; +import { DCCDocument, DCCXMLElement } from "../src"; + +export function select(xpath: string, domOrDCC: JSDOM | DCCDocument): string | number | boolean | Node | Node[] { + let dom = <JSDOM>domOrDCC; + if (domOrDCC.digitalCalibrationCertificate) { + dom = toDom(<DCCDocument>domOrDCC); + } + + return xpathTs.select(xpath, dom.window.document); +} + +export function toDom(dcc: DCCDocument) { + return new JSDOM(dcc.toXML(), { contentType: "application/xml" }); +} + +export function toTextArr(arr: DCCXMLElement[]) { + if (!arr) return []; + return arr.map((x) => x._text); +} + +export function indexOf(arr: DCCXMLElement[], el: string) { + return toTextArr(arr).indexOf(el); +} + +export function toTextContentArr(el: Element[]) { + if (!el) return []; + return el.map((x) => x.textContent); +} + +export function undefinedIfEmpty(str) { + if (!str) return undefined; + if (str.trim() === "") return undefined; + return str; +} diff --git a/tsconfig.json b/tsconfig.json index b736aad..5136c1b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,8 +3,12 @@ "target": "ES6", "module": "commonjs", "declaration": true, - "outDir": "./lib" + "sourceMap": true, + "outDir": "./lib", }, + "files": [ + "./tests/index.d.ts" + ], "include": [ "src" ], diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000000000000000000000000000000000000..85098f5a364c9ba6a2170cbd50db5b8a977f019b GIT binary patch literal 202139 zcmY#Z2+7DSR!GatNma-!R!C3HOD#$)Nlj5ms#GW{&CAQoOIJ{;Of1S%$jmD)NzBPn z0x>dEQWYxmON$f=it@8klS}ltlofmv^GXwQ6p}L%^U_m`6>>AvGfEVaQWbLYi%S%A zK`N6|Q&SYmGfOfQk`qfyGV}8kxwzuvb5lzaQxZ!Ot+*5v%2JDpGxPJT6wJ636p|B@ zGg7@%E3FhPxVV%Y5_1cnw&@q8<|Y;tWagzi<Q3#v#Tn@t>KQ1Z=r__c(lg*vP$)_* z&d&kcWu<_}2(WS`E(L{@)PmH!l+?WB%+z9#feH#r4p~K+De0-@sX00N>8W|TP^*=! z6ygj(7IP^mps6Y;N=!~gRcEYc3Gz`!YI1gQX|9z*in&ROp}9edftiV!g{7gfrIBHZ zxsi#nfsv`DiIGW?d8$dWg^^j3X`*?Gv1MACg|TI#k!6ahiFs;TlBIb{vZ=Xwa$=%I zQlfEMl4)|9fswJ9kx8m$Vwz=&fu)(LVPaacaf*qdp;4lVX{wQdse!SPMPgF2Ws-5C zk&&elmx4l0VqSV_VtT4yVs5IHLSBAKDo8LhFFT~NAk|7CBe5t26zoZfNvS#d$@wX% zx@kp;xv7vKH`g=JGtg0Rz$I&Fq-SW1Pu@b$3^m5g^$acaK+%pGWmqkMsKpgu5G@&* z=@~hoGzf|)hz67xFtjvHHA+e~HZ(U%F*ma?NlLRcO-@TQvrJ4iPBKq4G)=U$FfmL` zv`jHFPccrmFfleWGfFWvNKQ#HPcbtwH%LpdOtwfhGf7IdFi9~mHZ(LePc=z2F|aT; zu`o+bOG`>LwoJ23OieRON=h<Hwy;byPct%1N(M<7CnbUco3t3nEl4cU1?3c26c`!k znW6`xk%69}2}Z()1W9r}suAXTVAY^-OopdSvt-NEv{Yj=BV!{2OOsTS#1w-hbAuE^ zGgDIwkOz_z%?&M5O;ZdE4b#jMO^p)G%@YkRObv_@%}qfm&>+>w!qhY|(KOL0)xg5c z*wQp9IW5J=Fe$|-**w|O($L5vB{{_+#WF1=EiKj3#Msa*$=oP0In6ZL%q-0)ne=ce zf~QGCLp?L3M293{q-TsRq(J!qdwPTFg#?iiD2T8X4cN*gP<jKGNYH`-7WS|V1d@lR zM^MQDQ2;G@^NS$zMh1H3C<bJt<`kqB>4M@gGba&Ldg_)W7Nw__6yw*Bo1apeld4-% zl$ckXmS2>MP;O|5#R7yhs`UklMa8MO+*XpBTac4jl8VD6B}Iv#f*m1k2nu(E*Gno3 zQqk>A&d)1LEh^D1&Mz&36sA@RafW*4;8Gn_PA8S7TPehuz)Rrt)V$)#ykxK{13d%X zq|}l`J%~M7#rb)rRtj;TQXV2woSIvfT4bdVXQpQiHW4ZP8>N~h8>bo>nph^98zh+~ zTbdhLrly&u8KfAe8l_sAr&^{Yr=(g~rX?E~TP9niSfm=8m>H*-rkE!sS|%A;rh>`? zLxZ%$G;_-&Gec8jqr_xGGZWLqL^Go_qofoQBV%I=V<Q7IL-SO#RO3X8M3WSYRHH;A za|3g;R8XjsR5HWU4N|FK4$lM_vgUe5*fIjHA_G-FBsZAg$_<c&j4d|tSE9!7cuFk> zMWB(MsU9e8A|k~!%`7p|D8<4oG0n&<)!Zz_$lT1*$T-n7+1SL;($LVzB+<~&GRe>^ zHPtdXIoa3*RP36XB$}tBCR>=KC8e0B7^NhprWmD~nV4E6nk5>TC8b%Irx}}>8K$Hr znVTnDrllsDS|(YfnVF|0rlpxCTN;>K8Yf$trI?$gfT|^uA_aG5MUEvb5dn&RYy}bl z1Hlnvjz3;NB?q(uf#*|GEG2+$Sz=CRN@7WVk#2qgsGNbQhStss3Q0xz<;AH*#W|V9 zCEy%rWT<BhHYca3R2ST6vr>pN)iVUgp@ITNUMomVEpoxq&VnSL<oqINL1BQFGcA&h zjgl?Qjgt~B%u<a~4J`~zlZ*{g4J-`I6O&R5%ndCp5|fis4GdC~k}S<l&CSvbk_;>j z%nXy0%}fmp%+m~w4ULjaEi6-$laox0O)Qg56D^X>(=3vbEYpk<lMF2_Q%np~63q>a z4U*Cf4UAJP(~M2bQ<77R6OEJ8Kv{&GM39<SmRXdamz$bbqFa_(oLQ1z1WN>l7J8QG zi2x*qqyB~_0$c`yD-}ynB0yxEBqLKp1H&{kLo=h4l;lLC6hotwL~~<H6Qg7Ui^LQo z1LG8PGc$`+12Z!-<CHWr3sW;=lSGTOlvGobL`#dLWCKIfG_y1_BTHk8R0~s66BASO zL{m$nL<1ueLj#Kx6VoJ%G~-k=Q^T|rvy|kNBnxwMBXiRvbK~S>6B8p)6P%ndODoMw z1|>b+Jfs$<p(T1N-&_wQhCj40je_U`g%h?a9g+%BYcxX(JwuRJuvS@6Cm_N+H8I&R z%`_#+#K<Bk(bUAu$lM^=D9Iwl+|(f1$Rst%)W{;qA}u*B)zl!_!Z0P(DAgb-B{eC{ zAl1kq&B!DvHQCI<BE`hm*wED2ILX|?DAgp<(!e||F~!8#)X2od%*Ze~(a6x!I5{mj z&B7qj!pz**(8$u#!o(oeAk7Tij3=dK2~AcR`I*Hfx@Cz)nTbg`sl`ZXl$4e_9>c)t z(~Lm4Bboxx0tXSUpa!?GX;PAjv1wXLqJ@D`QkrF2nt760no&xcftj&^MWT_Rk-2%Y zSxRcMk)e@6qOoa`fn}OyN~)PfnwdqSv9YDOQL0h0p{c2XX|iFWVWNRalCfE8vYAP; zWnyxwrFn`;qGhU)S&Er~rFoLMS(1sdrCE}BvT0hPkwF@%EmLSvKpSA0xdr(}B@_lL z7PBZ0RbxxzG>b&zBx7R(lO)3=^F$*Hi$r6KWJ3c>3(J&Lb5oNv1H%*}%jCo~Go$2G z^JJ4$Qww9$l*BZHL?iPg3&S+y#AGuI^Au1|$-*GT*wW0xG%+#NJjvA5$jsc>$Rx?s z(8$o#Ak{p{C@Iy_%sj~;*~HQ~$t=+@C6&TZMKo(+=@rzaF+?v^!Gie9324xw83?Xe z4Gr-pT4+RLDVO0@rzN<8RD$-Gp&Fo8LQ@7@EvU7DC~2T-i!*Zza#D2@lao`65p88i zYZlGe;)0ya65Z4aP<qo%Nlng4ECTlz@LPbW^)pja^GY()GGWbqLrZ8)4zmZfaKz}T zU^e%0mYq<&h&*m&X>4ejnv|H9Xl7}gVq#%#YL;x4lxUD*VQy$<Zl086U|?*XYLJp> z0BY8y8W|ZT8k#2?Tcntp8(12rC0isW8e5o}7$+N;r+`}178XWkW{H-@=9cDWsmA7s zNhX#ChL+}r$%*D^M#kpJrin==rfH@|CP|=HK_bYZ<kVLMIi=~DdAg+~nK|$rjyymD zjYMq93=Q;5;LUY>>QF{h@F_IWGbPGE3#866KJzS*Mtbn5v%svKjSRpodpr$Vj1U25 zIB<U(ktov4k`q%+jg!pNQj!dl(u@<6QcMlf63q;g3=NV@Ow0`|EliV43=EQ!%`Ht* zERD=SrITT*xdAA_7=rq5X=X-di7Ckj<|c+oW|k(Prd^U*s)?ata!N`{N|Gh0nPZ-4 zZeW?53@YDJlS~X#&CHCGQcY9LO_Ing_))SfQt^bX0|v^-c!CMjC`35nX~ZBZQ)o;e z!Zb0(FxAp5HPtB9G|kM^BrPp9)yUY)GSSq+EY&pCBE`tu$S5hzD8(Ylz{n!e(8w^! zB-z+FH7POG#N5c#IL*u?#l*<K(9}H1GR+{-!qUh*F*VUR(K6K_&Cnv*z|g=r)!Za4 zCB@X((8AC(InCJ2)F9Cy(Ihb?InmHC5!AgSC!^si+hD;9YBZo1{va{@Wj|h1DXn0W z%~Fh0Qd3e*jV;VA(#(=l4O1-4EK?1PQ!Ufdl9G~)&C*OPEX|Y6lamcijm%S$EzOcm z%~A}F%u_6kK@nqOYGjaTmS&!6VrHIZnq-z{oNQ!aVw{?2kZNI=Xl`L>nPO&^m}+2@ zW^Q1fW|o+2U}~OboMLKjX=0pcM0V;eDay=C*M*Gxz=PLP&jcfQE%iWMBYdeB!zgeQ z96XMINRdfKpk|1rkwKENK}uR;vV~!4vXO;RVzNnMilwQgMQWm<xq+F9MVf_?sY#Nd zL7IuVX<|~US&F5JiG_hhT9Sc*Sz=<6v5{$tacYujqD5kgaZ+lcMM_$tg@r|OTB2EM znu)ogfvG`CVydaRiG_)!d9tCQL29yrnSrGVs0&L@io{lL!h;J-5sO#7r5;Ap1zP*! z30|Bgf<qbHc0q))L27cMX{v=;qPdZ!p_x%)nyHy(l8ITeS+a>?qM323p+%C3aY|CE zfn{1sqG5_rqH(f?rIAURd5W2#xuKz1Vw$mKa$>S+s!4K+X^M%lVN#O0nL(0CN^+uc zvVo<!L8?KriHV81g=LZ<s0);ooMxDoXkwU_l$c_WXiW03H?+b*_z^NDfgHjZ3DN@R zJOVz`5cwPtT4|Qa$!4iZ=E=#XDdwi20fVG80|PS?10zEVgEWg2(^L~9Q^QnCLrV)o zOLG$=i$qKFR0Go#Gt*RXa!xf(G)PW0H%>B4NlP(GF*Z$1GcimtNKG=gFfcPRPc$=0 zO-Zw~NHj?`H%v1yGf7QNO-xQrvq(ubwMa8cCbMx2Z-RiDSLmSwY6^qWI_?Ao(GIR) z42|)(d`WHzf^0^#Z83)m5ka3~W@KP)mX-)A1C33L%q=a_ERv1WQp^)mlMO7)4U&@$ z&5cY`jLeNwEG<(_O$?Hg5)&;_Kx4Nlh6YBa7Dh%EDJg~~W(J0!X&SSnwA93;q$JSn zTC#DHv7v#bL27a`s7M8kYowVcrI;Hfo0uD$q@<arB^iJk?4%V3u=yr(lO~FOL}J8U zy<;S1jD|ZTBPf98WOK5?1K^M`H3fyNV%?Jb?9{ws@CY766cP58MkyAlsb+?zCYC9w zrfF%WhDHXdmL{gD=H@2mMi!~2$;m0E=4mO$Nk*wDW}qZ%U}TV*Y;Iy=VPp*ILtCU8 znHVLd8k(3Irx+QUo0%jU8zdT<n44LqCa0Jg8JZiUB_$eJm>OFq85tUyTUsV1C8ik} z8-ZrZ%q>U`d$dXlslAFOW1@!`8b_4^XA5|<8AHw-TQ&lXo?^>JNV*}p$P|=|k}~rk zGs+NYD+N9Mq|7{h@OTrnn$^oHMxCQf0o8KJiDu?$X+~zIMrnr025D)Arsf7osVNpI zpmEG(lO$7PQv=IX^W+qBV-s_;L{OP!o|<B0Y+_-MY-yPW3g4s@vlN4*R0BgZLnC7| zizG{<BxB1|BLlM(V`GEF6f*-;69WUw6f;XpOJfrY6AMs-&eDS9rUSG!UtF12l31ae z2%3-4h0h>Bij_EXJqye>gaytf1QA9;OvEvH4-Q^^XjXw52JWUodczjrF=i4*q;)}E zL_|(8PfamQHcYWhvP?BiGBZg{GcdA9O*Bn4H#JQ*NJ=$IF-bK|HAyv2F-uM}Pf0Te zwU-kul1-99b)uzlijkRxp}AR#L7E|`)JaWFNl7$IOEot#vam2sHcv}QG_x>FGqEs8 zGd4FdOtDBb0_iX{F*i0#GcYwa15Fo@R7ycZ02)I{ndzB%C9nd^0&|Yk0z9&hHH|}h zyqE@oVuL`fL9^H}PBb*IFtJRrFitfA)f1)$X~t&eiI%CRW{GA=Mn);1Dg2b=R5KG} zV`Gyf0}JysOA8~5G?QfGloWI0q?BY+O9RWq#MH#3R6`@<wA2)H3sXZ=b2IZa%j87R zlz~N}K`Lnc)x_8$#V|R=$il!V#XK!B6*N<1VnJ$05j8fFa}tY-bqk8}3sQ?pG7%%N zSmFh|yaGp`h6qE=^}q&zN+p8T3)DEIJOkFtrJz85t}!x6Gd4*wv@}aGGd3|wGqOlA zNlHvHHZV3b1O;cBshL?~l0l+@p>cAmg=MO_xoL`}MT%LPg|U&PnWc%DQL4F-v1yud zs(ET+nxVOwxkaL>v2lt?QmR2xqKRpWabl{mNn(;os%fHSN^(+4B3QqPWvXdvTB1=J z$!iRtVE|3+knuWQ(7Gi&SqC((LsSf*8)vQu(n@aJ7=TMs@}tJk%q%h4(9p;<#n1pW zE|P3wY>;YVXliC;Vwq@YY+-7VY+!6=mSSvSVPaxoVVq(PZi87^ni(0UCV?h`3=K__ zlZ=v6lgv_*4GaxUjZIQa4NOhV4K33W4b6?rlT0nsj4e|Q6O)XS6D`dxj0{p!(~MJ+ z6O&AnEGevVKr{Wi#o+EHQgwr|^n=)94a2yBEZmaPOcPTR4bzMbEi95P6HN`wQw_~h z(^3tL4M1zcK%?%)piWp~N{X4Op;5A_VM>y@k+E@dvZ)1Vh~5IUj4atKDJ3n*z%a$w zz{12h$<WL&IW5&Z#n{L&)i4Q^5fd$p(##V<vsI~PNy(-rW+rB4W@*NzCM5UVP%}+d zaRn^1U|E8IXNU&7F(kB)p#~rqV32k(`I*El#n?PG5j3!9ZeVC>nr4`mmTH)2YGQ6; znw)Bsm}+8bmTHigY-VU;nwFSqnV4t@s=|#d&5cYfl8nrZQWMQUbJWHLh6brADM=P) zsYz*x$w`(bX{P4M2BwLIY00K3pyse;B4`2yG>c_mW?*D#nPO^anoMb}pOc@SnVguT zn^;_&nGTtk230wr8Gn4422?5$RiF_xe_%_v#I!VHV^ec;&_sf<Nvf%#DQE$SscCXb zQj%d>iZN*UTdJ|KnW;r$qJcq@MWSh1igBVzlBI#MsfDSbp;3x~v3YWGs$p`nWvYpp zu~C|Vi3Mmyrm2aEg_)s&S(3RWsDG52Xl4vr180zuW@2n+oMx6{l9py+0h-;Rpvjh3 znv;`RoS~bXpO}+coD3SGgGC-Je_?4a5L@68GJPP+KMV83<U|uoLkmkoGXo=o6vMRC z6wv&7vO%hmu~AB@iGf8*nvt1_Numj;_A)h2N;NjKFg7$!O94rySehAFSfr(<rkH_d zFcU$G4il3tEJ0)Z2Igt0X+|k2X~ssDiH4?z2A0XDsYzz0DWJigq%<Q_3xgDrN35ac z4z$sbSDKqzl$oqsoLT^yjzg>g!4g|U=QQkw4s7-^FicH0H8n9$N-;38G*2@(OHQ^l zFiuM|Nij<@FiK2Hwn#QGO*00K%2=crnHd=+nSsW+Q;m%iO+o9H6U~#&6OB_W3{pUo zdS<3(i6*8N7HQ^2=4Po$iN>bpX=X|0sh~kP3!^mCBvUh!B+xjTg+)rLiKQ{=6AP%( zl%E7z&aPXOT3n)ATu_vnm_mhIg~QN+%uH!1DamQ37KVwY=4s~UsTKyQNoGlw7KTZN z24<!fCZKi7#zuxoiKb}=iKa>BrY44l7RhFbmPU!7QZCKVDA6F<*w`%1+&sx5F)7U) zG-_a&YG`1TYHA2tKVfNTXpm@ZV3wMgl4JmCmZTb*nwTdiCK(&1nI<QtQPxv}i~%R+ z=q4wYBxmR*W#*;8Hv>RI6*STUT5}5COaK-ls_MdHFxU_>Tji9FGFTcKq*xlHnj0l0 zTN<P$8YZWjSz4r8SSA}97@4P~rdU{*m>L-xrI;ornOaz+8k?r3SsJDp8YfvA8=4qf zn3$$nnxq<;8iRVqhAH4Rt0}1|$%ZDW$p)b63pDy^mS|yUZkd{rVq%<VY-E;fZefyY zo|<BwW{^bscpS>$03uK`5;H*?N~n>gz$+6$DFE5bfsCWn)HF+z6jS3w(4eQWnW3qv zak62WrA3mNMT()hxrLF1nPH-VNusf(k%ftYv58?)vZbN9g@J{!MM{cEs+py!k%48h zxrMQrv0-wWK}xEjNwS%-skx~|Qfgval3Aj0qM4~NXqA^)T3Vusv4vSuTAHPSnX#p@ ziFukaXjqDZW<^PUfo@J}S!#}MVtHaFz9At)6Fr>co+#0d%}8@SkajY25lAaV!wyMF zDTaxrW=RH?rb(%wj;Dc<Ws;GBC1_!Zp`}Sm5@^oK$jr>rFfG;6($d1z3^deWW|m}R znq*{Qm}X#Xm}Z=kmSSlL>Nr_~7J{dNj7kDE7mW-JEsTwmEKE&O4APP;%q<L3%nU(! z(ag*|*(k*z#hm1Yd8kzrc(Nq9D6;?_J6JkWMv$R=!XtKQrh&()4akicOA1F(%?vFp zlR<0kjg68Ljgu`CEesOD%j7`|J<JU)Q_L-llZ*^f(~K;WEKH44OwtUDEsZQwEzJ!r z4UJQblT*`DEDQ`SOj0e4OcGNqEfQ1AQb22eEew)UEz(lWKs~gSRLexOlq3sFb0bqD zV<TgeGy@}ZlN3-TMrv&YoA!bgWQL&iq43EAbXm|W98O7N%t2R>dK|SCiqYUWBe>|B zz_t^}WCUa|9BMIf^K(Y2Nrs6AppgO-LsJ8D3v+X`q~z2jV-s`Z6wrcfa}%>vv!o=G zWFye>9TT(ERCCZcg^`6xin(dBNg`;n#~?YyEX^d%#L@(`WYf~z&@jz1*}&YwAQiO3 z2-LDOF*Y)=NJ&jhHcPWewX`s`NK8viNj5gIBsnv|R;9t>3^d_`*ujQP)(8=4&<!le zdJ((Z(Dh=^mWH6IPi*-TMLRf73C+49Hse9!4LW*)h&TA03q&3xUZDf<BrjM*SxXHu z8@l=#VK>xlwAI8=#gKs)48^$C-{8=NmS({ri!c*hvO#phJ)V-9guY!UCqF4M2Q>X@ zXb9aygqYPaHb_o11Fgz7v@kL@PD@ENu}DiaurxL_O-)NNG)YNIHZugZpOY-o5{=Cb zjgpK_jFUiuNybJ=$!5k$rl}UDp!F)CW$>1!=4Q#DjX}mqmS$-tW=STd7N9wXB!fg# zqg2B*W6+$xNoq>60caw~#4;_J<XIiCmtlz$dEFt31Spvxk~C;-7)%Q&60ysG){Wtm zLCmG1*kg<||B5DoF%k=nA*}fV?m}>;AW+ajlO1I27do8^Nd$(F^+|{X0#%AwQi3sW z4qNbAlCPVVSX_cMCxbMJjz}&^#+Hd`Mka=721({dNlBpTTF`uJijlFUp-GxqT4E}w z)0>)<XklPznrvucn4FYinwn^7lxk|3mTYMV+C^yyUYeR>Y-(hXY@U*oVrU6kmzWA# zU6X8L4qDuvW@c<*VQyxUW@wgTVPs&KY7ClqGP5uwd1L}5Qm~9aKsWRdj1)sX;wJhA zCQ{5zLG`=2p+!=nC8&X5kYr(KVQiLcVg{P)PD(OM0&NILOHNKsH8o7KOiD~kGqE&J zG)Oc`u{29IFfjpVa!Z5cG$RA!<kVz?#FS)na|07o(2RScrJ03cvT>TZxuKbbg>f=y zH-d#}Vv>bPvay*dXq<wJ_#M{C`KkJ47P`s#WvNAp>CoM*26`BKR>4A;Edy-Y!Ae2R zIYcV8Ff~ZCG&V3bH3rQ$8zrR}8mC&O8d!jmqiLFfQL0IrrEywfilHHBt8$VNXgVz^ z&CJpy6|`B=(#Rw=F(ozC(7?>X(AXfw#5mc|Fv;B1AT=#H+0w+oG|j>y(IVBvC^gLh z)agkvH#IW0Og2a}FfmU_HB2-jp-@XMF32wdRdV`>-JiO}r3Ih`?T{kNKo4WJF-QoM z6HrqvL8HLhKmmnqA{1%oKl+}213mOD{if!I7HLLi<^~p~sVNqzDM_H|$uuKF14CnT zBNIb&bJJ8a1M^hS3OjT26id(+>7*2MQ$v$96Z14v14B#j4o6VpOEOMMGX{mEd19i4 zr9q;xiCJ2rp@E5ssj*R7nt5`vu>okoM~ab2T5_s!a;lk;fk7Gx^D`;B1tm%PDapyY zS;Y?J`9;~q1&PV2R(hywTns>4{B=u<Q}uH4lM{0=(j87yaID10N-ZwYPlr^yppx0h zQqL6JZvd6d;37#Mqy#PnicEwQ=zIc@6sW0f23}PTmjm~SbW@9SGV@CGA(Sqp>jctZ zs%L73Y7L5dL|Xz$A;b_Xg*Xd6W0+=$m~L`@URq|lZb4CMNl7Mn3$X<#ErPdqfa?ly zhO<(LGuAVQZkqu43RG_({0kD%MQ(k8e1}CzR%u=)Xpg0#87MBmc4QT&<mZBvf?6$* zAj-*4Ni5C)FXS>b*E50$<`v}X7M14dCg$WoWWc?41qCFB8|lHCV<pA9ASZ#0wS+c? z6ckE|b)n8OG|+?Bh@eUt9Dra`Eup4X<mTvRfg4kLW_sWXNkO5aAh9Gvw*(?;tOstT zp^i|L=4I#Qm*;^>O8Bu8#rbI^TwF>H@ZiqP1qDJSEMmdac#uNC1a!s+YMM2HZs$fV z1PGf2)`z_mfNF;B+|<oZtpxeV7-|vrIYfva@b+>8Jp+ZB8ihFUff*o{ovj5lGQlYY zd>Tla38?#IkZ5LUlm=P~l$vI4mTF{Tk(gp`WNB_@X$WdVCMBAhr=}zuB^f3erX(At z7+M&ani?l1rkW+0CZ(At8JJt7nwgrUBwCoJ7?`9PB&Jy;npl{o7#Spi#@Q_l3=E9S z%`DPP(vp%>j8ct_4GhdJj6v%rNf<kV_zZLk0W?~QQqxl_3JPE`VuHR2#6-^oocjpG z2(mF?EuhFi1Q2N7s(E6XL9)52QIds0szsu?g;8o^GH9H}EYZTu60{Q3FeTN}C?(N2 zEiKtB%`(-@&@|QDz|hddG}Xi;(ab2-$Sf%(#liwK)oPTSVs2(`ZkcRsnUrXeVrgM+ znrLZgU}Bb<Y?^AGYMN$boSbB4VxDYdVxF34Mnc&N2_R@{ElP%ji;<oI`oeCo5Js7b zO*dF2C^#@{sKl%?a3V7_0<Zc&J{AGCr#=-li;-%j5Qivzpk*-Vqy%Hw23iG$%=Enc zB9KB;P__b>HPDqQX+^2v;>B3c2v(vM>sBV_!U`5p@=;L8&CJWp1r5i8%RWPB5e;hk z73hN3Q6%T*g7!c|at~y4I3j{g&5|q)EsYY*EX)&4Obt?!OpO!GlR)cB64NZx4AM+Y z%#%%wlZ-*TnJp}n(=0433@j4O6OBwjqic!A21bb{Mv11N%_k<w$!000iI!=JX~rpr zDQTb@6x1q7OEE|>Ge|NwHB2)$N;FQjOi4>kG&eL)HcKL9<rXxGvLI9CkO~5|5Q2!| zid$5TD9b&Q%u~#gEKHItjEs{llFiL6Op;QKEkT=>3@y#f49!i=Oihi<lMK_$K`ZUe z(^5cda!r%cl0a*5EiBS33_&}b5)F(~QY_3Z%uUTxjFOFw(-Ms=(~L}vEDcjFQ<IaD z4NZ(p%?%CG49v_e4I$ezO+kx4j7do4>4`=91x5L}nZ=oDm5?+Js*ljRcVHomaKO|H zRtHMqi1c7$U}~9WZfTHelwx3>lxCc4oR(&sYLJ$iY><+eXkln#l9p<0nrxV6mTF*V zXqaqiX=IoLTE=2vmY9;5Xlb5kl9*&*X_lB`o|2ekm}&%C&zxv!U}j)oVVrD|Vwh-> zm;y>N=4qyB#%bn>mS#y77KTQtMoH$T=E<Ns6t%7bRfQ-O73_SZjMCi1yz-2EP<ypl zAKE-fEGkNbhKqrop`o4yY6^jfVT23;qaeCK;e=TdC^?{NhE6#aCugMQCW4wlhVaab zJQf1-CwkU30N3e=s4z%NF-tN|HU)J&%}tV14HAuvOj6PeER!sgjnXVFOw2%43}^{{ zT4GXSs-Y2R<4#(#fk~QCs##)+nPpO%p=GLJidkZsS)!3enuSFwXqTp?rGcTDMUq)^ zl4Yu4YMQyJsf8Knga^=4O=ANy1Jl%GqvRyR6wt64Sy6$qyEYYi=7J$+NemVu5Et0Y z0_y|C21-yF85tOurzBYz7@H&-C8wkrC7YX>BpI3*q!^p0SQ;1^BqgOKr&=VMSf&`K zCYvT3m>Pj*_RLdEk_?Q@jFSwLEX_e_&?qI%BH048Vlgq%(!{{r*u=mh%_zw{#nRk7 zF*U`|*f1?I%`7?1*b=mq$TY<~Ey)ZNn`8wQN@{^+XCw3~3zmdXt8zT)4r~%w7iusi zT7b@LNli8eExj=^HcSPr{xmfQ4Q?2wnOde=ni(5g7@4OSBpRhACZ-x18-n(vrx+W9 zj;1m&vNT9aF*E}m0g#et1}Y2Fl9LP!O$<%UEzC?)3_%kyDQSkFI>bE9$UM!&FxAK) zCD9VJy)i90$vBOKV9G2mNz6+s&B-d(&&f|r(aoz&hV}r!ev1R80ko6nK!q8oMnnxI z0tSIKfdUCLXD27-rsgCk7DK9LV`vSWmYJ8LTUr2agd2hzSPBa1sU^AviOJcC>8ZM) z{uIgqby@H#8`KnsngVuX8R%d)aG$~yqhXq2YHpE|Xqsx2YGGiKVw!AeY-D6%Vrr0R zXl!ASYM5x8Y-VW)T6ke<oS2+!Xl9gVY+;^c4%(SxVQL7fWev=eEI_q(qNTA}ie*}2 zl7Vq*VzQ-yg`v5Lxv{08d8&~~nrVumnUSS=Vw$l9Xp5tzv5`fJsfDQ-2@9%`0vJ;0 zK_UorLLb_GTaXZ_Pyu@$el#F<{b04ActPZGQzHu_b5qL{OEbe1Gecw05_97eOG878 z6hpJ5<iykzOGA^?q%;cyGtjtRnn_xsiMdIVQ8H+?xsgG#CFsZxLo?G<L*pb1qco#b z&_+cgL!;zm(B3c$qcnqLv$SNx#AGA$B+FC-GxJnaV@uHS6lSR@h8AYYB+SKwx^$ol zsW?9eI;I5aa--Ho5HXDM4?{CV9Vjd?)2NaISUD)sfzKv@s0Ftnl^npL`k?w#$x1;< z3uFRfN0JFN$tfs+Owi3uEiMKnUr;X((i?>h5rCyJg^P0_U0-9UIf!_&1Whb~2I!Mg z42_Hojm->`%+riOJp|BcDru%^7RjL6-pJCx+}y~-($dllv>@3c3AAL%)X>}%v?JQw z($v_@BF!QN)WtGNN-|DNNisG{Nd`>?Sb~-$86=x0n_HMC8KfAQTBd?dU^D=q!D5mK znj<H&ECzW^A9U;yB*{VokCaG)o>d3ch;R5MIX@4S8bA#Kh-zpYft^s43L0QbEy9dK zuyhG%O;k~8acNEocKz_9GjK?Qh7K^Ku%?d0yy8sV)Z*mCf>cm<0o2h4724R6O>(Ag zW?ou8xYGeS@>4+}wE{e90?NFgef0_o>7WBS(@Jx6(_qGdvJo`RK@KcU(FGlW3X(<& z7?8iA<vo_vn2}gq0zT#wiyVQ34DRlNkBfllH39FlfjS6WFqMJIdvvEjWpq(;ph6sm zveLXf@X!<%iIPmvX`dKcit`c+iZk*-gH7m~Ff$!ESfJA<*qm7o>IR}aAU89)C?D2A z1Z8{Brg7+aRHZKHWWq!=+tKs3f&!#B2}&K{ZZBl51NI>pP<f-9mtO)t#{@i*XP{>Y z8h?qi1QiuvmLYhE6U&kk-&DwPv<l#3Q4z*~bBlrkY(bNiLP=36Xd)V^)Je4fohD+O zmTCc7js@C?Z)px%TW@KWW^80&U}}+)W)5ojfR1A|PP8yGH!?F$GfpxzPXnDKYG{yb zVUT8$Xqjx7WN2<~Y-VJUWM-0Ll#*(eVrF2T3_6f7$tcA%Db3J0)jZ8KF~z{d$Otr! z4>}+(*?@$_#h^&kM;e19ukb-P0Frn>Wjsn61qU3omPkv?PSph^L!1Q-@dX9Q6S}$i z$>7bcun`WV*f26oNi{PzGEGh~u`mQ3254qxVVY{1mS$vWnPg&VnPg^cZkcABW|<5+ zgCWTz$<P?IfDSY(Yhh%NXpn4fo@8Q~YL;kVVQy(@mSmQaY5_V7EzK;=6twZ%%-AeB zDbc_p#V{!abS$rhfw^IFvU!Suv2n761qmH$kVo`WD+*GROTfhfWOM<PO-;}bY&5de zGXamTfJ*~-0|vVZ5XIQz1EfP2)Mx~i!LV`&RA3?k5VQ*+(ZDj%B+bG!%^*3+A|=r{ zDKXhN(ag}$A~h}5#MsOfw4ct>$k^P#C@I-I%`nj*H3f98qNQcBX|knZie<97d8(x; zXvv1TVXCo#X^OE~Vydxeib<-0nE|LpV`Q9^W@%<@nw*?woR*fBl4xKGI))|LD3yfv zAILM<1JD$GND`7pvA1|Iq5z_pga8CJEfE2jY+{y{WM*!jY++$)Y?_>AVVs<11UfOr zG|4c{*xW4HEYZ-=z%nHzB@uK`5ool+FwrtODcRIGImyHXbaaA&QA&!LVOp|zlA)nt zT3WKDrI`U}@-5La3AB$PHPys0(J<K{)xg*^(bU4i*dQr6$=J-m!W^{U8Z=}<+*xo) z0Z3+108YJNz4!tR62g$=hSIphRs|sfGAYH-Al1my)X)&LkT})M*x1t0*xb+nbV!P& zg;`>fiA9QunW>qfDQKOmv4yb-_{>j>B%{Ps%M?>HBQrBo<22(m(^M1C{&nNDL~|3P z#AHhg(2=f5DQSjjrY43-rpBPrh!jIZ(8!{Bl7U64rLl#nk$D=a1uIe^2M!TXP9`ZK zq8orONTCHQC>vw8-HJ2w^7FEa^^pt&HNwDkA1JfKr_s=x=%55as6mci^g>%O=uHMh zG@4mj8XF{=SsED`n;51UnV1-w8iL03jLgkU3@l8IQj;ysjEv3G%#97wk`0VZQW6c* zOhJp7Q;ZFhOpKF3=h3BD8l_pLSfrYQj`gxIOioEo1s&*MVrZ6_lxz$-#mOMiAjQZi z*~r-39JCY8B+<;w(AdbtBo$OylhP`O4waJ^g~*zTh(4sM6cj-a9mo|YB<En4!xs0D z2*g=ACK(%8CMH>c&LlTAH%v57HZwN@704DwsTL+lNhvADDMm@ArY0#VX%>c{J?uti zhUTCF*hDi+151-cBTIwCBom`l<7A5@qhvF)q(lo#LkkO|q_iZ%B#R^?b7M1eBhYGf zBMVbd&&kZhEXC9`*(fn7H7zwI1=Ip3B`V;(6Y?ShRXZebv6t#f4oPS$DnLOFUQmG? z8+f}?wCOA1S&k3~T904|>U84F&&e5y;6p$_ZEw&3m4ZTYeohXk!GW~)1T-lGY9E7r zirJ6K$xpHZ&1J$){KeI=f{mu==42+p*R_EAXplC$f&z*P(A5$}rJ&g%=*htl_o1kP zL?CW65KBcsoj8Oi;f6pA07)9_!Q2nYBBTyFfOUb^O`!L2u=iN<(sgrE^U_NoQ}hPV zu{W%J83lzh3*C}@U6`Z6^L7v&gQ}ZjVqs`xW|5efY?)}1Xl|OEY+{*gl9Fa<WNw^d z25P5RfL84$TNs+ATBd+b7D-Go2c6SsWNcxanv`UaoSKxFY;KkcYGkK?mcE&!8X1_I zni!-SCL5)t8m5|=7^Ik(B%7oenHhnmbwQ^y8ylyBPBu$PO(kKMI4G|4AtQohwyBXd z<7-YUITUB+CFdk&7U_dZ<D~owXt`mkX9#LOASyu%(-cb+L$j3RR0~rx0}~SigH+I( zF@q!{LlZO5Ipj%+#-IT!qZG3g!?Z*T(2-l<W}S&qT4GX)xuKDPA?WN7b8}-O^Ry&G z10&F(BgTe?Mrp=L7RITTh9*hL=Agpa(AYf1&@$05)iBu@d_bnLk+B)5g-S}viyQ!; zc8m%7l67#XfK0{GBSF>-QHQJ4B{uXDlg&*{QjJVZlMO9Xl0hd47^EhF4(?7)HLx@Q z9nEEuY-yHglAL0ZnwDs20vcyEG_gnpB|Q^ULnDhcBNJ0g(3*<GB+${eCdS5zDT%2j z$;oM;16z{JOwCP_Ee%qVj4aHIl9N*`Oic|FEzHafOp;8KQj=0hY*Hi2C3wX}S^(z5 zE<gb5#~+47))2{wIXT6dCE&p|*vKiaQ8GlbH8KXB18igp+SP7hXk-jJa|?8+khyW1 zv1y`(L0XEDS)x&zX{xEEsVQjI(8AQnG{qu0HPO@pv?az8bf{rcnwcqRkD;YuT3V91 zv6)$-MWUglxupSU^>b2cQZncSxir&Mv*gqyQ^Pb1LklDG)D*)s3riAC?Eq(bq&gTJ za-gJ3QWG5A0Q`*xu$}lD1$f3aU<E!(g$XJ@K&w9>wITl68Y!AmEz;6VjZBP;jLZ|0 zEX@p(L2HUZ$3=n;`ZP&4wKPpmHcSSUCB_!!#>s}J7O9}Yax)9lG!sz!+Z=QxqD7)f zVw$B%VyZFdBq9R?1JgtkV^dRuL`zdkQ$uj<B^#M1g6<khNi#A}u}rbFNJ>hxGyo0M zl2W>WL%BG$urxI<88%A`4QVUn8=)X#*n90*%z!AzRn~wb3#<$4fHtmX4M>|Vj$vQ) zx*riCsmY1PCP^lVpd$fO63tT5lFZXA(@c^K%uJF&J6g;WQ_{>#K$F2{29}0NW@#p= zDV8b5$%dAuCYFZg=E+HkDamPu$!3P8$tKB$7Di?k7HNr~O@bDt$rj0`rpd;j?Fy-h zCI;q)mWjqDrluxI21#iK=7uR2CPt+8dEmqNWab*!MKfUS_@e=GI2UN@1C-RwK`SLd zH6^GC3kqs*J&M_*C9;qM8xCCvirk<wgWpVntwo%NdFu=!3xXGTf)_Itmw*n*haNSP znN|rJ&w#I-Bq#ZR{Hu$1S^&LM4O+K>eMmhMbb}kHp$lpSLx$PWQ>TJLc~NFbDtOXE zH?br?HxqR63P?R@OaPH~Q%p@$%nU$X^JGI)^W-$p`4_2%W}q_xLAM+vnp;?aZsY*< zzm3dH(~>|3C?+SGT3T2drKTF0q?(u*8d_SKnItEhn5QP0r5Ku9q@-Ay8iG#xGfOr# zH%kG{&Zn9hCK?$Srlo=E^%P^nR0~6kM8jlDBT_3{P{WJNW*$N-xQYcIL5*_^8``P? zrCNw;aDNFl*GWWSj-eFVI{}%9sF7i+K$96rlczA@%EY2{aP}|+tu6%(mSWD3Aw^}P zQF3CUQL-UuzofZ|nV})*s+*LQG|NO2LsN@HlcZG8tv3d#CMIb{MxaBnjm-^`Ksz%n z3`~;DO)QNJObtO>k`pbG4U)}32lIl49@El{lakGnjg3qa4Gb&{OpH?vEsc|sO;gO0 zQ_Yi1OcE0lO-w9}OhL{gsa^opmf$jk^okp<6@T#q%5$*30Vv?XQ3-0tf(jsTde9%7 zQE6xa+9?S-K`lAWBGJ;s%plRo!ZO(;&A`;m+|n#LE!h}!B7;Gyfr+J&8E9Fhp^<4K zXh(Vq=#XCvBa@^Q(7G-2q$G0-3nPOh^CYu0b5n~nvy>F$WTO-lQ&S5gOXH*@Gjp>P z(732kTB50CGU(2`G|LoYQig7@-kk`ER?z$`+Tt0I5U2rx){($%2v`HoS{|XVIJHC< zyeJP8&)`)%&>V|YnLt|Vxrqh3ptXF-5S1p7n_m#w$T%rE*~l<0)!f1?CDkk~Eh){| zG}+kFGSSf7BrP#9$pCcpFKAOnqJeR$g}IrfshMR;D(LdXB+z1z<Yc3iBxAEg(Dp6^ zLsJ7&6Vt?0BjZGi6l2pw^W-#hBV+R<qr^nZR7+!1Gtj7<ky%=ji5cjeLh}^UWKvqe z2=61^TL}w$WAu3?&<GN!@FyYcL1y4uZh){HBkVyj49a3ehCP~6^qn~1p)XL9M8uJy zg)!(hwM0YE*15#A)TC7Kru?K7lO#(MW0SO$BvZpglVsym1JDqtVXCF2v4xq5MXHfu zl6j(~xq*pgTB4bOfu*sfaZ*Z}foXCgXr~kC!XpzyV-piY&^bdX7Kz5mhM;SBEG^AI z3-2wB6HQXnlFTeDK%q!%QHKa7aJZMH>XsH|g5wA@N(I`Wj1)@fO5#9O1=^xpur|zQ zG68!)SqKq+Nv6rEiHT{Jpt-5E<Rl}|VFrdNpoK6di3Uk&DMp57<_1P-#)iq378WTM z1}30e1T4~$QjJZGlTA%iERzh<OidFF&5ex{(^8VnOe_pQ`?t+4lTAPy5<rK_Sr{ZH zn^+_oq*$gUC#ED>nwo%C=q6bhrWlcOz8O;Bz>^s`^y0voTt@-<_Esz^(2iRNt-}Mw z9yp*8Q>%!;Lp1`d95v|7EE6qEQcNu^42&&IL8~*<(##AJLF<Xk4b4GY7(jEVCZI## z3@waIl9S9049yZPLFcuA4*#~aFfdCtH%c-~G6UTMYhYlUY-XHhZfOBJ^T60L(KOjC z*~r|`!Zax<Inlx*6;v=7B!N!KHZ?Oa0<Cf;VRQn?SKu)Qc*zG2KtnwfJwwpVB*;OG zMO_?NAzC>O76Y|BaR($8qaeD_!qd>uz`)Gd9Ncy^PBBhOG`BEIG)+lMGXSkBPBb?G zO{7|yq!}B5&Ra=MH8wU+OEb1KFfz7GGcYwyvM@I?GfOs4v;^(3F;6o|GE7Z11Km&o zx*)(HG0Dsjv>w1DF)7J3(ExO=Q4**VmYQsAX_%N~Ny4s0q;NthqQIdEDqPX7dIJmL z%c!_aAzb2uLmg6-fNC*tDM4<1mttXQYH4n6YLu2@VUc2-W(>M)!Nk<e(l8M;CSa13 zVq}<>n3!w`Dn2bh*Hf4nn<X138Kk8cfG*fGwM<J&O0i5#OawI`4U$a^OpTHg(~ONw z6H|;+L6f?vhAD<gW+ui)=BA)Up@vE3DW--=iAl)@DJ0zwg*O7gwS*z)NCzU6f$q;C ztPD$h8iLXbIP|d<9@rz)5a-TzBqxB)gvThXj7O^(F&i+D9EGyU#4^R)0CY@^WisfN z%M=UaBy(c}i?kHb#eOEnhQ=1=DM_X&NtR|wDdrZS)?!kciAAcRg|UetsOy$uoMK{< zYHpTfnQ8)Bnhlz)HA_rNO-(W~O))pNOii{lGBiy#1g%j@NincUGXu3O4H7{YFq(ii zToYeFfqFeTnMwL-#d^ibiFqlRkTv|EyLHj7Jq8P5WF@@%abzN7Jtc{tg^r-!KV)7F zw4D-kcwbIVDroBysPMN$30hFoA;r|vG%3Z%IN8iB*}}pg)gU#^(8AE%+|tm**eE3_ z$viPRDaj(m1a!r>d5S@*d7_a~8u;`sGlLY9L<{3I(BM#tnPG~F3FzPnGeZMI(CNA6 zX%=aqn@bJM4J`}}Ow*E#EsRZ#k`hx>%nXgvQp_z=O+k(!ve|*=O>hwf_Nb1612(xh zkR;kVYLE~pV8BTep4_qN2CGCZ)(s4eOe{br{v=waSek=QvNAF=G&MI&NlHphHcv`Q zHZw3bPBXJiPPR0%G_XiYHcU-UOH45^2QA|_Of*e2w6ruyN;a`DGY4JWm1b^cVrZFS zU}^?xb*Ck!q$Q`CCYmLunWZEp8zdT=nVMRff+o2WO)QMl%+f$3s-y>1d16jBIH=-4 zn;Jj|z##b+RT6E(4@f<z1B^4Q;JU#oL1Be$>;cI-XpT^_Qh+6X1qIOXR3Uf<7qV#? z(V#Q5G)OixF-|iyH3K!{(u~Z_lhTY5%?!*f5+P?J8K$L}7^j(7TBI3TfX=H*GBQaq zHcc`~GD$Kuw=hjMFiHlUacY!mY-(m=X`W=6XqaSXnq+94ngUvpl#&XX@H0rVG&4*# zHnK1=F*Y+vNi;CBv@lCaHU;&mi4E?8+~k~0{WRDp4rovfZ7sAOWOE@}Sfc0yg$d3P z9Fz@cp!yM%lR-{Ix~tY)&lqhRl!<|<fw_sLnQ5xIQHn{jWs13xg{3j5;sRalVv%Z= znrLWbU<NwnH8I7^6tsfh)Hub^+%(n1&^Xz^476Cz)WFi*Alcl)I3>v-#T;~&sbNZ@ zMOrFo_S6V;q&8@03uud;QF4lzMXGV4xuuy2=&%nXBT!BwEeLb-K|4D#;cNdv)B5Nk z37J~P8j`5mL0K4llMrUI%*{^8ECTIB0kyb6Z9WBsqRiZ)#5Cw!J*Yj6NQtJP<?}{H zpbZqDoh62#GfYg9lZ+D$5{*H($Qzj_fhOZDjV)7B5)Caa3_v3kiRNbJ2B5W;iAG5# zi3WyApk=h6ZH}gCW~Rx8sm7pobTa5pIE&;|Q*$%WEx$%dpyX_snrv*4nrfPyYM7Q{ zX>374#z&uzgyeh!JtNS3E^0u61;HEdQG*hz5m3dTJdOw!b2H<_G($r(<Fr&0(Cq`M zmPwX|CMhPVCZ;A9iN>HdRHCtwg?Wlml5vt@TABgq{Ed`E<7CrB(AnLflc5a~LFcKP zq$U|!7+G3a7#bU<8W?~t#WDl6mCY?JLD!b2BpRie8KxSg85&w785<;l_Jk)IkQOZ9 z^<<#!y!m<XY-)h9$`X{`FzRI3YBXfsptObK=sD0JoNh{LNosP5l>%sV8dQiPLe12` z$T%s{&^$FI%_s?U?1rg@k(rS(XlqTXWs<37DySZ|FasS~l4zNjW&k=T1Jo}_wFKRM zl4Nda4mu0PB+<ysAl1Ui+#n?-1$0imnT4rgN=hoIuVHGEVs2z?02&%KH8M6yH3#j! zGfGYb6`RJO#vYM*66SBDRd|r}1X+iNnw%hFIKvLz42W`2dcw?{;6(|@@dYaHzyXfZ zasdtJCR$pgnu89?NwfeT4r*YSoC=;oOt!GFNJ%y^OR`8yvotp_O9mYZYXLe3F&Q*- zZVB3`XKH3>Xl!9(ZfucanUrXdWMl?9=HJpX*(fQ|$Rsr_H96HH)!f`NDapXX7<6)9 zs)f0+Dd_kt14|1dP^m#=K$hg^mn7!o<RzA*>gVSrLpC;HX_<ghG-_tVt`n3>K|zN| zREa4T=AaAAj0{pzjMI!vEI?-qq*#LHFOm(64a|*_j6kOoCZ&Nc>Pt#YOHDQe9mQ#p zl$4TamTZ`4VF=ofn3QU2mSUP@WC%K!A2bJRY-*WkkeFs-U~G|SW|5R=XljsboN8!h zX_A&|0=jHB(ExPeWC|#S6B`!AknP6cm79hJ&;+Gtpoex_5vX7WH4f3j1B-63O0?iG zHcm`6Nl7+J1l@aL0J>`<*&;F71a#P+1?aTj#8h+Bl*D8+Qxnjt*+kIbkC9P|WfJJj z;8Y7UW6+!>=tQ6-&@hLYsb#96Ns?t+l9_=esI6yaVPIimm<U>Pm~3chZj_Q{o@knu zmYil_4m$2Mg@luWOHe#ygf}?AXO!Rz4~TY9ctCFdMWheV5&xhm6Hwd7+``g4(bOWz zBGo7*&Ct-u%re>3*wWMzbR(ICMUrKriJ7^vg;|=VWeR9uE6ps~+&slFG0n)_&@$D; zz}(Ep(8SQl6tqmz*ud1#JjLA5BE=MR5Q4Fh38<Tvk_OsV2|5qRIMu`;(b$-jO$Dd{ zVuA<|jL{kc@ctuw;Q`SN3J>s^Ux?r^v@|j|O-r>fNH$5fNHGB2@|TpFVwPxWmIApe z&nVTxBFV_e0CXOwiJ^s=fn~CZvAJ2QA?Ttz!=yAr(1PEjG(&TP#1z9MV-rIYQzOs< z(Ig8)L(>$CloZe&$>fx@l+;ASBqMVZBO?RQMTEvF$(BipmL$v&q6UW<A~?{B53naO zN?&Zc!75R+i*cd_Xa!M9ih+r_iKS_hc_Qd0E@N}h_V*Mc10zfG<Wx%oV+(_{G|;W@ zsg}lR$>u4>mWh@I1}RA?7Ac_n$5Ty>)6&e6OhAoIOEYuOof0W&pygo}<`zb#mIfdr z42_LITWk$e%@R#5jV#iVQp_w2ElJ5Ppjk4=^<(kzpgDL*fS7}($1yJXG=i+#L`xx9 zO#q+Phoe4+-5_0%SX2zVUK)A?AZRQDJY|oV^#_{-s$@ZOpr$}E%(>~Qd8tL93oEe9 zih>P^kB1$Vibn<XR8P1HM4~paOfoY79dBxGW^A5j2-?+bVqyeZ&uEsE0@}2amSSj- zmIgYiBgr5Y)E7-PH%>G&wlp&{F-|fyF*Y?eGfPV{2CarPGXS5QW&t{>1T-~nlA2~| zo|uxHlx$*Xl$e^5YH5&^WN2uVnv`k*&Ol})6?({V01p;$RBEBND$MoFz^BCEi9=NV zU=5(ujjdS$4rS!1f+P?`5Q2{D1zm4z3cA%b(ZI;iFcq|P$TG#iEHTyG0Ca*0=*R*~ zLj%w`a>hx<7HO%VDYew3)U?DDi&O*4)Kmk|^^K;f25BkA$tj7cDaq!>DTbf}u}wjz zMVMI_8l+kpnwg~<rWshKnk0ipC=HS<%uP~~lR))9vDGMY5W<oT_7F4yFW$uyf+*U} zK||>H0}weQ!1nROG6^`vgW7AL*?o|I5P@rEVwsj|kz`_&Y-C{$x>7hT#mFMrEH%Y4 z$;jL+&D_G!)F{Q&(!eA&8FXBNS+a$hVTxsHnz50Ikpbv#8q;JW6QfiMV*}G<6C=aK zWYErwG&69E%skcDC=qn0f~8TKsj0EK0q8<NBhZi@==fzrQ_!u^#1G<uJps$MC`a9D z=_o+=hJ({md_0OQ_`obP^b~A}?IIK0R)B8_0@qhWC1GRmK?;aaPBAjDG&MFhwn#Ec z15FJinVXv$SQ;Cpf(}73w@5WlF*GwVO#)rcoMvK_Vq%$;YH5&WY6?C)+`z&#CDG8> z+yr#Tm06;BN}`b|=ui(!Q&ZDqGgAvQGfUH?M3WT56q6*AR11s5B%>tDG-Cs^q~sK1 z(^LZkQcgaB1Od{zBXIJKGXX7hM-4-e5NM4Rwls{cAFLKv`h{2t8j-?MekL0mfNp3_ zNw!Q*G)OZsNJ%p{F;7ZPO)&&Dn#~Op%?vFqjZ#3TcbJ=*r&^??7?~u2&bUuDN=Y>` zOSMR{FflYXO-)HPFfd3mPc^p$od{)+XaqV_5!4$=u}n!aGe}KMH8Zv}1>KUFoNAbo zm}+TgY-X8~LP~!EocXaX^8kk-B9-D+10Ed(P1Qoegn&Y{DMwIe4CG#H5rW$!ur5&4 zAW~~0XaL^S!ZJ10%rx23B*oa!#LNWLH!(K?-GXOfn39%gkd>I(Wv=z%(({z}UjV zD8<asEY&E{z}(OXwCmWwFwxY~GBw%6!YBpQRxviUG)y%#Gd4D}G&8a=w@6MhhMfCt z2HJ&eZkA$XZVo!5GC37gPm@&OqIeFn{0S1`s0kJ{c?Bx`2!;=m5nw%_(7~4N@kA1q zlx${dW(?}R7^Nf|Sy-eRCYc%;nSqZVOH8x0Ft7mMu$Gc!X#kq0G&N1Ow6IJx0Oey- zqa;&vbJHZy6%dK07Kw&t$)<^^W+p~yNoHorW`>DLi6#a{sRrhWmT5*wX=#QjhNfng zpq*@>tG>*VLAT_k8H2Jad7%mk4(Rv{BtTHs(}ILR3o-D9E3zSA4I~6AL@$;gO*2eP zF*Qj_HnT`GHcvAH-S?hsZfR(0VPTeJX_RIGIs?tzz}Ps|)Y3f7GRfEkbhff-Vsc7S zs%dJ9IcVXsDY!FjVgS0#-P|NOB`MK3$t=;#IN8|5C>gXc(Kyk}1av!866lC2vqUpX z6T>tU(B2741JFn>NkIx)CI(KKkcDXI`PWj<6lbddt`)ox4aWc~WM3a>1u6Jw0`NpF z_?S-AV-e6BSm1NGK&S5{TbLOe8z&p2S{i|FH%Lk~O13btOtv&KN;FS0N-{`H1nn|O zOg1*Nv@kSCF-tNsHZuTCs+c4irx_)if!1nTBpMl;Cz_h1B^ss~8l)zJ?iEb6FajM> zm6n_YiXB5s)5J8Blr&Hy)yUA2l-n#IIS#UJ7JMKXBs4+I8nii7kPx=6Ik=EUHvpm- zlp+y@An1I&l$5koGtdG?14E;<WY9^EM&{<0CP^tK$>xShsY&MMW(J0!o7zlGQ!LC= zjZ;%i%s@*X4b77+Ow*DR%@a+MOwAHg%|N$ZTNs;}CncpAnOLMGrKB1fo0=LM8-mW^ zGD!jLRWM34N;67IN;3mZY#UmT(i;W)2~>ZALj$d`ZfK!r2x*RB%b##vP-UoLV3L|> zXpm-MVPIroVv%HEXl8DdlnmO)oMvWj0osgilALIioSJHoY-w(8l4fXRWNw-WT8*BV zYG7_*XklV#nQWYDlxkv_VrFD&4qC>U2wE*@n3`y0mTYEhWN4C@2&zp?49(2a5{=DG z%#17z!6$Pjo0)+3I+2vW;J%3idB+TWT^dvnvqO#=fKX+qL1CVlVrG_NWSj)L3dzC( zbSk8Uxg}`2(IVBr(9+D@(jYO#*woa*GRedobn6(Xd<RW_TPCI$ny023fr@w|15m%+ zEG5m<(9A5^D8<|e)EzMcT?v?&WNeaR1iBK-*bH>Oo0+*K=>EAR<5aV>)T9&=_NhVg z2sqnk!nZ-_8R}uobem&2`vHq)BR$YH6exqdNhang=4OeeMxZLpG|eK#$TTIzC@s|} z(KHcspMi;SQlddBXyhg>EhWXkAlcN?Bss|>Eydg<+0fF$DA_30*aS5BmuhTcZe(F# znqmnm7)%U6+dxc=j4cdIKuaSH4H6BKKsBY2QF2;Za$=H^iJ6JHWfI8^gyPiPGFVW6 z=Hm>}#%aJ}pwb*$7D3VsQHPo^3=EPD%#BP^Oie(?JsPEfsw0CWQv+k8v{XyO<dj4+ z6GMYk6ALp7&|!2brfJ5epdsu;gG4hk6BE-^<5W}gv_!)cvs44~)Fg8YgEVtXqf`r{ z#AH(wBTEyD)MS$sgCx+Eb)cKkj4aKQ%q^2r3@wr@Ksz}|@0}KxBqnF0oD2dUxJIeb zL2W`@H9ER}uv*k0F)}bsO95SFWMr0PZeU`T0=it;G}Xk?Bn31^3%Y>b(!jzDbWR22 z#1sRAq~zpeQxnT%i&SGX&~Rp&g@vJ+MPiDHG3ZGABm;8;OG`^ra3-`&GdE2$GBq|z zO#y9A1l^6EWMFJ=Y;2Hbo|Fj6jHLD{!K>e)H$7l0LXAM9bGTZL7@8rfQ9~rjC=E2G zX=nsm-IQo*W^Q6)U~Fz_X<%t+WS*R6l$@GuY-ya52;Rw-W@KUpI<e3cboxnZqNN3> z$VoC!wM?}zGBGkWOtS=?Y?x+gWRaYdY@TeGn3!Z{ZUh?eF-S`@G))0t7HejfoSJNu zlxk+4Vwnh<I3=kd1$zn{6mf>2$`O4L0!YjVWGc1{gU}4tYlL(998%bTl|w@xOB>I? z+}zmI2y}IdxnUA$4XCM6nxS!;sinDrfw5((sj+Dyc#O<6(aazz(bCAw(9i_5yb&~E zWN82ju~f5EbMrLNf*Ffs12aow!_;JRi{w-b3(FKUlN8XUUB=0vc@!h#)Fjh1Q*#re z6jNi+(bp-UvWmpSlnlC73+oZ`kl=)z4UgI}frw$RmI#;!(F#gz*g7bX6NWL**ai&+ zfzQSUw-BM5Ku~NdPR=g?ok*6Km<}FYh1i2rIVdI}Wr~uO0s*z4-AACkCP>N<2gw?P z2NuCQNDDGjb5nJ}7y6Wdx5tBWA*g?g^@QoX#FEk?&@F!Xxdn+usk%9tC7=Vv4D}#~ zhNCUW0M#I%bLqiu0k19q<ytJ~cY%sU_?R(D2qDJXV252QC_us+cA^;gWH3-pft=e8 zJFFdj`#s`_Fi<EKgDrtri}!pmqtw(ClSGr$6bmDBOG{IO#1vCgV<S_eR0}iEF<vI- zX=y2`sm7K`1}SFd=81;JX=bS=sYWRlX2zg<AHn--ER56A3@t2EO-)k_KwA(}OcRYv z6Vo8=65~Wm(BNIFiJ^IlsfmGUqLE>0Vu~f`vhXBBQ&2>ZQlx;r1<MzZu%kkTKr#rD zoN(m?M9{+AKt>8jOSRbY4T?P_MX9N%`2jtlqo)N(ywfuofmU0ZSVE4%HBB`#O0!Hh zF)}kS22I=>q!^`Gq^4S!n3|dzry7G!HcL%3HaAa7F-=J}GBN=jMQmbboCX?WOG*VV ztxhybGB!_6u}n=gHA^xA9rj`Zx*Y)2+5z2zXlY`RVwr4VX=a*iU<|tHoP>kTP=XeG zLkCI}f>RST5rBdberGF0jEK?|r*Sw|cw#yTEP@*2*b)iy4G_qx5uMMZ#N@<eBU97V zR8u2E6N}{3R5Q^1#;HaYhK9+Y3m}b5O$;p!Of8ZuEYl1V4Gq&wk`0XwjMEZR(@a2B zqCujek+Hd{iDjClsi|3NvSEsOB4`xO%)}r$)x;Qd!;EpFA*eHEnqqF0Y6#k&VxD4= zmSkdVVQxZdZv!QBg8~6k7f>E0*v%p>K46Z+%#GOM23#W`M+)jy2%ut*go*=}lOc!I zqUUxpOMc^&6vH&o8rH-VLkn|DgCt7>gGA#LOM^7f(f*bOCW$FYW=RIApo^JO4O3H+ z%u<umj6la*fG&MCGfhskG_bTVGch+Y0JU?{Qj<(T6ABhdMoA{7=H?a_pgw1cacY`H zih)5=N{XqGVTu{31rA!SXkkWi;(&}KLb4^94IxmvKrsfTdum~noM;HTHa96L$q;l( zdSaS+Drl?*bb+)%iiM?xrHO%&u|-O<fq{{!sZp|#VPcwbs;Nbqd5VdJQL>pyvT?Fm za+-menVBg_F3l*>5VQp~$<!h#$t=|*#WK;rAjvS*#L^Np91H60S*Dq$7=dP84M@5D z0PGJ~0tJ_8C?cRFOPx#vX;$c_7NZ+UT3$lU7})X;uCfhVHUb@MmIT`H4!<}NbefYc zNEmz^Ib<yfxlK1Rb60AzajJ!>k%1v-cTl2bVoFL%Qlfcsl7+EJqGg(~u|cAFnyG2B zxshdRs%3I=nuQ7IlD%Z3G;<SU^CWXKgEV7va}z^TqvT}J-LVFVi6#~)hQ?_r=AZ*x zp=<e#6U~zoO^i|v3=@qE5<!C{hKYut1^CG%tj<MAD&WKeF1#pDFc`+*NF<Qb4XJwp z6#(mp^f6!uDMOQrepYdQo-Sn1J4gYjbqrch25(~PLq=O5a>jawpgtyC5+$Rc)YgR4 zB{;B%R0gvLlvhx-Ks^Yy8+yPPXq*H~5=AfTK}`}OI|ztofQg}Tszr)PQkuDek#TA& zXqGn(G}&urlxl8imS~t}X<}(?kOZ3RNHtANG)PVb6=G(_NtPDIpp{L@M#gDopp*1W z6D^a?%nj4b3=L9E4bn`_j13GeERxI&Of8d4Qd7*5K+XF^V`F2`0^byiR7-R7q|{`J zN_ymifbt}X%QPG*6CB&HXar{sun5-3L^c}S6@-kIBVxhS%mTE3#=y|nB-PN=IK@0E zH7&{1GRf4`%+eyw+|tkzw3QIlST;5>HUzEtG)+rQOiD9KHAqWJvPeuc2Q6ALH%>B6 zHZe0#NdX-PoCeyJnQ98UnaeQE!YB!}=gBPD*xbShbPr^Txw#3rCzqU<Vg$+`#Pzfi zlM<7_K@FZpMqBa#8m9xz0iul9z;%FSL7gXrx6RT(w+Ez|q@@`fni_y+8jZ{h3=EBo zEiDaFEX++!4U<zrQ$lHp28OBN6_$zS=AiAmmKNrT$>s)zmL_Iq<`xE^U0()ihTv<2 z%s>Nrrm4nemIlcdhRMmv#^%XsDT$z)UM!Q+Obrc^EE1DU%u`Jhjfp>OCNU|gD76gY zanKk6#+pP!%vm)gJ%*rVYN%dM1TD2lO*SwGja(WU8YP<=nj08{_G2d*B_<nz_A47$ zCYdK0f{y%8Ne0dA8k(gTn5P&USeO`tPO~$z0JRd#P0Uh~O;RjOlG4nQ3{%ZblS~rL zLAUj$87C(h8<<)enHXB885&t6Ct4<gTKUFF$!Uq;t$#$ucyfMG9=O6x%z?Crz^h%* zLI70Cf{H2BsK?L>Rt5?P%%P-2kYe!J=dh(kU=dx=W+Sk$0eCI}k$8*}jX-T9Qxo&V zG_w@Y4Jv5{$)L&Y#N@<8^JL@Xq~t_1a|6(1cdCJrp^;%)l0}k*nW1^IL0VFZMN(pt zL6U`;r738P)Hp3A)!5V`G1=V01hgQ|EYZ*eba!{MVWOG2QEGCMrFoKpNs?i*QF3xp zqNS;6G6}~$L;R6dTmeZxrh1^02tb83QvVTh0~(glgK2~4!Z~~dwu8W^5F+T3L3@*p z5-lu~EfWnuy=Vi|Br{7>V}nFvbMTcuCI%*;iN@4qi&Rt4DpxZzvouRn(CzhxX2z*T zi6&`Ah9-&ThH0SdrOl1a4bnixzk#`lxlxKyT8d#Z=$0$cm9qxMDF&9tsm7qCi7A$* zDT$UAmZqR_Zc-8-C<#Eq4m7}Jq@w`#EjVSsgbmT}|FM8x42LC1;l_d0fKnqOWDLzg z7x9@T8yKdfn1imBO-?j12aQ;mT7cHZ8=57WSXf#bn_DEB87HQgCV{5d%*-s3Ko|2R z8W|><8(Ny1B^#QgCYz?2CYggSnl(={Gd46&Hc3o10L^$OCK;L-CR-RArkI-;rX-u2 z85o&B3UtH76i^l-A!HD~H-H8TOvFUb5KY7abkQ|9;9zPj&?hfJmxF>@LzrO()&iCW z1y@pL9w_-LK;pqlAt^IYA8ay87YTGDS`z4}k)$*;<J2@mGlOJHGjq@`7tpzpsfp(1 z7Urp@#)d|gMoCE)M&^b_X2!-QW`;(|puH<8CKi^71}Vu#$>yM|j}1*hleK9EX=#a| zslcQ(Bha4hBy-StCPqn#W(KKA#;KNO2BzjlNvX-HCI%!N?UtCHnpdKmlvoVepJAq> zfF=?Ly3rJEJ`XH}KH`I>53B|hV3?&Hbd(O%*GDA2G*hD_GYfO0<YY^;v=q}cGw|y1 zBy+>mG$YVeEr!YF$tKArrY4|60g{p}6O)rc9qnXGi{!K<W6Lxn&>B<YRLjIfV`Bpo zV^a%b)6~?IWD8Im%_Pkt(a_Y$%skD^JQ;LfrzvQ6ma(}h2qvW@CYzA3IvwoK?9|kP z#GK4BNT|hu?>#~7YlAN;#TrJadco@Oh7)*kAgI^?_3;W)K+8`+Q;Oip0`Q$)nN_K} zxu8?TKwDBlxd;)epe;M5#-M|pk_`<L4a_Wz%#tmP%?yl8Q%w!cjFK%(%u)@F3=9%e zl1$CgKv(#gniv?QB$}rf8>Lv78yFcT8G|ZR3v)Az6iXA!6bmC0(2+)_W~QL)EK)#s zA{nP7rWhI-SQ;578krbdni-j<CRv!6Cz~0Wfm}^wmQGJEN=;8JN!3j)D#|Yc=Q;49 zDQI;qY(qV2HpQYDtPp#+Cg-Fk=IMebT2TTsGcN^{8H!7aGV{`*J!Fs%5W#6^XkeIV zYz#VyJ2BD7JkcmE(IVBrBnforkGWy0nTeSp=ypOgb4yduF5P5f&?Vf-2Ii*5#>wVM z#%YPkX~~IcCZOBAlM|DS&A`VyS)`d8S%S6(q!}h#8W<)TCK?%8CR?VOSQ?}zrX{DE z7=lhU1?@v8p{be$ZLpc?fi|7#C?p~Y80n$y8Zgr{G}6Otyh61=WU&V&Xd|<3N@{9> zZfap^B51QcDBMA55VFY`a-k^JGx#8@q!bj8x~#geg~i|t(I88>6%<N~G9gzMgK`<D zh(^SRg}I5Pxlw9bDrj-Efl(r8g|CINxuuDPVOmm(af)G*X^KIjc~Xj5iZN)#Lkeg} z-P9N~V3%fWY-*HflxUcin3QB@Y?NY>mSU8gY!2Gvm6Vd4Vw##_W^Q3*U}2JMnUs`f z4!Vle(A3y0#n2+nG6j4}0tu^EK{w&R?n#2AZIEZs7N~)W0+9bu({>)>h9$60uqy1a z0qTV5rll5_fWyxSa&|T%v@DH57jT*w8CqB-8zh<~rKVUWrzDxAn5P+87=h3Au`~f) z=LedSFt<!LHvui0NHQ`?O*J$E9d%`7m;#!NFilQ0H8(dhPO?Z%15NZA7#gM}r6n7g zTbLM|8l)x}C8eYqCnu*RC#M;unVOrXC0dwRSXzM3JSVa+0Qnhw#3I<oaiAGMw6FpT zVHB^Z`oL;HA%zG6qr^m$q$E?5<is?i6f+~EG{eNSl*AMROA`}AGtjy@qeKhi#6-}o zKuH#fX^EzwV~z|=Q$ZIxn;4lHCL4k;B{jA%H&0GYH8KUQA~FFrpiRMdBATaIm|7+q z8d!j~>x1?~gEkYHr<$atni{1hnUOHI3r;Y_C6zg;(0&K_PG8h21}ua%43IQ}6@daF zCAA<GRKO)?rWQk5Fv<Bj`9+{xvp^?lf=?r`L|<2LVVandYG9ZQ8rMikF*i>#OSZ5~ zGd4+0F*h|fOi47gFg8drN=`Dh0FUdMf(Gym%q=a=O_R(G%}k6fl2go6lR$?>8Kjt{ znkAW}StgsBo2MCCCW4M6Ofof1GXU|-EzFV(K$k_NrC6pK7@M0LTbi1g5kFXm5nP}x z$e?y1C`BNJ2Ba=U4MtFg0u}R^*$zn~SP^l-2<q#DN<c)aGc`0$GBHUuPBJnyFilA@ zG)Yc2F-ipO$1_Z|FaX`9XkuoT3_8})+$1SE8MM;Y%*fot*eK1?(9*)x+%Po>v?kUt z6=VkJur3pGGgFH+lhjm0b3?;qLo?$P(6R~>&~cBTTQ)#DN({{tL37p?Mybi5h877K z56RcyoQGBe!)~3%8(d&Tpx{CTLW()4;xkW9H83+WPE1WS105S=X^@f(8rQclOieW~ z0o~AKmTYQnkYs6|mIAssCJ8jJW@eF^nv#}cnPQr1lmaTJlR?*m8zq5`S4l}TO-oEO zOEWS_1Z_Jqut)`6CY@*j+9GXWl#*m>X=0IPW^7_cLfx5H3BLUdQucrrQyZfu7*G|5 zv6?LrSr=FZ$orU?E-$|*H!%m)WGhGnUo-%+0F?X`6bdqv;rFhA5)mlg5aDN>YG7iL z20Cay#mLOm1a$K`Xq9BDNs4)*sWIqSej~_TD`|=5X(^VVLqk%Nj0}y84bse#OpPr- z7ks29rkR==8k?n>86+pAS)_ul#WXQVGEOo#GfOp3G)qe~G6bDYmS~)4XlM>P^U%yJ z)!4uYG#^d$LY>5dqWq*pNa%sai;TewH9#IhOG#iMjPeVi8!QhBMMNNgt_?~C9kQHc zVrm51L6HcWA5Tn6F)%YpOfoYy106wTW@un!kZNdd3_b(b*u=~fbT^P$nuWOuXupn8 zibV>jqE9nOF*LL^vPeocPcbnvO*1kFE%!1?v@l6COEyR{1}(Ks0}Ui5TNr|-e=QP8 z*!~V$BU7HLTauAll&V{qS^^0Ua9pD&CM-vLVAT!MjALPXN@@<c@eJt%z*<&Csfj7D z!;e!FbHRhJ=;zItf_JGJnOK+^q=D{OH%>}TNlh}dOf*Rbon2&VZfs(1oN8faU}$L$ z8tYE7Of<4EF*Zs~H8D1~G%&F=23;Owo|tN!Xb4){0J=TZ*buZE5Ht<~nhj4iHMcM} zH!}pS1xqzEH8e6bPqef!F-`+*j00sOB8#S?bVwM2_Bx>@B#;ouB-A1assSvCmWoVF z64NYFQjF8g3`|YTQjAkg64TNQEKE{NObwGP%`D9fQ;dwv%u~$FK-UR?&P4`ocStcX zHAyot0qu1*O9L&Z1RV=yW@4CXX=rL<mSzAxI4#vY*~l{0)X3Bz)zUHzR9l*wni_%5 z6*o<>G)^)%Pcs2Im1s|cm*7Br4$4ee4h%2^l^*C`M`#1-GQ_dVx457vGp{5K+`O&> zDFih?5xLDAbXqy+h*{%ABa4(&b0brWRPa1^iiKgSrIBfJ8h9&Hib-N3s5mh&OEk6s zEx9%@N=r^MG&V6XPBbu2OR`8zO$AM*q!}834o*!qNi;J`Ni+c8RcxMQY+?aAhT6c? z6tpPWA~n_2+&C4q2GfLu>c1!*;bHLTJX&)RRFr_~WZc07R)LyKER4-eKpPB9ER9nw zEEA1PO+f2kP0c|ajWkdRX<(QHx-~e(AUV<4Fa^|ovjp8iW}0Z4XquE_VxD9Sx*XUX zw42M^(7@6n#l+Ci&?LnoIne-glSpccr9pCH3h3H#W6-giiKYg|W@e_TCMl+d=E<qV zZ&3iBm#bTvmzkdjNhzRHmC*7CSO}xAEh<W^MA8UWgc=B@NucJxv88EpQlf=XN}`#$ zi6zLhW+?_~sfk9$$tH=3CT5`e#5l>=*djSK#WKwTv;oa15wsK{(a6{c6rpBGpd&Ud z(u|B#4U$b$lZ*`v&CN_e=_NTe%?LC`p9DHrz%nJ-)G{U2AQf~np=FvS3Hvk>i!1Yz zvooP3tpR9ZB5Fws7QzStWL;ntsNOeEGPg)JF*Qs{GY74gPD(TYE%GxkN(BuCrx+xq z87CQl_K2sLrJ5KenIxx~nVBXhnJ1@OSXw5frlc5~m?WE7CK`fvk*6A)nkJd1S(<~| zXXZ&priqD(hRKHJCPqo7pcVKjmdT09$w{F356~csNt#&_39~e1iJ3Xz(jL?cOo5!C z4DCCBayHub1h5cBVBj_btR6LJj0{qfz-c@+EyX+qbUsm%Wl~a-rKK@w*KA@^im_RW z2`C8CQVk72=k^$zSz3ZleM>bmH%&4~woEcIG)qo4FgHs}Gfp!~Ndn#QY;0s?nwDg4 zkZNvbXbhU^N;5PuGP4Bj6iWp)nJo;AlarGzLDyFj-5>$)TGoZ{@Pcd(L(d+TdXPH~ zQA!9jo#4G;IEqr()qb!`6+lz$5cS}JI@km~*hI)F4j>hfGaSGwz%qDmL4c|#N(G&5 z3-S(V^a|!~%md}Yt9+AFvD~IyjCL0{_Q`bE?sm|L6A-srpmh&Z6VsB+QjE=0Qj^RL z(?B=kCZ!oCTNoG_nt}=ib7LbzQ{z<AREwnK6m!sNerYD=DV9d5rpX4Naa)Tt^E7i) zOVGAp(78iqpp(&!%?(pi5>t%LERB;>EYcE<K)bpO%*+gvO~AG!8Yh~APM<L|PfZ~{ zb3j8br!+k?PZzeG6;f1!FPT6sD8NGKc>}i*VCA5!f!WxH1z|>NPC;rBEOJXrGIKy{ zT_JOc;K)~UfVnEGSU)E}F-148G8xo0Ps>aPg*_<yfvS1XS`8$Xh?O3o<JCcxH)w@V zNn&17X%6^;8npY`44})u!56BeRwU<?rhry)gU0GXrXy;8@NObYQ*&brBSXtHBV(g9 zgT&P2R6|2UGczNL<mBYEG()qLBnwMJb3@R%LCHy`28PKgDWHpGjLbo|e}Yc_wJ=OG z0_{ct9YK|5l4P7}4%*R}XqjS~oRpkqV3Gp5bjZLwCB+nUwY#OcG3Z1d3j;Gl;+L(W zL<=ZS=w{?+7DFomNd7~OT!<Ln*hMo2q62>f!%mX`#T9556R3#?iYu`5^g$&uG{TL+ z=l6i5z=E*z77%&NP|pz5@54|58ybb!U;rMjMZ}kZrDc+-k*SG+xp9(NQnDrJc;6JG z6ay2}#1zo6^cJZp#s+C=7Kxzy+CaCprCOw>nkT0iq*_`eS{NCmfi^U!q$OFHgXUSx zOcN7R4bn`K%uEy0%t2d>j7&_D4a`9+VNy&$XJ8u`fNr1wb<52x3{6S6X8;@^x&@Fj zEV;C(2sGjj+E=JsT$xvr2%RPdCwJ6%0|{ZY;D|B}tP_9q6+lV`h!b?dEeT!t5i8J` zvw-FuSe{1Jla!gBnO6dd9LUiZpcn+ZPajofa!z7#v2H<8enDzcNoFeCbkrn+swXqI zAit<YH#fB;kr*o=L+apZ45EzB$xqKrPR!9wEH2JW&ja1=s0(r(=-3{j^yii4<YX3S z=qBeU=A;%UXXd5D^%LXVywcp%qReF7;#AO~y(RfY#AwP-$^zYpS(I8_qFY=5>gp1u ztDqz^KM%Bz1$6VhZc=7mN@gCogf-X0A8oL!<aLuX5;OCN)KrpRpqrCgmYSoRSe}@P zl01m5b0M91L{3jJG_*(t9j;|!X#whk8YLT8nkFS%n1c4r8<?9V8JQZVnj3%`nudv> zy=keSWiv)87NFJW7G`E?1_tH^#wKQFW=6)QrpXqmMy8<qdqEe@SfnHyr6gLUm{}$z zgEqBTnj{*efc8tLn588qnOPbdCnpns=p8ui!*V*PNQKn5(9#q%0u5gR0ujSeCPRt} zxB(Eg*t0X#N=Rk~>3~!QsLdp(B8ahAN+9q+I3(1`jU!W2GqdDGBXct&b2GDKOJhUO z753)FDF%iXDMo3D1{TQ%X~}73CWfGOuAq&Xpxuk9=7yG*sTQV&sfiZgYxT^`jSbQa zj8jw0Q$a^eCtD<?rlx^zbxTPxG_^D|OfxbwF;7WN1x>XYnx=v7EJ;mCNis|%zT=pb zn3I^7oSLGGG~fv;F3}ptAR$oW0<CR~p%<(U6g7zC3O<I?z``QY2y}#zMWRKbrDdu? zQktb<l0l+T8fXiJd77aG=o*F;OV9#`Bx3`UlvL0eNTwF4Nhyiu$>v7Mpsl-U28Jn# zDXA%miOHtmt^(*T<1|w<votd^gA_BPq!eRNr_sdB0<;zabS9r=3JEg^Nkxgtsk*5Z z1)!+}SU(!Hb`4|1#ZV9P-~(*BL7E{)5@I$CQ3D<+$${?r%}Y)!(alXPuu?G4gA5KL z!ZR%~%^0-EEy*C+I4wENBnfoej|J%5ZPOH^M9^)T29_2Ui76>*Myckh29_ylpu2$* zjf_kUEkMgCK$8zCMoFNhhl%Evpqp@v(o793O_NPc($b8~(@f0Lk_?S3EYnhrQq0X$ zKv#I0CV~3vCdMY9z8dkJE^Ofm8Dv4t`%o{UrY$U*A$qYcNW~eNh;U0ZGX%AFj8ZKU zEldqeQ!UdB42;c^jFZd^4J?upO;at6%s?k-n;L*dm6J?OO%0M$3``PD%nj30LH$%q z(0S3R=BXyh=4qCepo|N;(9a|>6?FP&TCxeKg_M|LXpoqi2HIEzx*EjD(%2v|Eyc*# zI0e*lA#TVIoRXmZcF>3~+R_`a5JpJ}3NDBquskRWVy3yY%$ywEqQty(P?I0L7!hU3 zQmRp+MXEXIRunViG~*PL)Km)#^CVM{@6*hT4K0m9w}yi@@|qbMrKBX8B$-*HSQvq( z*wc*D(ku<kjT1pTI+Be|j8iQw%*+#wEkS1_gSJ_jrX(jBgT~O3ERD?#Eltx>lPr@B z%?yoGj7%+4Q__-COh`BrKdC6cyg0R}I0xR&H_-#lb)&Wy!D65hM6`s3rWc|Ndw?Y; z=4F-^BkgrH&@(nLFfcSR0Zk?;D5U13CYKcD=Yj5lPR=OG&&@0a4YGsw#2Q&Z8u8$k zZBc4YYGN_?4p&ej234U73Z(@ppw%wOp3zN7f|dl}Azk=NGh{VZ3duQ{dRfINQD<px zYHDd=2AZk|9d4LtXabr)voN<bPfSfou>dVmF)}v*ofwduYG#%S>UNnX8YWvLnp;{J zfi4{b?MwtMDl-CI=aH6Zm<&33!U%Nww6S@Lxp9(#MUpA#goPB)-EyGA=u=G-O^s7b zLCbH=4L~bLh)mqYx;gpj>Cm$x4D>2c<IF%0%QBQCG(ARoX4s<(ycPx8^aT%uK^F3W z?|d}Ut3U~{6l0U5l*BYMi)1sCq!a^7OVAB6$;PRPW(F3?mWiM?6KG-)Gz(^tWSj=N zOa*kVk);V}?@Fqffdy!JWSXU+fpJ=rQL3qdF{sA2G`9ftr;IF(Q_?`o2@I1gOh5<C zStgknCa0Min3x)ygATGVBPqn7fdv|x#Te8!)B_bPs42V{MFZCI5}YbC^GeK2zzann zTeuNrr6uUJyJS<)9)2@p1A}A>GtjYD$;O~l+tLgSl8h1!jFSvNGq#{5h-M~9si~=n zX%<F_p!Hu#7D)!iNr|S$X@*9|pjE~uM#+Yj1}P@SmX=ADCT5oApp*4M2Uw?>CmE(D znwTV+873wgStJ{q8kr@UKr$DR$*D9gEwxBDttdYi(zpaQKrq@ahTyf+sDXs05mZ%! zk5NDbf`N&Ng{hHAqNy2Z%WaAYs1;_JnwDZ|Xl4N#-ZwW-G&L|YH%bQW{{+nqfUa0K zOEES`1<!kcjtB-VdI6o$WNK!bl4N9(YGG__X#!dbV4Q4eo}368B>_nrTUsWYfv)`n zZJjeTOfxkDoxV+UMVk!T%bEdQh-e5Jj6x3qkQk_Ui4p|J+Q7PSp1zm|yRZS&!2%^i z&`=SmcMFw(-#-A6hcul*!;$&rc}1YMH+;2XTCr|!W?p7NVlil<5@8f{M;d5>GblYP zC}ie=;x)fK5A9%roT5_Q<iz9*NDXEVPW_<URpDlWCf-5C5kgQGdK)veWCb;2ktEY{ zN{cg~QlQELNva^TAT=j54`dZ+T_vPE$8v>20i>xG2VQXk9?UBMRRzVVx|w-tIhpAh zB~bGrUc<O?K|!IoxG2*~Ar5h-SV<x%+(6L=ZfPngl;&j?mO}1;%}dM$ISEvefZ_p> zU{fp&O$;nk%~DOxQ$UB37$<@jd8Q;Mn_5^VTbO`$M;Mx0B&J%VCYq<D8ki=7Hcgm= zuCW1~<DCdOb_#UBW1?A_sS#+wleq!tOvh9s^F%WX!&Jjm6BAHvVQQF^mIhiSXJ}w# zXl7twlxC4;Xp#yFb>ea@=uUHR&l@Sv>L_3lMQi$iGB+st(2{XZ4#F_75*)QdX<jm@ z?+;cCjuA-Vsi2UaTB4ho2O2FY2H&j<HUy=%NV7;aHcUyiOfj?sHLgvPK#O)#%?(V< zEi95v5{**KlFZUTSBNC1r6!xCnVP308(Ai&rkI!-B%2y1nplEvEJ!vpOG*RnzA&>i z1|6)Q3fionVr-mhmTYN|XbdV1EE7}HKo@J7B$}jHni-~Aq?nl)nUQb?5hxJB*TqAE z7StF-D-1vx1e9(t0uiANtOOK@h_q#3Zj@qZo@ADolw@KGI{78h(hPKUu%Sf~=zL#` z#56N=b3;=T(3L=`=Ef;TMn<41+(e7C6wsVdnmOpiPqRb|6C*<d3)AG3#1xC<6i}^T zVP<A(oMf5=x_ibn(Zs~UB+V$*G|4E{$UMa~72L-$G))2(Uc{!Y+|-<8*lPAT(8dw8 zN)s%E-hfU{MAimYf*Js+W~pgu$*D$WNtU4PA;!rDX~qVICYGQ>*wTzlj6vrH7#o0& zvr7T(7dJJuFf&d{u}C#BFa{lg16qb|X#`rBnr38SkYZ+G1log@XkcoZW|nMXY+?xN zzgwDHn3*JkE*S)!;t4vG+B7W%Gzefs!hr#(K8Z5}?F2z>WSQwfHsGP90OSAwD?tqa zi)2eP&|S}#2Igia#-NSapv5(&pm|Lrb2CHGrG19xsfmW*&AP_sX(r~0$p#h%pfk8F z(vr=LlFg0HEKQ6o6Adj>jSS5#K+}XKmga`WM#-RKmeNd<lMT~MOp+2U&5TpcK`U>Q z5>3o3lfj3x8<Q{%jNE94<N{EBhPB&Kg90IAiX~4V8vkH(kQJkbjj5qwlChZq=$;7! z^CTnC$`~_COJg&W<TOjOBnx9x1M{S06H@~dV@o456H@~NQ!_IYBV%JD&@fw?nJH-V zJ80}a*}}-e)EIPGn`x>+VzQ-ySt@8lLz;<MauR5ph>3}*MM{dPg+WrXv7w2%MXF^= za;gytmzaXDQ3rblyhg%6M*&5|1brWok)8==+X<lsEDZ_@%)TaQ5JeZVkPy7=$Ou|h zrxqtC7NkONV~5<L4!e*DQvDW}7J!Dji$T?PKByK1WkyisAPS?@WMeZk!xYdl<mTpS zW)`6R3uzYS7O5#oDV8QC7N99BBa>8vG)v<|%jDFwWP?;AvqWR#BtsL^G(!W>vV8;4 zmO;?69&<x8&?+#{x#Y%4;2V9w2jQienpheqS%A)Q0Ntr-lx&=qYLH}LoMK^+461^N zEQ~VX*N}l52dIe;v@Qu`7HU3(YXM6W6SyFSpa4=(zz93g>@r9S5q4>*=BCM@`8RX3 zM9?y<6cba>-3OM2Nk)d|Mrn!0NuVPFQw@@nEsf0$QcaUB(o&NQlTFRclPo}M>@6%( zLDw~<q^5v2mZq44?n+5EvPdyYGPW==NlOLoGBirEFtaeTFfmHCGzQ(TXJKTXY+`7h zYGIs4{GG_j8Hq)Z^Z`k)pxj4PdjM4*L>o$Fo@8ofoNAI}W?*cYWN2z+2wtsbWM*b$ zm<l>r(h$7+)W9MMl(!7hK+E6_Q_L(aEzHx*j1p556O&WTL046!fsQ7%0G&!{4$AYE zNhT?lrp87l$(CuR;B6kJp!>c}3{#Dh3{#R*QVdg#OpQ!aNZ5RuoB?V;L%a`e?xCh1 zun<N?hR_3+2PGgx>?fO=C#PAafG+0)Uo2&jXbL)H!4R~WG%?jI)xy9qEzQ&-Ej88B zEG5|@DJ{hyB{>OnS5Tr^aw@3sF#;`RGczzvGE4?7^Dr?4-HDcFnF2a(J;}%dbjh|! zikX?2iA8b}=$L9V^VG!DG|=&#NvTF@#P?}3L5=5ph~Ggg*fCl$khVW+-a*o2tY@wV zUMq?4ytz?|rE!X>p@AXjd@e%^Gf)KvI=C*y0({efMWR`%0cdX9C=GP?v>9lHTT+_2 zv1yXAC1}M`iXrIS$P`1<L^HFrG>c@DRO8eXQ!~pn&@Fsv7A7XCmS$;|2C0T7hDk;# zsiw)GqyNo8X~hI|voNUjPh_!?RjiwvpHiBWs+*Hq0qxC0Zb?Q>0ibRPW(k5#H&`WV zTCg-XPcu$4FfmF>F-bE3oeOD^Y+-4TVriI~nw*xDY?5Yan38CalnlCg8+2DRs18d3 zU7~JeU}Th-VhFkq$HXKNbQcilmdun?bAz;G%QWMZ)I{^dloZe@Rf%S%7NC`nmT8Hg zd1lZlzG;?5#>R%psi4xH$lyTi)`Fx5NWw-NM1~xMftnuBG#Y{1LMUZ{QDU-1a*9!s zQJQILvZaMtqH(ghiLoW<2vG~uBv7?&2p+L9GE6j0O-r^gFf>m!OfxhwO9Tz*fNpO{ zOtmyKGBdOQ4fq(F8W|cGCm9<hTY|Pd7#SEFnVY3rBpX>6nHVM|rCNfvhZ!U%CK;L; znt(1=0*wR`8wi=Dkjuv7z`bPDga8)8C<=05TENnv*vG7=Awy)k<(VnqwdkNtNuUZt zK>;LDpbM(Tp&P3~=~qFayeJVa3K~KNDMrd-mS!dvpbditpylbQMi!<?=4PM)G9%FP zbn|4hlq3@qV<Tfz3&T_sBg16l#N?zDgH#JM6I0OIf5RkW^TgCdOLMbC&~g$>(?k=? zRC8ks6VS4RRI`+{BqJje^TZVMl+<KX<75LP6H}8!P&P9+2AzLvN<tSDTC|wxnW5i? z2NuEzONe@~94H_WUIs;Zilvc}v4NpMYLX>rW-2Akz%0=cv{WX|C^^kM*&@}z+{7Z$ z(g1V?rv<3HW1MDeW|W!;y2{Qd%`nw8DG9W)ILR2)STQp(H8KV*zfQ9>GXq`uX=Z3_ zoM@b6Vw`4TkYZ|Sm}Z=0W|5i#IzP!2JWfnx3d+v`4Oi=yS?DI`m!%dZro)DeK*KYr z=?PS8g5n!BJK-<@tQa*=K-b6_BpQN_^fm=`8%<5jLC2PxnSk!uNlZyGNHj4{OSUvh zG&M^zwM+!9EV4{8Gqf;EOEonFRi`PbCgz4lrpBfg<|(P>$(DwuhGuC7ps7GJi)15E zXVW0b477#_)VKp3f^KXI*~5@*VV-JALfL}60}4{Q80uM~Ckc=cs0)f79Ei<RV69+f zpn$;4X31cCAVW8xu||+-h%}UzVx9=<`I#rDq*_{}C0QDQ+6*ZMrpcyhMyY0L=837G zLp+i|)12m@18YFX&KVn7B$=d|8YdYUStObmS)`>HTO_5WCZ;BVR#Jj4r7|-$Fitc# zH%qj%G&3|cNU|_UPDwK|GBGeSN=!4bNHk5hNHk6~BH@^Qh&Ph+^FSNMz<vhzBhY%- zpz;}8>Ol)Gurk8IRR;<$(BK;)yv!|A&5}}*EYng<%q<g*3`~>F4MCTmo11|493~kV zC8bz`E|gEPv`97soeyGekOI1W)YvH1G!=B!j+ue6iKV$ks;Oy`iE)aVWg6(v3=?DH z#55xVL$lOWBLm~)RCBY`)TBhq<g`RnQ<EfPbK_L=H1m`sV-jw9fP@z)+QESZ@(J2j zBCrr<X#?7qho%js-ZHREHcc^3H8xHG?I^P_H83;<b#F|}%uEdoL6=k{85<ZInSdtP z%}mWK5={&&K=+m!Cz+cV8z&j0ni`~n&Pqu#v@|idFtbPntywlSFic7^Pfjv7H88R? zH3eNbU~FuhWR_x*WMOD*k!WrVy5SCVQ5FfC<<UX_5}D|QjiDYWezD{(lprtxr4>XX zNHPF*hfOU_jSN$hObm<+lT!@Rk_?iQ4HL~xlT(w^%*@l0Q&W=@Q!Ol$%#72_K(|2} zCMPFaq!^o+CMBj>Bw3moC0m-AS(t&YU9n6wGBY-^v@lOGNi#FGFibN@O}0p}G&N62 zOH58pPPG7S@Bke~WNc^#I_HV_wk$aBL;GgnbPxxQb<9uzl?qrw0a+_VCzk@~*a=Vz z2((-Plvto@z{gQw%nl}*8=IP07=o_m1>FX1oM>d0oM@VuW|(YbXa?H4Vw?oJ^xeWZ z$=uj7$=uA?B+($*$iT!r+0ZOGHO(Z+$imDt#oW}~%);C>+1N1II5{N+)Q>PTGE4() zW3(_$H8ZjRWgbh5BqL+vMAPK7l$1o!kv*2i#Gi7NoS&PNnU|UZ8XibZM4HmEKo2Ve zJy6pLEvzs#gQ_MAP_n@+kyBE05-Z_WSt)>bzo52eOf1t9O%hX+Oe_t}OwG(wjg3<i zEeul(EG$3?1axU&TC$}<vUy@sYO*=#%nH!$qK3()iHWAk=9X#3rWPhirb&s$DXC^j z7G^0%W+^EtW}q!3rp88=$tKC>CgzsLCdNjl2FYoupmmp~NlC_LW~qswQa#C>guZe< zY{dvTd4U&=poSP&2(y^Mq79{(u{1DB1RcC+VF{YfPc=$QOfxjL0Il9Nw=hYvv^2L& zN=z|IH3MDwWNHptmIE3put-TWNli*MGfGNMGBh<b0NucwWMl-I{4@b|laegWOh8M{ zjMI`*EE7RD&n1C^26RTfk%39FSz3~5l6g{^aUu!*#r(YD{G3$Kg6Wc?{2WjM%FIiL ztcU>THnjdDC>wzy8!ZLlHUz8zl#&ny5a@`m6wpYed77n3s#$WHxn*)HXkA^JL9(f- zp{1pPS&Dg@X_A2vs06hzNlr5{Of>|J1(<^tJ%BDCHBU)2Ff#|O5wSEfHcK%w0$oE2 z8n{YMGc~kKNis-Iu`sesHcLqct<g<NGEFp1Hcm-RGqo@wVRsO;zSb?yFD*(29XehB zP9|}NpvJF`0&Zz@Yz-l7!3Js$pc@Zr4S}~xAVMr9+0-=AFwMv!B?Ywb*u=s#HO<i2 z)XX%^BF)^?EXml!C=C<>pyPr-7ciI@r==Pv8yh5>nVY5<m|CQO4j?izPEAX*FiQcQ zOk`+bo@8haDwsi6exxRvCz)BMCK_8Lr5c+gfwq|$CxaHG8zvc;S{jqEbP-pOfSN35 zDG4luC1+s^60lm-L}Uh<RJSxXPD(XRG)l4n%@|pxBqk@C8iKn_$%ZB=21dro7Dfi3 zy>})SCaK0oDapo0CMm`y$wua;CaLCzpmT>oOEpc+Elfb$U{gQ?@}>sH=Bc2Da;kBf zL9&5?iJ4^@Xt%wIfn|zO5@=trnW2F(2`%NKRM2vjqSV6D%p!Qt!4NZrKxWlYGZv;^ zP<}!ipGmY#G&D6Z1}zjYNU=yVwM<O0FiSHrGXQk~EX)l+!!V!=D^e_tEG-O;O)V`! zHz66CSQs0oS{Npq8iCHzO*1o00u8o-X6y{oK=))ACmJQ08z!b&m>OGvdf=&`0bMiD zp>oMaNl74WX=av2sc9q>Hbwcx#k$1>iRIAUcA)JOXxpp6LKw*cO(R$lC_P|SPkEWi zsk$Xa;KN(>V7oRz8^(3BQ$d2Dqy%bXBb|(C3f;h@pirEVnv|HA4n8<EF%NWL5NP}d zlyMal$}=*PArsz4dZ1NIh}@ZGVQHL{WRPNMmYf1QPr%eL#lR%h%-qn#G$|z|CC$h* z&C=4u#M0E*Fwq=zgGx$rQc{YEk-4Q=Qc|*ok(ouZp@F$svRRUGYNDxO3TQK}sRigX zLn8|VlO#(M&>TogT9UDOYI0JNu~BNGMXIR@Xg?unARr0k7$SSJXu$~HMq{L-kc>?n zt-TEzv%qX-p=ksw!X7V3Q2?GM1<&_mhBqjBP{SJ}0*Ww1c$=9UCMScsv=$c0#)+V; zn`R8!DrlUTYLu32VG6o^(g3uKDAh8>%+N3;HO(^7%-qz>*wn<_$js0r%`n*@HN_w` z&BDOa)D(0aTZ&1lxe;jdI_T({H1H+ONd^XH$wsM(pgB7Wi?rmlR8S;>>Lt*?A(7!- zTnwJcfz%pU=aeC9K2S3~vMz`wtZR{qipo=ybd!sV^FeFp3_x`fN*l!3FwM*obemZU z=z#mw6iZ`MbAz;0Q)5fe%1vYQBnxv3Lrde76blmz^JHV=<Rn9*lq3rS0~63yYo^A@ zMv2Cjpl~!Zvao>MV{U9=k!)_1mSkXPU}%zJVwPfTWMZ6>k_I|~1aum|rG;gRg{e`p zfmxan=q3x|f+;1jBvH4t2zE{+))^lx;e@IUq6=$4fzA?zuBHJEbb+#RVo7<rZf<67 zDrheec%BVn0bH)M2y`TqAt>>Ik|QGV85o$QT9{cTnI@$fm|L2em|L1yCK{(&CK;xr zm|22O)HF&lO)&x;*<xUr3_5SZ!qm*tGAY^8EY-r;!q7a$Bnh-h$lTN-$;i^sAkhT0 zUd#Y=On{+rnsK6mfw769kzul7a-va6q7i6KcA}AqNwTTAsiA2S2}c2e&x!-5JQE!S z1SbwW>xCg=h$dpJXM`bQj3I({8W!lN7mN-m!fLQI_R;}#2pecs6DV(??;SuKmksT! z!KOIDMF`%jNQ_gG5>t#pt;|F-lQd%!6Jx_f%jBdqgCx-YOG67&<J6QyQ}d*>G$RWO z(6VMjQ)3fji!@V%v?No|aTZ4AW)`3;!%{#cu8~<%nu%eeMY361nt`!}xuuB(XbLqs z%{0k4(Hyi)+8k8IgXZ4N3=9&@4M1HjBC|kha%OH~j$Rh5<qg_UjaC91g2m9Q#uQYY z5JjLsMkHBKGBq$sNlr_&OfgJJN=r#Lv9K^VFfy`CF*Q#!x3EYuu}C&DOg1wxPBu<6 zGc`2<Z>~-@GyttQPBsJ`HJJ*!BG@1~%`(*xbZ=rZsE2Ewnwn&2k!E0GYGMKE(Ih9E zrlq7MCZ&Q#Ly`>=Q;m%*Ko?&T-QiD3O-apz?m#rq!)Qc<g)sdO*8`SE^*U%2)X>rp zbcd#8qKQFDin&2@Vv2#Gp{XTkh9=FxG&MQN)Dm>(F{t5aWMFOpTC0<0X=-L^U;&zo zwXiS%T{e(tX#_gJHOa)l)WX8RBn>p!l?a;XF*7hpGqNzYG_p)GNi#DvNinoAOinRR zOf>_IF_GZ))B@d1XzYWwq=GXWLaYufhTb>DGX4WTQVwbmNDtcJPijh%nQ2OjL5g{b zVUlICi2-N^$G`}5s#Kb>L8>8W+#)5#EG^mG(#X;v)!f9u(%dK+wAjSJ($K&x#VFOn zAQ2RF78XWkX6D8zDW-`A21Z6kDJF*Ipw)6o#%77;mIkS*X=cWWCdnpA$%*EsiJ&I6 zrGbS3sB|DUN2C_yrWU0`Tg;&O6|`AwP;mk(n^7uHkoOVVz)Db4M6$W1g+XePX|icj zs)30?lCimAnqf+sK?-PTiMcUooCcJHQ!LX!OH`ASL8IyxhDnJQsi~=^W)^12sYWK| z7AdJlX@)5V2IgkQmWF0VhRI2(pmX<4QxlU@5{)g*4b4I45~ijZq?uV*8W>ubfNF}A zBts)m1w?EBq-Ex%B5ijBm*wC-IXG?Lltn9)K^+EAu%iVNHtk@gpy0x6R%ax_cV1TN zrldk{ZOAVItwuEjO@n~TV(8Ao?9@t#IHX5|D2PCJil?R-r&*>Z8Cn{H)(4v=r-5z_ zG)gf_wlGUFOEd)SyGgc8OG!>LO*1h~F|#l*GX@>(XbIZ-WoBVyl9G~~l4Nd_WNvD1 zoMdVOTA-4gYG9rQx;Wd!$RH7PXF-Z-vY8R+e3TTUWW$tHi_|nzBlA=v;>Xia$GE@& z4;kh{&44hUqXjMU_!w9(SRE)_5kUbu%ofxjNHt1MGEA{BO-eL1NJ=p^0-e%eW|5R? znFL-GVPTY(Xl`I>mS$?0209%lCB-zw%seg4!Xz!t+|)SP)X>t*%)ksZ69&2p!Zg(c z)OSrW22G<`8iCG`03CLlW^7_%3|@?4kY;WU%CDe&Lu@jH9*_j~3HHf!NZScL6d>m+ zfwf@?fJ9S6a}$#k%Oq3dWJ5F1^0j0G6H6l#b5Lv>rGZX<F*7$Z2OTSvl5Am_YHVm` zWS*9iW|Eka0@?>}Xk>1loR*xFmSkj*2D+Z!z#=&rbdbHVS(>qlVM>}YXk(JGVWP2# ziGh)kSqgX?j=7<^k%_svVH)u}{Zdj3Qox=7&)5(%hym9DZat#Ldty>js-b1FxtT?> zCFt_i)YKF+BMYMxi{w;e17kx&BhdCzBU7VfQ;QUHL&G#P6EjOA(2ep&#%Y!Yrbem8 zsfLyYW+o=a24-eSsj10^29~B4#ztwNgUmo9iAJEYXk+6v3(zLE6iZ_RQ^Uk0v!uk- zG}FW+5^jJ=Ni6~G63$C42QB4>1OTKn0vbJsZ$O3h<<KG@LoZkzT2Q2#C8wBx26PQU zRdSM{nMtxKXcWo}v_CV^DA~l^($o@k)LJs=o)b&Ultd#FLvzza^TZ?zgA~wYv6+dH zK^o}jX3IpwWK(m{$()HPCWeMdCT6ClperXqQ{F}vhRFs728p0HieZ|GMRHQArLiRm zm$|28rlsi?rxuo`<|V@pl{B&ht?)xF4j^I}4HQh>5QV6rVQ!FUnPv_e|1?WWGBZju zPc;IyK~ob!Qz;e($;rlsmKGKUNycU-=H`|Lmd0jgmY_3q&67Ygb>>OtMy7_T2B6(} zDaJ+?mWd{yb7jno%?&Kl!0p{c3&S)MV*}G<qa+Js&`Kt=Bv3{$G_|xaHcc@G^{|O7 z5HS4%Iv2)753RWh_9VuL0hX|YC`1hnBa0*>Gt*Q9leCnSl;kw?G|My#LzC1r(1AFh zgRV^zEmKmH4NT2U5>3r5lS~s+Qw&WEQbC(V(vpo$Oq0zF4U-d1jZ)0bQp}A^6OEG- zlT1xhj4doIk}M5D`!X#OP0T@e(}NB&10B+yXlam^XqskXn3kMEV%mUY4p0XaZ9W$y z1nSYCW{%9XG_Ve^EULHDKzq`YKo_B<nt={_N;Wbw1l{vvVVsm^oCaF!0bW*=oR|pe zwu7#yFiSQxGEXr}O-VC1GBQp~G)hWJ1ub&`Ek#Q-G&D#uPct$zN=!*gOSUjE1=X6# zCML-iiI!=gBQHT6O3+y`mdUA>DMkh)6pEQe;L9Dr9s!>=jplVwQ2|O*XkJIs1y%v_ zK4xPBJXQqlnS(+JR9hjc&a^}W(^NwXV<Qt&LxU7^BMaj+&{BHP>O(U_(1^Ds=+5^v zi<G3~R1-_XM5DB1Lz85X`eYMJ3nL3N(EY_0M#-RwN=wkNho!MWN+Re=@FZgcGjmI0 z3riDA%Op!fOG6_gOH<Ib1s0~DX$GUzG!rvYdf@rVpuG{$7A(lWXtf7e2&23})&*99 zJ&;n1OF^gMKnFHJ$qXroK+`M6$%*FXX{knL$)I_sL}QB-3q!M{WOJhwGZVu!Qv-uE z!!*kzBhw@c<5UaKa%c-9kn$AJA~aJA<3tP4@IzvfSz?-nX_|$xiJ`GYa+(EbKSG+B zC1{4lEHTN_$TZE=C?zE^$<W-?1hhyg#nLjF_~V6A@^e!wl2gHFOF+^RIKENKRj?3d zFrn!LtHK^s<*7-TDLJ4yE@-_4YMz3|Dp3<wN=j0)A!x)UCC%74(IP3)z$iI6+0@d^ z+}JcVCDp>f*xVF!rF@#9kx3Hh^xiZB)08yRBok2c#oQt_%_Pml(gHkbZfOW=sTi18 znwq4V8K;0Q?lm(uOg2wTPP0fdOa|RZpOg%`#lY0a60{#K&Coc7_$dW!+h-x62i-x7 z8h#K#&|m~gZp3K{R6Qsx5lPC}&?wc=$j~6o%qZC`Daq8*IK?o{)I8A;v>(>Y1l0R6 zO9TZIXwE+wbmbgq)tO<MVIpXKIp_d)LqiJ#(?kPv6U#)CR5Ob-!!*#PMP^1umPu)r zDdtJZiN<EBhH1to#s<d5W|p8Eh(KyVJFk)riJxRh&CM(+NiC{`1c-s2p)va6e25r& zf<n;;QGyx*Mo9)1mWfGbpc4l{OXw35lhRDm%+d^u%q@-5EK`#$K<9y&nxv&9np>us zn53D3`oU(Pd;ZLll1)+#%?!;F(~>NcjEs%INBJe2f+}i@L=#h^G;_<Ov_vz|>YGHf zv=lRwR7;a2&|VS4Gy_Xx(7hDN#P=LibMvz@k(YpjmNB9gJzycsAVAd!R)iV|DJIFL z$;Or`riqpoW)?}NX`t&N(hNYODxec8j6v(yK?e|<nWq^Wr<ofjrJ5Rou9Z(UNwzRB zHZ(R$0d4s(Of)kxGD<QsH8)H$Of^k2Pc<|K^^;A_K-*y~42(@oO)X7Q3_vT!jgvu_ zzoeO(8KfCnf{HofnklJy$@!oYYT(I0&k(JF0va7L#Au+P=z}N$g#czHl?j^bgx%&0 z8hr=34Uu1xk}NIEj6qxc(h@B|S5uj#ni^Onr<x_2TBM~Vr<q!qnt^VHPf4{f1|8{b zlx&#_YN44WCmSc3CMTPLCV~=E6I0ENjEsyx3n@%YO^iUpkZCCfX=aIu78YhkX(`}q zO;VDQlTA!5EYl2Ajnj<H4NX(cNysmGC7Gbplpp~GzI+?C_y7xGBo$;`U=^THLU`Z8 zB*n<oz}UzVbkK%bl8HfDqNQ<aih&vEZYq-$&<(s67KWy&CaFo5Nv4)*CdP>dpoK!I z$tlJrMiz#kBOH@WER0i9EfPVeX_$iY1gP*aGcYzbv@}Wr9Uy9G4q88IlxPk*6Wh|< zAT=q~AkEkiw5*)yfw$DWGF?!613L5uS?Y|^#Q_OnG-Xh=ft8>JfSG9$sB$m`)gwuk zpeRfPU1MqhI-)Ph*up$5F~!Kl%+T1#%s9o+z&O#;Jk8QD*)lEF#5fsr`n08)X)@>_ zZ=)o`<m4pN6mxR}3()z1paXJ~O;Qa^EDRG<l8g;Nw}zw`Bqv##B!Uiq0bN&>l5A*B zd=;Ep1Ukt+1=>mhby?BI*+4>=*#ub^SOu#0EkKu$C8ZjHE}u&^G)gftGBr&$NJ=(J zPBb&NNHR}MGc`0f1fNi8Y-DL^VrZ6XmS|~gY?+i|o&uV0vjF+nJjK$`IK|u|)xgry z*wEa}zyNaJx3O6gsQYVTYG!7ZWMrOXZfOqcGn<<m8k(9VCa0Q$2E2$YCqS2`=%&Jt zPs6A!3_%xfVI+TKU0@X;?_((>iXq2|W`g%hgHCAxr6fc)Nj3!a$CAuU(=3xg2m633 zLen&Zl+>ieMDx^S(<EclWFs>(P_QMNrlgt}8iDQ>OGyPS<46XbscVv$YGRUVYG`0= zZjqb>TJ&IS1Uk~&G!ayVnt~2aGE1{aN-{S#GfzrRHZ!tJNis4u11)DvG%x@;hR9$l z)=f+*E-6Y(hK|o0>KR&s?uJUmlrS<tzb3^Hbj%3IGSmhLnpTJ^>;ajG^?+6IZe#;J zP|HaHu@4$53M!8k6jF<IL5F^p<b&4b=cSh<g6^jQC0LMiz|tl8x&=j<xtS%IWuX1x zhI+6qcWF2`KEq`63X1Ye@=GcUQuRP9F2NQXLY;%TIT~`Shyr-qba7>FQhpA6BsDWX z53Ct7lBS>l+Si|$Q<9MhYN>)o&p;VaK_NXKe2WoC0OI_NL{tSt4bwsumE=RMgd3#` zaTThOnRz9tMWBP<igWT|8}dQf3v^y4BysB|fe(d%PNPCh%PiIfZK(#GCIYs_NDnk0 z4Azqe8W_whOVzDPEdn_K6d91X$}EPoTEIFWa~ohC#Tki3snCOY5te~M0j>`cyI_q5 z2&+Ib1JwtXGSmaF`v)6Zo|>3ll$r(>hg=e<pa31f&de(=NKJ-#*3byNkrOV5Hn<HF z*Mpn@2)_FW=5p{oEConuBrPW~9TK=E(8DZ?6Vp;5e%1w@EDCiDs9OTrNRpS1q`jml zGdC5wDg|<kB@RW!C5c54*Ta+{1%z%+YF;{c&k862Au(B+my}<DmJ48E0$%r`i(~-U zk%nk%V2q4GTeUzP9Yga(Q_~bfQ-f6Vq-4;}(j)^j(-ac}bMr)tBuk5A6JxVf&<W;- zsc9xDDW=9oiDoJ07Kx^221XX338hp6(Dv^X6El-U6XRqPGtd>LhRLP|pcRiMMwXyS z0`pW8lawUTfn4S(=Aa1#5~fu!%L7Qm2b2oY#xTG_7$rYOc>>lCR*Svp!d(zx%e|-t z6)1{8sR2=Aq$Zmfnk5<<S(;cRr=}&DBpD@|S{fUrni&~bf-Y}PGd4>}Nj6SRO93tW z1FbDcG*3)52MrmUn}VuFQ_zYQ&=r<R21!Y&pwrOIK%0AwjS?-AlT$$V6B&Xo>oPJ1 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⋘kAPs#D@u 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 literal 0 HcmV?d00001 -- GitLab