diff --git a/package.json b/package.json index e5652ae..45d4f70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@garmin/fitsdk", - "version": "21.205.0", + "version": "21.208.0", "description": "FIT JavaScript SDK", "main": "src/index.js", "types": "src/index.d.ts", diff --git a/src/accumulator.js b/src/accumulator.js index d7ce946..91762a5 100644 --- a/src/accumulator.js +++ b/src/accumulator.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/bit-stream.js b/src/bit-stream.js index 101a99d..b92e272 100644 --- a/src/bit-stream.js +++ b/src/bit-stream.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/crc-calculator.js b/src/crc-calculator.js index 037198e..a0fec43 100644 --- a/src/crc-calculator.js +++ b/src/crc-calculator.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/decoder.js b/src/decoder.js index eeaaabc..41945fc 100644 --- a/src/decoder.js +++ b/src/decoder.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// @@ -433,7 +433,6 @@ class Decoder { fieldDefinition.size, { littleEndian: messageDefinition["endianness"], - convertInvalidToNull: !field?.hasComponents ?? false, isArray: field?.array ?? fieldDefinition.size > fieldDefinition.baseTypeSize, }, ); diff --git a/src/encoder.js b/src/encoder.js index f1b69c4..51cf52b 100644 --- a/src/encoder.js +++ b/src/encoder.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/fit.js b/src/fit.js index b3918fe..4964ef8 100644 --- a/src/fit.js +++ b/src/fit.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/index.d.ts b/src/index.d.ts index 34404e1..6ab143d 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/index.js b/src/index.js index f89a18f..1f1c44e 100644 --- a/src/index.js +++ b/src/index.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/mesg-definition.js b/src/mesg-definition.js index f081127..9ca66a9 100644 --- a/src/mesg-definition.js +++ b/src/mesg-definition.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/output-stream.js b/src/output-stream.js index 148da9a..a0387fe 100644 --- a/src/output-stream.js +++ b/src/output-stream.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/profile.js b/src/profile.js index 059c0b0..1e7bcbf 100644 --- a/src/profile.js +++ b/src/profile.js @@ -5,15 +5,15 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// const Profile = { version: { major: 21, - minor: 205, + minor: 208, patch: 0, type: "Release" }, @@ -18907,7 +18907,7 @@ const Profile = { 0: { num: 0, name: "weight", - type: "weight", + type: "uint16", baseType: "uint16", array: false, scale: 100, diff --git a/src/stream.js b/src/stream.js index 8e7bb08..195f4f6 100644 --- a/src/stream.js +++ b/src/stream.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/crc-calculator.d.ts b/src/types/crc-calculator.d.ts index a4eed08..d20f5ac 100644 --- a/src/types/crc-calculator.d.ts +++ b/src/types/crc-calculator.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/decoder.d.ts b/src/types/decoder.d.ts index 627114f..0b8f976 100644 --- a/src/types/decoder.d.ts +++ b/src/types/decoder.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/encoder.d.ts b/src/types/encoder.d.ts index b0f4ddb..6936561 100644 --- a/src/types/encoder.d.ts +++ b/src/types/encoder.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/mesg.d.ts b/src/types/mesg.d.ts index 495c97e..26818ff 100644 --- a/src/types/mesg.d.ts +++ b/src/types/mesg.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/mesgs.d.ts b/src/types/mesgs.d.ts index 5422240..0b9b165 100644 --- a/src/types/mesgs.d.ts +++ b/src/types/mesgs.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/profile.d.ts b/src/types/profile.d.ts index 5177008..44d23f7 100644 --- a/src/types/profile.d.ts +++ b/src/types/profile.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/stream.d.ts b/src/types/stream.d.ts index 5bad0e2..cf92bcb 100644 --- a/src/types/stream.d.ts +++ b/src/types/stream.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/types.d.ts b/src/types/types.d.ts index 14b8e0d..f3c87c3 100644 --- a/src/types/types.d.ts +++ b/src/types/types.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/types/utils.d.ts b/src/types/utils.d.ts index 538da16..287b308 100644 --- a/src/types/utils.d.ts +++ b/src/types/utils.d.ts @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/utils-hr-mesg.js b/src/utils-hr-mesg.js index 2f0965b..f729626 100644 --- a/src/utils-hr-mesg.js +++ b/src/utils-hr-mesg.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/utils-internal.js b/src/utils-internal.js index 1435862..7454de3 100644 --- a/src/utils-internal.js +++ b/src/utils-internal.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/utils-memo-glob.js b/src/utils-memo-glob.js index 06cb8ae..5374354 100644 --- a/src/utils-memo-glob.js +++ b/src/utils-memo-glob.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// import Profile from "./profile.js"; diff --git a/src/utils.js b/src/utils.js index 27ce426..3dc5494 100644 --- a/src/utils.js +++ b/src/utils.js @@ -5,8 +5,8 @@ // Transfer (FIT) Protocol License. ///////////////////////////////////////////////////////////////////////////////////////////// // ****WARNING**** This file is auto-generated! Do NOT edit this file. -// Profile Version = 21.205.0Release -// Tag = production/release/21.205.0-0-gb3c261eb +// Profile Version = 21.208.0Release +// Tag = production/release/21.208.0-0-g5209d509 ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/test/decoder.test.js b/test/decoder.test.js index bdc9cdb..d639159 100644 --- a/test/decoder.test.js +++ b/test/decoder.test.js @@ -17,6 +17,7 @@ import Stream from "../src/stream.js"; import Data from "./data/test-data.js"; import HrData from "./data/test-data-expand-hr-mesgs.js"; import { uint16LE, uint32LE, uint64LE, buildFit } from "./utils/fit-builder.js"; +import { encodeThenDecodeMesgs } from "./testUtils.js"; describe("Decoder Tests", () => { describe("Decoder Constructor Tests", () => { @@ -757,6 +758,38 @@ describe("Decoder Tests", () => { } }); }); + + describe("Invalid Value Tests", () => { + const invalidValueCases = [ + { label: "Enum", recordMesg: { activityType: FIT.BaseTypeDefinitions[FIT.BaseType.ENUM].invalid } }, + { label: "SInt8", recordMesg: { left_pco: FIT.BaseTypeDefinitions[FIT.BaseType.SINT8].invalid } }, + { label: "UInt8", recordMesg: { cadence: FIT.BaseTypeDefinitions[FIT.BaseType.UINT8].invalid } }, + { label: "SInt16", recordMesg: { grade: FIT.BaseTypeDefinitions[FIT.BaseType.SINT16].invalid / 100 } }, + { label: "UInt16", recordMesg: { power: FIT.BaseTypeDefinitions[FIT.BaseType.UINT16].invalid } }, + { label: "SInt32", recordMesg: { positionLat: FIT.BaseTypeDefinitions[FIT.BaseType.SINT32].invalid } }, + { label: "UInt32", recordMesg: { timestamp: FIT.BaseTypeDefinitions[FIT.BaseType.UINT32].invalid } }, + ]; + + test.each(invalidValueCases)("$label: Fields that have invalid values are dropped", ({ label, recordMesg }) => { + const { messages, errors } = encodeThenDecodeMesgs([ + { mesgNum: Profile.MesgNum.RECORD, mesg: { ...recordMesg, heartRate: 50 } }, + ]); + + // The invalid fields should not be present + expect(messages.recordMesgs).toStrictEqual([{ heartRate: 50 }]); + }); + + test("Fields with components that have invalid values are dropped", () => { + const { messages, errors } = encodeThenDecodeMesgs([ + { mesgNum: Profile.MesgNum.RECORD, mesg: { speed: 65.535, heartRate: 60 } }, + ]); + + expect(errors.length).toBe(0); + + // The invalid speed field and its component should not be present + expect(messages.recordMesgs).toStrictEqual([{ heartRate: 60 }]); + }); + }); }); const RECORD = Profile.MesgNum.RECORD; diff --git a/test/encoder.test.js b/test/encoder.test.js index 2f556fa..c698e5c 100644 --- a/test/encoder.test.js +++ b/test/encoder.test.js @@ -238,6 +238,77 @@ describe("Encoder Tests", () => { encodeMesgs([{ mesgNum: DEFAULT_CUSTOM_MESG_NUM, mesg }]); }).toThrowError(); }); + + describe("Null and FIT Invalid Value Encoding Tests", () => { + const FIELD_DATA_OFFSET = 24; + + const nullTestData = [ + { baseType: "uint8" }, + { baseType: "sint8" }, + { baseType: "uint16" }, + { baseType: "sint16" }, + { baseType: "uint32" }, + { baseType: "sint32" }, + { baseType: "float32" }, + { baseType: "float64" }, + { baseType: "uint8z" }, + { baseType: "uint16z" }, + { baseType: "uint32z" }, + { baseType: "byte" }, + { baseType: "sint64" }, + { baseType: "uint64" }, + { baseType: "uint64z" }, + ]; + + test.for(nullTestData)( + "Encoding $baseType with a null value throws", + ({ baseType }) => { + addCustomMesgToFitProfile(DEFAULT_CUSTOM_MESG_NUM, "testMesg", { + 0: { name: "testField", type: baseType, baseType }, + }); + + expect(() => encodeMesgs([{ + mesgNum: DEFAULT_CUSTOM_MESG_NUM, + mesg: { testField: null }, + }])).toThrowError(); + } + ); + + const fitInvalidValueTestData = [ + { baseType: "uint8", value: 0xFF, invalidBytes: [0xFF] }, + { baseType: "sint8", value: 0x7F, invalidBytes: [0x7F] }, + { baseType: "uint16", value: 0xFFFF, invalidBytes: [0xFF, 0xFF] }, + { baseType: "sint16", value: 0x7FFF, invalidBytes: [0xFF, 0x7F] }, + { baseType: "uint32", value: 0xFFFFFFFF, invalidBytes: [0xFF, 0xFF, 0xFF, 0xFF] }, + { baseType: "sint32", value: 0x7FFFFFFF, invalidBytes: [0xFF, 0xFF, 0xFF, 0x7F] }, + { baseType: "uint8z", value: 0x00, invalidBytes: [0x00] }, + { baseType: "uint16z", value: 0x0000, invalidBytes: [0x00, 0x00] }, + { baseType: "uint32z", value: 0x00000000, invalidBytes: [0x00, 0x00, 0x00, 0x00] }, + { baseType: "byte", value: 0xFF, invalidBytes: [0xFF] }, + { baseType: "sint64", value: 0x7FFFFFFFFFFFFFFFn, invalidBytes: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F] }, + { baseType: "uint64", value: 0xFFFFFFFFFFFFFFFFn, invalidBytes: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] }, + { baseType: "uint64z", value: 0x0000000000000000n, invalidBytes: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }, + ]; + + test.for(fitInvalidValueTestData)( + "Encoding $baseType with the FIT invalid value writes expected invalid bytes to the byte array", + ({ baseType, value, invalidBytes }) => { + addCustomMesgToFitProfile(DEFAULT_CUSTOM_MESG_NUM, "testMesg", { + 0: { name: "testField", type: baseType, baseType }, + }); + + const uint8Array = encodeMesgs([{ + mesgNum: DEFAULT_CUSTOM_MESG_NUM, + mesg: { testField: value }, + }]); + + const fieldBytes = Array.from( + uint8Array.slice(FIELD_DATA_OFFSET, FIELD_DATA_OFFSET + invalidBytes.length) + ); + expect(fieldBytes).toEqual(invalidBytes); + } + ); + }); }); describe("Encoder-Decoder Integration Tests", () => { @@ -395,6 +466,21 @@ describe("Encoder-Decoder Integration Tests", () => { expect(decodedFileIdMesg.developerFields[0]).toBe(fileIdMesg.developerFields[0]); }); + test.for([ + { mesg: "weightScale", field: "weight", value: 12.34, expectedValue: 12.34 }, + { mesg: "deviceInfo", field: "deviceIndex", value: "creator", expectedValue: "creator" }, + { mesg: "session", field: "messageIndex", value: "mask", expectedValue: "mask" }, + ])("Non-enum fields round-trip correctly: $mesg.$field", ({ mesg, field, value, expectedValue }) => { + const mesgNumKey = mesg.replace(/([A-Z])/g, "_$1").toUpperCase(); + const { messages, errors } = encodeThenDecodeMesgs( + [{ mesgNum: Profile.MesgNum[mesgNumKey], mesg: { [field]: value } }], + ); + + expect(errors.length).toBe(0); + + expect(messages[`${mesg}Mesgs`][0][field]).toBe(expectedValue); + }); + test("Can encode a datetime field with a JavaScript Date object", () => { const date = new Date(Date.UTC(2024, 5, 15, 12, 0, 0)); // 2024-06-15T12:00:00Z const expectedTimestamp = (date.getTime() - Utils.FIT_EPOCH_MS) / 1000;