@marcuspuchalla/nachos 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/LICENSE +674 -0
- package/README.md +345 -0
- package/dist/chunk-2FUTHZQQ.cjs +755 -0
- package/dist/chunk-2FUTHZQQ.cjs.map +1 -0
- package/dist/chunk-2HBCILJS.cjs +2034 -0
- package/dist/chunk-2HBCILJS.cjs.map +1 -0
- package/dist/chunk-7CFYWHS6.js +742 -0
- package/dist/chunk-7CFYWHS6.js.map +1 -0
- package/dist/chunk-PD72MVTX.cjs +160 -0
- package/dist/chunk-PD72MVTX.cjs.map +1 -0
- package/dist/chunk-ZDZ2B5PE.js +149 -0
- package/dist/chunk-ZDZ2B5PE.js.map +1 -0
- package/dist/chunk-ZRPJUEIZ.js +2020 -0
- package/dist/chunk-ZRPJUEIZ.js.map +1 -0
- package/dist/encoder/index.cjs +57 -0
- package/dist/encoder/index.cjs.map +1 -0
- package/dist/encoder/index.d.cts +72 -0
- package/dist/encoder/index.d.ts +72 -0
- package/dist/encoder/index.js +4 -0
- package/dist/encoder/index.js.map +1 -0
- package/dist/index.cjs +606 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +494 -0
- package/dist/index.d.ts +494 -0
- package/dist/index.js +523 -0
- package/dist/index.js.map +1 -0
- package/dist/metafile-cjs.json +1 -0
- package/dist/metafile-esm.json +1 -0
- package/dist/parser/index.cjs +85 -0
- package/dist/parser/index.cjs.map +1 -0
- package/dist/parser/index.d.cts +72 -0
- package/dist/parser/index.d.ts +72 -0
- package/dist/parser/index.js +4 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/types-DvNlfbKB.d.cts +301 -0
- package/dist/types-DvNlfbKB.d.ts +301 -0
- package/dist/useCborSimpleEncoder-ButVU988.d.cts +268 -0
- package/dist/useCborSimpleEncoder-TVxzNJ_9.d.ts +268 -0
- package/dist/useCborTag-B_iaShG6.d.ts +142 -0
- package/dist/useCborTag-BfTIV8HM.d.cts +142 -0
- package/package.json +102 -0
- package/src/__tests__/public-api.test.ts +326 -0
- package/src/encoder/__tests__/cbor-collection-encoder.test.ts +331 -0
- package/src/encoder/__tests__/cbor-integer-encoder.test.ts +283 -0
- package/src/encoder/__tests__/cbor-simple-encoder.test.ts +224 -0
- package/src/encoder/__tests__/cbor-string-encoder.test.ts +345 -0
- package/src/encoder/__tests__/cbor-tag-encoder.test.ts +565 -0
- package/src/encoder/composables/#useCborTagEncoder.ts# +158 -0
- package/src/encoder/composables/useCborCollectionEncoder.ts +424 -0
- package/src/encoder/composables/useCborEncoder.ts +203 -0
- package/src/encoder/composables/useCborIntegerEncoder.ts +188 -0
- package/src/encoder/composables/useCborSimpleEncoder.ts +266 -0
- package/src/encoder/composables/useCborStringEncoder.ts +266 -0
- package/src/encoder/composables/useCborTagEncoder.ts +158 -0
- package/src/encoder/index.ts +35 -0
- package/src/encoder/types.ts +88 -0
- package/src/encoder/utils.ts +80 -0
- package/src/index.ts +434 -0
- package/src/parser/__tests__/ast-tree-structure.test.ts +311 -0
- package/src/parser/__tests__/cbor-collection-errors.test.ts +296 -0
- package/src/parser/__tests__/cbor-collection.test.ts +369 -0
- package/src/parser/__tests__/cbor-deterministic-encoding.test.ts +432 -0
- package/src/parser/__tests__/cbor-diagnostic.test.ts +333 -0
- package/src/parser/__tests__/cbor-duplicate-keys.test.ts +235 -0
- package/src/parser/__tests__/cbor-float-errors.test.ts +222 -0
- package/src/parser/__tests__/cbor-float.test.ts +502 -0
- package/src/parser/__tests__/cbor-integer-errors.test.ts +139 -0
- package/src/parser/__tests__/cbor-integer.test.ts +200 -0
- package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +403 -0
- package/src/parser/__tests__/cbor-parser-errors.test.ts +126 -0
- package/src/parser/__tests__/cbor-security-dos-protection.test.ts +503 -0
- package/src/parser/__tests__/cbor-sequences.test.ts +150 -0
- package/src/parser/__tests__/cbor-source-map.test.ts +321 -0
- package/src/parser/__tests__/cbor-standard-tags.test.ts +340 -0
- package/src/parser/__tests__/cbor-string-errors.test.ts +227 -0
- package/src/parser/__tests__/cbor-string.test.ts +224 -0
- package/src/parser/__tests__/cbor-tag-advanced.test.ts +500 -0
- package/src/parser/__tests__/cbor-tag-errors.test.ts +447 -0
- package/src/parser/__tests__/cbor-tag-source-map.test.ts +360 -0
- package/src/parser/__tests__/cbor-tag.test.ts +684 -0
- package/src/parser/__tests__/extreme-edge-cases.test.ts +146 -0
- package/src/parser/__tests__/pathBuilder.test.ts +256 -0
- package/src/parser/__tests__/rfc-test-vectors.test.ts +607 -0
- package/src/parser/__tests__/security-limits.test.ts +248 -0
- package/src/parser/__tests__/utils-errors.test.ts +127 -0
- package/src/parser/composables/useCborCollection.ts +509 -0
- package/src/parser/composables/useCborDiagnostic.ts +381 -0
- package/src/parser/composables/useCborFloat.ts +256 -0
- package/src/parser/composables/useCborInteger.ts +114 -0
- package/src/parser/composables/useCborParser.ts +951 -0
- package/src/parser/composables/useCborString.ts +330 -0
- package/src/parser/composables/useCborStringTypes.ts +129 -0
- package/src/parser/composables/useCborTag.ts +739 -0
- package/src/parser/index.ts +56 -0
- package/src/parser/types.ts +371 -0
- package/src/parser/utils/pathBuilder.ts +259 -0
- package/src/parser/utils.ts +398 -0
- package/src/utils/__tests__/logger.test.ts +186 -0
- package/src/utils/logger.ts +96 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CBOR Integer Encoder Test Suite
|
|
3
|
+
* Tests for Major Type 0 (Unsigned) and Major Type 1 (Negative)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect } from 'vitest'
|
|
7
|
+
import { useCborIntegerEncoder } from '../composables/useCborIntegerEncoder'
|
|
8
|
+
|
|
9
|
+
describe('CBOR Integer Encoder', () => {
|
|
10
|
+
describe('Unsigned Integers (Major Type 0)', () => {
|
|
11
|
+
describe('Direct encoding (0-23)', () => {
|
|
12
|
+
it('should encode 0', () => {
|
|
13
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
14
|
+
const result = encodeUnsignedInt(0)
|
|
15
|
+
|
|
16
|
+
expect(result.bytes).toEqual(new Uint8Array([0x00]))
|
|
17
|
+
expect(result.hex).toBe('00')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should encode 1', () => {
|
|
21
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
22
|
+
const result = encodeUnsignedInt(1)
|
|
23
|
+
|
|
24
|
+
expect(result.bytes).toEqual(new Uint8Array([0x01]))
|
|
25
|
+
expect(result.hex).toBe('01')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should encode 10', () => {
|
|
29
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
30
|
+
const result = encodeUnsignedInt(10)
|
|
31
|
+
|
|
32
|
+
expect(result.bytes).toEqual(new Uint8Array([0x0a]))
|
|
33
|
+
expect(result.hex).toBe('0a')
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should encode 23', () => {
|
|
37
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
38
|
+
const result = encodeUnsignedInt(23)
|
|
39
|
+
|
|
40
|
+
expect(result.bytes).toEqual(new Uint8Array([0x17]))
|
|
41
|
+
expect(result.hex).toBe('17')
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
describe('1-byte encoding (24-255)', () => {
|
|
46
|
+
it('should encode 24', () => {
|
|
47
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
48
|
+
const result = encodeUnsignedInt(24)
|
|
49
|
+
|
|
50
|
+
expect(result.bytes).toEqual(new Uint8Array([0x18, 0x18]))
|
|
51
|
+
expect(result.hex).toBe('1818')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should encode 25', () => {
|
|
55
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
56
|
+
const result = encodeUnsignedInt(25)
|
|
57
|
+
|
|
58
|
+
expect(result.bytes).toEqual(new Uint8Array([0x18, 0x19]))
|
|
59
|
+
expect(result.hex).toBe('1819')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('should encode 100', () => {
|
|
63
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
64
|
+
const result = encodeUnsignedInt(100)
|
|
65
|
+
|
|
66
|
+
expect(result.bytes).toEqual(new Uint8Array([0x18, 0x64]))
|
|
67
|
+
expect(result.hex).toBe('1864')
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('should encode 255', () => {
|
|
71
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
72
|
+
const result = encodeUnsignedInt(255)
|
|
73
|
+
|
|
74
|
+
expect(result.bytes).toEqual(new Uint8Array([0x18, 0xff]))
|
|
75
|
+
expect(result.hex).toBe('18ff')
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
describe('2-byte encoding (256-65535)', () => {
|
|
80
|
+
it('should encode 256', () => {
|
|
81
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
82
|
+
const result = encodeUnsignedInt(256)
|
|
83
|
+
|
|
84
|
+
expect(result.bytes).toEqual(new Uint8Array([0x19, 0x01, 0x00]))
|
|
85
|
+
expect(result.hex).toBe('190100')
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('should encode 1000', () => {
|
|
89
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
90
|
+
const result = encodeUnsignedInt(1000)
|
|
91
|
+
|
|
92
|
+
expect(result.bytes).toEqual(new Uint8Array([0x19, 0x03, 0xe8]))
|
|
93
|
+
expect(result.hex).toBe('1903e8')
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it('should encode 65535', () => {
|
|
97
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
98
|
+
const result = encodeUnsignedInt(65535)
|
|
99
|
+
|
|
100
|
+
expect(result.bytes).toEqual(new Uint8Array([0x19, 0xff, 0xff]))
|
|
101
|
+
expect(result.hex).toBe('19ffff')
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
describe('4-byte encoding (65536-4294967295)', () => {
|
|
106
|
+
it('should encode 65536', () => {
|
|
107
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
108
|
+
const result = encodeUnsignedInt(65536)
|
|
109
|
+
|
|
110
|
+
expect(result.bytes).toEqual(new Uint8Array([0x1a, 0x00, 0x01, 0x00, 0x00]))
|
|
111
|
+
expect(result.hex).toBe('1a00010000')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('should encode 1000000', () => {
|
|
115
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
116
|
+
const result = encodeUnsignedInt(1000000)
|
|
117
|
+
|
|
118
|
+
expect(result.bytes).toEqual(new Uint8Array([0x1a, 0x00, 0x0f, 0x42, 0x40]))
|
|
119
|
+
expect(result.hex).toBe('1a000f4240')
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should encode 4294967295', () => {
|
|
123
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
124
|
+
const result = encodeUnsignedInt(4294967295)
|
|
125
|
+
|
|
126
|
+
expect(result.bytes).toEqual(new Uint8Array([0x1a, 0xff, 0xff, 0xff, 0xff]))
|
|
127
|
+
expect(result.hex).toBe('1affffffff')
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
describe('8-byte encoding (> 4294967295)', () => {
|
|
132
|
+
it('should encode 4294967296', () => {
|
|
133
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
134
|
+
const result = encodeUnsignedInt(4294967296)
|
|
135
|
+
|
|
136
|
+
expect(result.bytes).toEqual(new Uint8Array([0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]))
|
|
137
|
+
expect(result.hex).toBe('1b0000000100000000')
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('should encode BigInt values', () => {
|
|
141
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
142
|
+
const result = encodeUnsignedInt(18446744073709551615n) // 2^64 - 1
|
|
143
|
+
|
|
144
|
+
expect(result.bytes).toEqual(new Uint8Array([0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))
|
|
145
|
+
expect(result.hex).toBe('1bffffffffffffffff')
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
describe('Error cases', () => {
|
|
150
|
+
it('should reject negative values', () => {
|
|
151
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
152
|
+
|
|
153
|
+
expect(() => encodeUnsignedInt(-1)).toThrow('Cannot encode negative value as unsigned integer')
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('should reject values >= 2^64', () => {
|
|
157
|
+
const { encodeUnsignedInt } = useCborIntegerEncoder()
|
|
158
|
+
|
|
159
|
+
expect(() => encodeUnsignedInt(18446744073709551616n)).toThrow('Value exceeds maximum unsigned integer (2^64-1)')
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
describe('Negative Integers (Major Type 1)', () => {
|
|
165
|
+
describe('Direct encoding (-1 to -24)', () => {
|
|
166
|
+
it('should encode -1', () => {
|
|
167
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
168
|
+
const result = encodeNegativeInt(-1)
|
|
169
|
+
|
|
170
|
+
expect(result.bytes).toEqual(new Uint8Array([0x20]))
|
|
171
|
+
expect(result.hex).toBe('20')
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
it('should encode -10', () => {
|
|
175
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
176
|
+
const result = encodeNegativeInt(-10)
|
|
177
|
+
|
|
178
|
+
expect(result.bytes).toEqual(new Uint8Array([0x29]))
|
|
179
|
+
expect(result.hex).toBe('29')
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
it('should encode -24', () => {
|
|
183
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
184
|
+
const result = encodeNegativeInt(-24)
|
|
185
|
+
|
|
186
|
+
expect(result.bytes).toEqual(new Uint8Array([0x37]))
|
|
187
|
+
expect(result.hex).toBe('37')
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
describe('1-byte encoding (-25 to -256)', () => {
|
|
192
|
+
it('should encode -25', () => {
|
|
193
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
194
|
+
const result = encodeNegativeInt(-25)
|
|
195
|
+
|
|
196
|
+
expect(result.bytes).toEqual(new Uint8Array([0x38, 0x18]))
|
|
197
|
+
expect(result.hex).toBe('3818')
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('should encode -100', () => {
|
|
201
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
202
|
+
const result = encodeNegativeInt(-100)
|
|
203
|
+
|
|
204
|
+
expect(result.bytes).toEqual(new Uint8Array([0x38, 0x63]))
|
|
205
|
+
expect(result.hex).toBe('3863')
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
it('should encode -256', () => {
|
|
209
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
210
|
+
const result = encodeNegativeInt(-256)
|
|
211
|
+
|
|
212
|
+
expect(result.bytes).toEqual(new Uint8Array([0x38, 0xff]))
|
|
213
|
+
expect(result.hex).toBe('38ff')
|
|
214
|
+
})
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
describe('2-byte encoding (-257 to -65536)', () => {
|
|
218
|
+
it('should encode -257', () => {
|
|
219
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
220
|
+
const result = encodeNegativeInt(-257)
|
|
221
|
+
|
|
222
|
+
expect(result.bytes).toEqual(new Uint8Array([0x39, 0x01, 0x00]))
|
|
223
|
+
expect(result.hex).toBe('390100')
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
it('should encode -1000', () => {
|
|
227
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
228
|
+
const result = encodeNegativeInt(-1000)
|
|
229
|
+
|
|
230
|
+
expect(result.bytes).toEqual(new Uint8Array([0x39, 0x03, 0xe7]))
|
|
231
|
+
expect(result.hex).toBe('3903e7')
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
describe('4-byte encoding', () => {
|
|
236
|
+
it('should encode -1000000', () => {
|
|
237
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
238
|
+
const result = encodeNegativeInt(-1000000)
|
|
239
|
+
|
|
240
|
+
expect(result.bytes).toEqual(new Uint8Array([0x3a, 0x00, 0x0f, 0x42, 0x3f]))
|
|
241
|
+
expect(result.hex).toBe('3a000f423f')
|
|
242
|
+
})
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
describe('Error cases', () => {
|
|
246
|
+
it('should reject positive values', () => {
|
|
247
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
248
|
+
|
|
249
|
+
expect(() => encodeNegativeInt(1)).toThrow('Cannot encode positive value as negative integer')
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
it('should reject zero', () => {
|
|
253
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
254
|
+
|
|
255
|
+
expect(() => encodeNegativeInt(0)).toThrow('Cannot encode positive value as negative integer')
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('should reject values < -2^64', () => {
|
|
259
|
+
const { encodeNegativeInt } = useCborIntegerEncoder()
|
|
260
|
+
|
|
261
|
+
expect(() => encodeNegativeInt(-18446744073709551617n)).toThrow('Value exceeds minimum negative integer (-2^64)')
|
|
262
|
+
})
|
|
263
|
+
})
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
describe('Auto-detect integer type', () => {
|
|
267
|
+
it('should encode positive integers', () => {
|
|
268
|
+
const { encodeInteger } = useCborIntegerEncoder()
|
|
269
|
+
|
|
270
|
+
expect(encodeInteger(0).hex).toBe('00')
|
|
271
|
+
expect(encodeInteger(100).hex).toBe('1864')
|
|
272
|
+
expect(encodeInteger(1000000).hex).toBe('1a000f4240')
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
it('should encode negative integers', () => {
|
|
276
|
+
const { encodeInteger } = useCborIntegerEncoder()
|
|
277
|
+
|
|
278
|
+
expect(encodeInteger(-1).hex).toBe('20')
|
|
279
|
+
expect(encodeInteger(-100).hex).toBe('3863')
|
|
280
|
+
expect(encodeInteger(-1000).hex).toBe('3903e7')
|
|
281
|
+
})
|
|
282
|
+
})
|
|
283
|
+
})
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CBOR Simple Values and Floats Encoder Test Suite
|
|
3
|
+
* Tests for Major Type 7 (Floats and Simple Values)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect } from 'vitest'
|
|
7
|
+
import { useCborSimpleEncoder } from '../composables/useCborSimpleEncoder'
|
|
8
|
+
|
|
9
|
+
describe('CBOR Simple Values and Floats Encoder', () => {
|
|
10
|
+
describe('Simple Values', () => {
|
|
11
|
+
it('should encode false', () => {
|
|
12
|
+
const { encodeSimple } = useCborSimpleEncoder()
|
|
13
|
+
const result = encodeSimple(false)
|
|
14
|
+
|
|
15
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf4]))
|
|
16
|
+
expect(result.hex).toBe('f4')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('should encode true', () => {
|
|
20
|
+
const { encodeSimple } = useCborSimpleEncoder()
|
|
21
|
+
const result = encodeSimple(true)
|
|
22
|
+
|
|
23
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf5]))
|
|
24
|
+
expect(result.hex).toBe('f5')
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('should encode null', () => {
|
|
28
|
+
const { encodeSimple } = useCborSimpleEncoder()
|
|
29
|
+
const result = encodeSimple(null)
|
|
30
|
+
|
|
31
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf6]))
|
|
32
|
+
expect(result.hex).toBe('f6')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should encode undefined', () => {
|
|
36
|
+
const { encodeSimple } = useCborSimpleEncoder()
|
|
37
|
+
const result = encodeSimple(undefined)
|
|
38
|
+
|
|
39
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf7]))
|
|
40
|
+
expect(result.hex).toBe('f7')
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
describe('Floating-Point Numbers', () => {
|
|
45
|
+
describe('Float16 (half precision)', () => {
|
|
46
|
+
it('should encode 0.0 as float16', () => {
|
|
47
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
48
|
+
const result = encodeFloat(0.0, 16)
|
|
49
|
+
|
|
50
|
+
// 0xf9 (float16) + 0x0000
|
|
51
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf9, 0x00, 0x00]))
|
|
52
|
+
expect(result.hex).toBe('f90000')
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('should encode 1.0 as float16', () => {
|
|
56
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
57
|
+
const result = encodeFloat(1.0, 16)
|
|
58
|
+
|
|
59
|
+
// 0xf9 (float16) + 0x3c00
|
|
60
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf9, 0x3c, 0x00]))
|
|
61
|
+
expect(result.hex).toBe('f93c00')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should encode -1.0 as float16', () => {
|
|
65
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
66
|
+
const result = encodeFloat(-1.0, 16)
|
|
67
|
+
|
|
68
|
+
// 0xf9 (float16) + 0xbc00
|
|
69
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf9, 0xbc, 0x00]))
|
|
70
|
+
expect(result.hex).toBe('f9bc00')
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('should encode Infinity as float16', () => {
|
|
74
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
75
|
+
const result = encodeFloat(Infinity, 16)
|
|
76
|
+
|
|
77
|
+
// 0xf9 (float16) + 0x7c00
|
|
78
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf9, 0x7c, 0x00]))
|
|
79
|
+
expect(result.hex).toBe('f97c00')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('should encode -Infinity as float16', () => {
|
|
83
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
84
|
+
const result = encodeFloat(-Infinity, 16)
|
|
85
|
+
|
|
86
|
+
// 0xf9 (float16) + 0xfc00
|
|
87
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf9, 0xfc, 0x00]))
|
|
88
|
+
expect(result.hex).toBe('f9fc00')
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('should encode NaN as float16', () => {
|
|
92
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
93
|
+
const result = encodeFloat(NaN, 16)
|
|
94
|
+
|
|
95
|
+
// 0xf9 (float16) + 0x7e00
|
|
96
|
+
expect(result.bytes).toEqual(new Uint8Array([0xf9, 0x7e, 0x00]))
|
|
97
|
+
expect(result.hex).toBe('f97e00')
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
describe('Float32 (single precision)', () => {
|
|
102
|
+
it('should encode 0.0 as float32', () => {
|
|
103
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
104
|
+
const result = encodeFloat(0.0, 32)
|
|
105
|
+
|
|
106
|
+
// 0xfa (float32) + 0x00000000
|
|
107
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfa, 0x00, 0x00, 0x00, 0x00]))
|
|
108
|
+
expect(result.hex).toBe('fa00000000')
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('should encode 1.0 as float32', () => {
|
|
112
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
113
|
+
const result = encodeFloat(1.0, 32)
|
|
114
|
+
|
|
115
|
+
// 0xfa (float32) + 0x3f800000
|
|
116
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfa, 0x3f, 0x80, 0x00, 0x00]))
|
|
117
|
+
expect(result.hex).toBe('fa3f800000')
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('should encode 3.4028234663852886e+38 (max float32)', () => {
|
|
121
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
122
|
+
const result = encodeFloat(3.4028234663852886e+38, 32)
|
|
123
|
+
|
|
124
|
+
// 0xfa (float32) + 0x7f7fffff
|
|
125
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfa, 0x7f, 0x7f, 0xff, 0xff]))
|
|
126
|
+
expect(result.hex).toBe('fa7f7fffff')
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('should encode Infinity as float32', () => {
|
|
130
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
131
|
+
const result = encodeFloat(Infinity, 32)
|
|
132
|
+
|
|
133
|
+
// 0xfa (float32) + 0x7f800000
|
|
134
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfa, 0x7f, 0x80, 0x00, 0x00]))
|
|
135
|
+
expect(result.hex).toBe('fa7f800000')
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
describe('Float64 (double precision)', () => {
|
|
140
|
+
it('should encode 0.0 as float64', () => {
|
|
141
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
142
|
+
const result = encodeFloat(0.0, 64)
|
|
143
|
+
|
|
144
|
+
// 0xfb (float64) + 0x0000000000000000
|
|
145
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
|
|
146
|
+
expect(result.hex).toBe('fb0000000000000000')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('should encode 1.1 as float64', () => {
|
|
150
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
151
|
+
const result = encodeFloat(1.1, 64)
|
|
152
|
+
|
|
153
|
+
// RFC 8949 Appendix A example
|
|
154
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a]))
|
|
155
|
+
expect(result.hex).toBe('fb3ff199999999999a')
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('should encode 1.0e+300 as float64', () => {
|
|
159
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
160
|
+
const result = encodeFloat(1.0e+300, 64)
|
|
161
|
+
|
|
162
|
+
// RFC 8949 Appendix A example
|
|
163
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfb, 0x7e, 0x37, 0xe4, 0x3c, 0x88, 0x00, 0x75, 0x9c]))
|
|
164
|
+
expect(result.hex).toBe('fb7e37e43c8800759c')
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('should encode -4.1 as float64', () => {
|
|
168
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
169
|
+
const result = encodeFloat(-4.1, 64)
|
|
170
|
+
|
|
171
|
+
// RFC 8949 Appendix A example
|
|
172
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfb, 0xc0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66]))
|
|
173
|
+
expect(result.hex).toBe('fbc010666666666666')
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('should encode Infinity as float64', () => {
|
|
177
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
178
|
+
const result = encodeFloat(Infinity, 64)
|
|
179
|
+
|
|
180
|
+
// 0xfb (float64) + 0x7ff0000000000000
|
|
181
|
+
expect(result.bytes).toEqual(new Uint8Array([0xfb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
|
|
182
|
+
expect(result.hex).toBe('fb7ff0000000000000')
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
it('should encode NaN as float64', () => {
|
|
186
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
187
|
+
const result = encodeFloat(NaN, 64)
|
|
188
|
+
|
|
189
|
+
// 0xfb (float64) + NaN representation
|
|
190
|
+
expect(result.bytes[0]).toBe(0xfb)
|
|
191
|
+
expect(result.bytes.length).toBe(9)
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
describe('Auto-detect precision', () => {
|
|
196
|
+
it('should encode integer-like float as integer', () => {
|
|
197
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
198
|
+
const result = encodeFloat(100.0)
|
|
199
|
+
|
|
200
|
+
// Should use integer encoding if possible
|
|
201
|
+
// This is an optimization - float64 is also acceptable
|
|
202
|
+
expect(result.bytes[0]).toBe(0x18) // Integer encoding
|
|
203
|
+
expect(result.bytes[1]).toBe(100)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
it('should encode fractional number as smallest float', () => {
|
|
207
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
208
|
+
const result = encodeFloat(1.5)
|
|
209
|
+
|
|
210
|
+
// 1.5 can be represented in float16, float32, or float64
|
|
211
|
+
// Any of these are acceptable
|
|
212
|
+
expect([0xf9, 0xfa, 0xfb]).toContain(result.bytes[0]) // Float16, Float32, or Float64
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('should use float64 for high-precision numbers', () => {
|
|
216
|
+
const { encodeFloat } = useCborSimpleEncoder()
|
|
217
|
+
const result = encodeFloat(1.1)
|
|
218
|
+
|
|
219
|
+
// 1.1 requires float64 for precision
|
|
220
|
+
expect(result.bytes[0]).toBe(0xfb) // Float64
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
})
|
|
224
|
+
})
|