@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,224 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { useCborString } from '../composables/useCborString'
|
|
3
|
+
|
|
4
|
+
describe('useCborString', () => {
|
|
5
|
+
describe('parseByteString (Major Type 2)', () => {
|
|
6
|
+
it('should parse empty byte string', () => {
|
|
7
|
+
const { parseString } = useCborString()
|
|
8
|
+
|
|
9
|
+
// Test case: Empty byte string (RFC 8949 Appendix A)
|
|
10
|
+
// Hex: 0x40 = 0b010_00000 (MT 2, length 0)
|
|
11
|
+
const result = parseString('40')
|
|
12
|
+
expect(result.value).toEqual(new Uint8Array([]))
|
|
13
|
+
expect(result.bytesRead).toBe(1)
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('should parse small byte strings (length 0-23)', () => {
|
|
17
|
+
const { parseString } = useCborString()
|
|
18
|
+
|
|
19
|
+
// Test case 1: 4 bytes (RFC 8949 Appendix A)
|
|
20
|
+
// Hex: 0x44 0x01 0x02 0x03 0x04
|
|
21
|
+
const result1 = parseString('4401020304')
|
|
22
|
+
expect(result1.value).toEqual(new Uint8Array([1, 2, 3, 4]))
|
|
23
|
+
expect(result1.bytesRead).toBe(5)
|
|
24
|
+
|
|
25
|
+
// Test case 2: Single byte
|
|
26
|
+
const result2 = parseString('41ff')
|
|
27
|
+
expect(result2.value).toEqual(new Uint8Array([0xff]))
|
|
28
|
+
expect(result2.bytesRead).toBe(2)
|
|
29
|
+
|
|
30
|
+
// Test case 3: 3 bytes
|
|
31
|
+
const result3 = parseString('43aabbcc')
|
|
32
|
+
expect(result3.value).toEqual(new Uint8Array([0xaa, 0xbb, 0xcc]))
|
|
33
|
+
expect(result3.bytesRead).toBe(4)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should parse 1-byte length byte strings (24-255 bytes)', () => {
|
|
37
|
+
const { parseString } = useCborString()
|
|
38
|
+
|
|
39
|
+
// Test case: 24 bytes
|
|
40
|
+
const hexData = '00112233445566778899aabbccddeeff0011223344556677'
|
|
41
|
+
const result = parseString('5818' + hexData)
|
|
42
|
+
expect(result.value.length).toBe(24)
|
|
43
|
+
expect(result.value[0]).toBe(0x00)
|
|
44
|
+
expect(result.value[23]).toBe(0x77)
|
|
45
|
+
expect(result.bytesRead).toBe(26) // 2 (header) + 24 (data)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it('should parse 2-byte length byte strings (256+ bytes)', () => {
|
|
49
|
+
const { parseString } = useCborString()
|
|
50
|
+
|
|
51
|
+
// Test case: 256 bytes
|
|
52
|
+
const hexData = '00'.repeat(256)
|
|
53
|
+
const result = parseString('590100' + hexData)
|
|
54
|
+
expect(result.value.length).toBe(256)
|
|
55
|
+
expect(result.bytesRead).toBe(259) // 3 (header) + 256 (data)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should parse Cardano transaction hash (32 bytes)', () => {
|
|
59
|
+
const { parseString } = useCborString()
|
|
60
|
+
|
|
61
|
+
// Real Cardano transaction hash (32 bytes)
|
|
62
|
+
const txHash = '48bd01d51e580cde15afa6d28f63d89c9137b93a910e5941192e26b1290610670'
|
|
63
|
+
const result = parseString('5820' + txHash.slice(0, 64))
|
|
64
|
+
expect(result.value.length).toBe(32)
|
|
65
|
+
expect(result.bytesRead).toBe(34) // 2 (header) + 32 (hash)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('parseTextString (Major Type 3)', () => {
|
|
70
|
+
it('should parse empty text string', () => {
|
|
71
|
+
const { parseString } = useCborString()
|
|
72
|
+
|
|
73
|
+
// Test case: Empty text string (RFC 8949 Appendix A)
|
|
74
|
+
// Hex: 0x60 = 0b011_00000 (MT 3, length 0)
|
|
75
|
+
const result = parseString('60')
|
|
76
|
+
expect(result.value).toBe('')
|
|
77
|
+
expect(result.bytesRead).toBe(1)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should parse single character ASCII strings', () => {
|
|
81
|
+
const { parseString } = useCborString()
|
|
82
|
+
|
|
83
|
+
// Test case 1: "a" (RFC 8949 Appendix A)
|
|
84
|
+
const result1 = parseString('6161')
|
|
85
|
+
expect(result1.value).toBe('a')
|
|
86
|
+
expect(result1.bytesRead).toBe(2)
|
|
87
|
+
|
|
88
|
+
// Test case 2: "A"
|
|
89
|
+
const result2 = parseString('6141')
|
|
90
|
+
expect(result2.value).toBe('A')
|
|
91
|
+
expect(result2.bytesRead).toBe(2)
|
|
92
|
+
|
|
93
|
+
// Test case 3: "z"
|
|
94
|
+
const result3 = parseString('617a')
|
|
95
|
+
expect(result3.value).toBe('z')
|
|
96
|
+
expect(result3.bytesRead).toBe(2)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('should parse multi-character ASCII strings', () => {
|
|
100
|
+
const { parseString } = useCborString()
|
|
101
|
+
|
|
102
|
+
// Test case 1: "IETF" (RFC 8949 Appendix A)
|
|
103
|
+
const result1 = parseString('6449455446')
|
|
104
|
+
expect(result1.value).toBe('IETF')
|
|
105
|
+
expect(result1.bytesRead).toBe(5)
|
|
106
|
+
|
|
107
|
+
// Test case 2: "Hello"
|
|
108
|
+
const result2 = parseString('6548656c6c6f')
|
|
109
|
+
expect(result2.value).toBe('Hello')
|
|
110
|
+
expect(result2.bytesRead).toBe(6)
|
|
111
|
+
|
|
112
|
+
// Test case 3: "CBOR"
|
|
113
|
+
const result3 = parseString('6443424f52')
|
|
114
|
+
expect(result3.value).toBe('CBOR')
|
|
115
|
+
expect(result3.bytesRead).toBe(5)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('should parse UTF-8 encoded strings', () => {
|
|
119
|
+
const { parseString } = useCborString()
|
|
120
|
+
|
|
121
|
+
// Test case 1: "あ" (Japanese Hiragana, 3 bytes in UTF-8)
|
|
122
|
+
const result1 = parseString('63e38182')
|
|
123
|
+
expect(result1.value).toBe('あ')
|
|
124
|
+
expect(result1.bytesRead).toBe(4)
|
|
125
|
+
|
|
126
|
+
// Test case 2: "🎉" (emoji, 4 bytes in UTF-8)
|
|
127
|
+
const result2 = parseString('64f09f8e89')
|
|
128
|
+
expect(result2.value).toBe('🎉')
|
|
129
|
+
expect(result2.bytesRead).toBe(5)
|
|
130
|
+
|
|
131
|
+
// Test case 3: "café" (é is 2 bytes in UTF-8: c3 a9)
|
|
132
|
+
const result3 = parseString('65636166c3a9')
|
|
133
|
+
expect(result3.value).toBe('café')
|
|
134
|
+
expect(result3.bytesRead).toBe(6)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('should parse 1-byte length text strings (24+ characters)', () => {
|
|
138
|
+
const { parseString } = useCborString()
|
|
139
|
+
|
|
140
|
+
// Test case: 24 character string
|
|
141
|
+
const text = 'abcdefghijklmnopqrstuvwx'
|
|
142
|
+
const hexData = text.split('').map(c => c.charCodeAt(0).toString(16)).join('')
|
|
143
|
+
const result = parseString('7818' + hexData)
|
|
144
|
+
expect(result.value).toBe(text)
|
|
145
|
+
expect(result.bytesRead).toBe(26) // 2 (header) + 24 (data)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('should parse Cardano metadata strings', () => {
|
|
149
|
+
const { parseString } = useCborString()
|
|
150
|
+
|
|
151
|
+
// Test case: "Hello World" (common Cardano metadata)
|
|
152
|
+
const result = parseString('6b48656c6c6f20576f726c64')
|
|
153
|
+
expect(result.value).toBe('Hello World')
|
|
154
|
+
expect(result.bytesRead).toBe(12)
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
describe('parseString with type detection', () => {
|
|
159
|
+
it('should correctly identify and parse byte strings (MT 2)', () => {
|
|
160
|
+
const { parseString } = useCborString()
|
|
161
|
+
|
|
162
|
+
// Major Type 2 should return Uint8Array
|
|
163
|
+
const result = parseString('4401020304')
|
|
164
|
+
expect(result.value).toBeInstanceOf(Uint8Array)
|
|
165
|
+
expect(result.value).toEqual(new Uint8Array([1, 2, 3, 4]))
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it('should correctly identify and parse text strings (MT 3)', () => {
|
|
169
|
+
const { parseString } = useCborString()
|
|
170
|
+
|
|
171
|
+
// Major Type 3 should return string
|
|
172
|
+
const result = parseString('6449455446')
|
|
173
|
+
expect(typeof result.value).toBe('string')
|
|
174
|
+
expect(result.value).toBe('IETF')
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('should reject invalid major types', () => {
|
|
178
|
+
const { parseString } = useCborString()
|
|
179
|
+
|
|
180
|
+
// Major Type 0 (integer) should be rejected
|
|
181
|
+
expect(() => parseString('00')).toThrow()
|
|
182
|
+
|
|
183
|
+
// Major Type 4 (array) should be rejected
|
|
184
|
+
expect(() => parseString('80')).toThrow()
|
|
185
|
+
})
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
describe('edge cases and error handling', () => {
|
|
189
|
+
it('should handle strings at boundary lengths', () => {
|
|
190
|
+
const { parseString } = useCborString()
|
|
191
|
+
|
|
192
|
+
// Test case 1: 23 bytes (max direct encoding)
|
|
193
|
+
const result1 = parseString('57' + '00'.repeat(23))
|
|
194
|
+
expect(result1.value.length).toBe(23)
|
|
195
|
+
expect(result1.bytesRead).toBe(24)
|
|
196
|
+
|
|
197
|
+
// Test case 2: 24 bytes (first 1-byte length)
|
|
198
|
+
const result2 = parseString('5818' + '00'.repeat(24))
|
|
199
|
+
expect(result2.value.length).toBe(24)
|
|
200
|
+
expect(result2.bytesRead).toBe(26)
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
it('should handle empty strings correctly', () => {
|
|
204
|
+
const { parseString } = useCborString()
|
|
205
|
+
|
|
206
|
+
// Empty byte string
|
|
207
|
+
const result1 = parseString('40')
|
|
208
|
+
expect(result1.value).toEqual(new Uint8Array([]))
|
|
209
|
+
|
|
210
|
+
// Empty text string
|
|
211
|
+
const result2 = parseString('60')
|
|
212
|
+
expect(result2.value).toBe('')
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('should handle strings with special characters', () => {
|
|
216
|
+
const { parseString } = useCborString()
|
|
217
|
+
|
|
218
|
+
// Text with emoji "Hi 😀" (😀 is 4 bytes: f09f9880)
|
|
219
|
+
// Hex: 68 (text string, length 8) + 486920f09f9880
|
|
220
|
+
const result = parseString('6748 69 20f09f9880'.replace(/\s/g, ''))
|
|
221
|
+
expect(result.value).toBe('Hi 😀')
|
|
222
|
+
})
|
|
223
|
+
})
|
|
224
|
+
})
|