@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.
Files changed (100) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +674 -0
  3. package/README.md +345 -0
  4. package/dist/chunk-2FUTHZQQ.cjs +755 -0
  5. package/dist/chunk-2FUTHZQQ.cjs.map +1 -0
  6. package/dist/chunk-2HBCILJS.cjs +2034 -0
  7. package/dist/chunk-2HBCILJS.cjs.map +1 -0
  8. package/dist/chunk-7CFYWHS6.js +742 -0
  9. package/dist/chunk-7CFYWHS6.js.map +1 -0
  10. package/dist/chunk-PD72MVTX.cjs +160 -0
  11. package/dist/chunk-PD72MVTX.cjs.map +1 -0
  12. package/dist/chunk-ZDZ2B5PE.js +149 -0
  13. package/dist/chunk-ZDZ2B5PE.js.map +1 -0
  14. package/dist/chunk-ZRPJUEIZ.js +2020 -0
  15. package/dist/chunk-ZRPJUEIZ.js.map +1 -0
  16. package/dist/encoder/index.cjs +57 -0
  17. package/dist/encoder/index.cjs.map +1 -0
  18. package/dist/encoder/index.d.cts +72 -0
  19. package/dist/encoder/index.d.ts +72 -0
  20. package/dist/encoder/index.js +4 -0
  21. package/dist/encoder/index.js.map +1 -0
  22. package/dist/index.cjs +606 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +494 -0
  25. package/dist/index.d.ts +494 -0
  26. package/dist/index.js +523 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/metafile-cjs.json +1 -0
  29. package/dist/metafile-esm.json +1 -0
  30. package/dist/parser/index.cjs +85 -0
  31. package/dist/parser/index.cjs.map +1 -0
  32. package/dist/parser/index.d.cts +72 -0
  33. package/dist/parser/index.d.ts +72 -0
  34. package/dist/parser/index.js +4 -0
  35. package/dist/parser/index.js.map +1 -0
  36. package/dist/types-DvNlfbKB.d.cts +301 -0
  37. package/dist/types-DvNlfbKB.d.ts +301 -0
  38. package/dist/useCborSimpleEncoder-ButVU988.d.cts +268 -0
  39. package/dist/useCborSimpleEncoder-TVxzNJ_9.d.ts +268 -0
  40. package/dist/useCborTag-B_iaShG6.d.ts +142 -0
  41. package/dist/useCborTag-BfTIV8HM.d.cts +142 -0
  42. package/package.json +102 -0
  43. package/src/__tests__/public-api.test.ts +326 -0
  44. package/src/encoder/__tests__/cbor-collection-encoder.test.ts +331 -0
  45. package/src/encoder/__tests__/cbor-integer-encoder.test.ts +283 -0
  46. package/src/encoder/__tests__/cbor-simple-encoder.test.ts +224 -0
  47. package/src/encoder/__tests__/cbor-string-encoder.test.ts +345 -0
  48. package/src/encoder/__tests__/cbor-tag-encoder.test.ts +565 -0
  49. package/src/encoder/composables/#useCborTagEncoder.ts# +158 -0
  50. package/src/encoder/composables/useCborCollectionEncoder.ts +424 -0
  51. package/src/encoder/composables/useCborEncoder.ts +203 -0
  52. package/src/encoder/composables/useCborIntegerEncoder.ts +188 -0
  53. package/src/encoder/composables/useCborSimpleEncoder.ts +266 -0
  54. package/src/encoder/composables/useCborStringEncoder.ts +266 -0
  55. package/src/encoder/composables/useCborTagEncoder.ts +158 -0
  56. package/src/encoder/index.ts +35 -0
  57. package/src/encoder/types.ts +88 -0
  58. package/src/encoder/utils.ts +80 -0
  59. package/src/index.ts +434 -0
  60. package/src/parser/__tests__/ast-tree-structure.test.ts +311 -0
  61. package/src/parser/__tests__/cbor-collection-errors.test.ts +296 -0
  62. package/src/parser/__tests__/cbor-collection.test.ts +369 -0
  63. package/src/parser/__tests__/cbor-deterministic-encoding.test.ts +432 -0
  64. package/src/parser/__tests__/cbor-diagnostic.test.ts +333 -0
  65. package/src/parser/__tests__/cbor-duplicate-keys.test.ts +235 -0
  66. package/src/parser/__tests__/cbor-float-errors.test.ts +222 -0
  67. package/src/parser/__tests__/cbor-float.test.ts +502 -0
  68. package/src/parser/__tests__/cbor-integer-errors.test.ts +139 -0
  69. package/src/parser/__tests__/cbor-integer.test.ts +200 -0
  70. package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +403 -0
  71. package/src/parser/__tests__/cbor-parser-errors.test.ts +126 -0
  72. package/src/parser/__tests__/cbor-security-dos-protection.test.ts +503 -0
  73. package/src/parser/__tests__/cbor-sequences.test.ts +150 -0
  74. package/src/parser/__tests__/cbor-source-map.test.ts +321 -0
  75. package/src/parser/__tests__/cbor-standard-tags.test.ts +340 -0
  76. package/src/parser/__tests__/cbor-string-errors.test.ts +227 -0
  77. package/src/parser/__tests__/cbor-string.test.ts +224 -0
  78. package/src/parser/__tests__/cbor-tag-advanced.test.ts +500 -0
  79. package/src/parser/__tests__/cbor-tag-errors.test.ts +447 -0
  80. package/src/parser/__tests__/cbor-tag-source-map.test.ts +360 -0
  81. package/src/parser/__tests__/cbor-tag.test.ts +684 -0
  82. package/src/parser/__tests__/extreme-edge-cases.test.ts +146 -0
  83. package/src/parser/__tests__/pathBuilder.test.ts +256 -0
  84. package/src/parser/__tests__/rfc-test-vectors.test.ts +607 -0
  85. package/src/parser/__tests__/security-limits.test.ts +248 -0
  86. package/src/parser/__tests__/utils-errors.test.ts +127 -0
  87. package/src/parser/composables/useCborCollection.ts +509 -0
  88. package/src/parser/composables/useCborDiagnostic.ts +381 -0
  89. package/src/parser/composables/useCborFloat.ts +256 -0
  90. package/src/parser/composables/useCborInteger.ts +114 -0
  91. package/src/parser/composables/useCborParser.ts +951 -0
  92. package/src/parser/composables/useCborString.ts +330 -0
  93. package/src/parser/composables/useCborStringTypes.ts +129 -0
  94. package/src/parser/composables/useCborTag.ts +739 -0
  95. package/src/parser/index.ts +56 -0
  96. package/src/parser/types.ts +371 -0
  97. package/src/parser/utils/pathBuilder.ts +259 -0
  98. package/src/parser/utils.ts +398 -0
  99. package/src/utils/__tests__/logger.test.ts +186 -0
  100. 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
+ })