@ic-reactor/candid 3.0.9-beta.0 → 3.0.10-beta.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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata-display-reactor.d.ts +4 -4
- package/dist/metadata-display-reactor.d.ts.map +1 -1
- package/dist/metadata-display-reactor.js +1 -1
- package/dist/metadata-display-reactor.js.map +1 -1
- package/dist/visitor/returns/index.d.ts +23 -71
- package/dist/visitor/returns/index.d.ts.map +1 -1
- package/dist/visitor/returns/index.js +156 -306
- package/dist/visitor/returns/index.js.map +1 -1
- package/dist/visitor/returns/types.d.ts +68 -192
- package/dist/visitor/returns/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/metadata-display-reactor.ts +8 -8
- package/src/visitor/returns/index.test.ts +311 -382
- package/src/visitor/returns/index.ts +237 -387
- package/src/visitor/returns/types.ts +97 -298
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest"
|
|
2
|
-
import { IDL } from "
|
|
2
|
+
import { IDL } from "../types"
|
|
3
3
|
import { ResultFieldVisitor } from "./index"
|
|
4
4
|
import type {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
ResultNode,
|
|
6
|
+
ResolvedNode,
|
|
7
|
+
RecordNode,
|
|
8
|
+
VariantNode,
|
|
9
|
+
TupleNode,
|
|
10
|
+
OptionalNode,
|
|
11
|
+
VectorNode,
|
|
12
|
+
BlobNode,
|
|
13
|
+
RecursiveNode,
|
|
14
|
+
NumberNode,
|
|
15
|
+
TextNode,
|
|
16
|
+
PrincipalNode,
|
|
17
|
+
BooleanNode,
|
|
18
|
+
NullNode,
|
|
19
|
+
MethodMeta,
|
|
20
|
+
ServiceMeta,
|
|
20
21
|
} from "./types"
|
|
21
22
|
|
|
22
23
|
describe("ResultFieldVisitor", () => {
|
|
@@ -35,33 +36,33 @@ describe("ResultFieldVisitor", () => {
|
|
|
35
36
|
expect(field.label).toBe("message")
|
|
36
37
|
expect(field.candidType).toBe("text")
|
|
37
38
|
expect(field.displayType).toBe("string")
|
|
38
|
-
expect(field.
|
|
39
|
+
expect(field.format).toBe("plain")
|
|
39
40
|
})
|
|
40
41
|
|
|
41
42
|
it("should handle text with special label detection", () => {
|
|
42
43
|
const emailField = visitor.visitText(IDL.Text, "email")
|
|
43
|
-
expect(emailField.
|
|
44
|
+
expect(emailField.format).toBe("email")
|
|
44
45
|
|
|
45
46
|
const urlField = visitor.visitText(IDL.Text, "website_url")
|
|
46
|
-
expect(urlField.
|
|
47
|
+
expect(urlField.format).toBe("url")
|
|
47
48
|
|
|
48
49
|
const phoneField = visitor.visitText(IDL.Text, "phone_number")
|
|
49
|
-
expect(phoneField.
|
|
50
|
+
expect(phoneField.format).toBe("phone")
|
|
50
51
|
|
|
51
52
|
const uuidField = visitor.visitText(IDL.Text, "transaction_uuid")
|
|
52
|
-
expect(uuidField.
|
|
53
|
+
expect(uuidField.format).toBe("uuid")
|
|
53
54
|
|
|
54
55
|
const btcField = visitor.visitText(IDL.Text, "btc_address")
|
|
55
|
-
expect(btcField.
|
|
56
|
+
expect(btcField.format).toBe("btc")
|
|
56
57
|
|
|
57
58
|
const ethField = visitor.visitText(IDL.Text, "ethereum_address")
|
|
58
|
-
expect(ethField.
|
|
59
|
+
expect(ethField.format).toBe("eth")
|
|
59
60
|
|
|
60
61
|
const accountIdField = visitor.visitText(IDL.Text, "account_id")
|
|
61
|
-
expect(accountIdField.
|
|
62
|
+
expect(accountIdField.format).toBe("account-id")
|
|
62
63
|
|
|
63
64
|
const principalField = visitor.visitText(IDL.Text, "canister_id")
|
|
64
|
-
expect(principalField.
|
|
65
|
+
expect(principalField.format).toBe("principal")
|
|
65
66
|
})
|
|
66
67
|
|
|
67
68
|
it("should handle bool type", () => {
|
|
@@ -106,7 +107,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
106
107
|
expect(field.type).toBe("number")
|
|
107
108
|
expect(field.candidType).toBe("nat")
|
|
108
109
|
expect(field.displayType).toBe("string") // BigInt → string
|
|
109
|
-
expect(field.
|
|
110
|
+
expect(field.format).toBe("normal")
|
|
110
111
|
})
|
|
111
112
|
|
|
112
113
|
it("should map int to string display type", () => {
|
|
@@ -191,30 +192,30 @@ describe("ResultFieldVisitor", () => {
|
|
|
191
192
|
describe("Number format detection", () => {
|
|
192
193
|
it("should detect timestamp format from label", () => {
|
|
193
194
|
const timestampField = visitor.visitFixedNat(IDL.Nat64, "created_at")
|
|
194
|
-
expect(timestampField.
|
|
195
|
+
expect(timestampField.format).toBe("timestamp")
|
|
195
196
|
|
|
196
197
|
const dateField = visitor.visitNat(IDL.Nat, "timestamp_nanos")
|
|
197
|
-
expect(dateField.
|
|
198
|
+
expect(dateField.format).toBe("timestamp")
|
|
198
199
|
|
|
199
200
|
const deadlineField = visitor.visitNat(IDL.Nat, "deadline")
|
|
200
|
-
expect(deadlineField.
|
|
201
|
+
expect(deadlineField.format).toBe("timestamp")
|
|
201
202
|
})
|
|
202
203
|
|
|
203
204
|
it("should detect cycle format from label", () => {
|
|
204
205
|
const cycleField = visitor.visitNat(IDL.Nat, "cycles")
|
|
205
|
-
expect(cycleField.
|
|
206
|
+
expect(cycleField.format).toBe("cycle")
|
|
206
207
|
|
|
207
208
|
// "cycle" as standalone word
|
|
208
209
|
const cycleSingleField = visitor.visitNat(IDL.Nat, "cycle")
|
|
209
|
-
expect(cycleSingleField.
|
|
210
|
+
expect(cycleSingleField.format).toBe("cycle")
|
|
210
211
|
})
|
|
211
212
|
|
|
212
213
|
it("should default to normal format", () => {
|
|
213
214
|
const amountField = visitor.visitNat(IDL.Nat, "amount")
|
|
214
|
-
expect(amountField.
|
|
215
|
+
expect(amountField.format).toBe("normal")
|
|
215
216
|
|
|
216
217
|
const countField = visitor.visitNat(IDL.Nat, "count")
|
|
217
|
-
expect(countField.
|
|
218
|
+
expect(countField.format).toBe("normal")
|
|
218
219
|
})
|
|
219
220
|
})
|
|
220
221
|
})
|
|
@@ -242,15 +243,15 @@ describe("ResultFieldVisitor", () => {
|
|
|
242
243
|
expect(field.label).toBe("person")
|
|
243
244
|
expect(field.candidType).toBe("record")
|
|
244
245
|
expect(field.displayType).toBe("object")
|
|
245
|
-
expect(field.fields).toHaveLength(2)
|
|
246
|
+
expect(Object.keys(field.fields)).toHaveLength(2)
|
|
246
247
|
|
|
247
|
-
const nameField = field.fields
|
|
248
|
+
const nameField = field.fields["name"]
|
|
248
249
|
if (!nameField || nameField.type !== "text") {
|
|
249
250
|
throw new Error("Name field not found or not text")
|
|
250
251
|
}
|
|
251
252
|
expect(nameField.displayType).toBe("string")
|
|
252
253
|
|
|
253
|
-
const ageField = field.fields
|
|
254
|
+
const ageField = field.fields["age"]
|
|
254
255
|
if (!ageField || ageField.type !== "number") {
|
|
255
256
|
throw new Error("Age field not found or not number")
|
|
256
257
|
}
|
|
@@ -277,14 +278,14 @@ describe("ResultFieldVisitor", () => {
|
|
|
277
278
|
|
|
278
279
|
expect(field.type).toBe("record")
|
|
279
280
|
|
|
280
|
-
const addressField = field.fields
|
|
281
|
+
const addressField = field.fields["address"] as RecordNode
|
|
281
282
|
if (!addressField || addressField.type !== "record") {
|
|
282
283
|
throw new Error("Address field not found or not a record")
|
|
283
284
|
}
|
|
284
285
|
|
|
285
286
|
expect(addressField.type).toBe("record")
|
|
286
287
|
expect(addressField.displayType).toBe("object")
|
|
287
|
-
expect(addressField.fields).toHaveLength(2)
|
|
288
|
+
expect(Object.keys(addressField.fields)).toHaveLength(2)
|
|
288
289
|
})
|
|
289
290
|
|
|
290
291
|
it("should handle ICRC-1 account record", () => {
|
|
@@ -303,22 +304,23 @@ describe("ResultFieldVisitor", () => {
|
|
|
303
304
|
|
|
304
305
|
expect(field.type).toBe("record")
|
|
305
306
|
|
|
306
|
-
const ownerField = field.fields
|
|
307
|
+
const ownerField = field.fields["owner"]
|
|
307
308
|
if (!ownerField || ownerField.type !== "principal") {
|
|
308
309
|
throw new Error("Owner field not found or not principal")
|
|
309
310
|
}
|
|
310
311
|
expect(ownerField.type).toBe("principal")
|
|
311
312
|
expect(ownerField.displayType).toBe("string")
|
|
312
313
|
|
|
313
|
-
const subaccountField = field.fields
|
|
314
|
+
const subaccountField = field.fields["subaccount"] as OptionalNode
|
|
314
315
|
if (!subaccountField || subaccountField.type !== "optional") {
|
|
315
316
|
throw new Error("Subaccount field not found or not optional")
|
|
316
317
|
}
|
|
317
318
|
expect(subaccountField.type).toBe("optional")
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
319
|
+
// Resolve an example value to validate inner blob type
|
|
320
|
+
const subaccountResolved = subaccountField.resolve([
|
|
321
|
+
new Uint8Array([1, 2, 3]),
|
|
322
|
+
])
|
|
323
|
+
expect((subaccountResolved.value as ResolvedNode).type).toBe("blob")
|
|
322
324
|
})
|
|
323
325
|
})
|
|
324
326
|
|
|
@@ -342,10 +344,14 @@ describe("ResultFieldVisitor", () => {
|
|
|
342
344
|
expect(field.type).toBe("variant")
|
|
343
345
|
expect(field.candidType).toBe("variant")
|
|
344
346
|
expect(field.displayType).toBe("variant")
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
expect(
|
|
348
|
-
expect(
|
|
347
|
+
// Validate options by resolving each option
|
|
348
|
+
const resolvedActive = field.resolve({ Active: null })
|
|
349
|
+
expect(resolvedActive.selected).toBe("Active")
|
|
350
|
+
expect(resolvedActive.selectedOption.type).toBe("null")
|
|
351
|
+
const resolvedInactive = field.resolve({ Inactive: null })
|
|
352
|
+
expect(resolvedInactive.selected).toBe("Inactive")
|
|
353
|
+
const resolvedPending = field.resolve({ Pending: null })
|
|
354
|
+
expect(resolvedPending.selected).toBe("Pending")
|
|
349
355
|
})
|
|
350
356
|
|
|
351
357
|
it("should handle variant with payloads", () => {
|
|
@@ -385,26 +391,19 @@ describe("ResultFieldVisitor", () => {
|
|
|
385
391
|
)
|
|
386
392
|
|
|
387
393
|
expect(field.type).toBe("variant")
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (!transferField || transferField.type !== "record") {
|
|
398
|
-
throw new Error("Transfer field not found or not record")
|
|
399
|
-
}
|
|
400
|
-
expect(transferField.type).toBe("record")
|
|
401
|
-
expect(transferField.fields).toHaveLength(3)
|
|
394
|
+
// Validate Transfer payload
|
|
395
|
+
const transferResolved = field.resolve({
|
|
396
|
+
Transfer: { from: "aaaaa-aa", to: "bbbbb-bb", amount: BigInt(1) },
|
|
397
|
+
})
|
|
398
|
+
expect(transferResolved.selected).toBe("Transfer")
|
|
399
|
+
expect(transferResolved.selectedOption.type).toBe("record")
|
|
400
|
+
expect(
|
|
401
|
+
Object.keys((transferResolved.selectedOption as RecordNode).fields)
|
|
402
|
+
).toHaveLength(3)
|
|
402
403
|
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
expect(approveField.type).toBe("number")
|
|
404
|
+
const approveResolved = field.resolve({ Approve: BigInt(5) })
|
|
405
|
+
expect(approveResolved.selected).toBe("Approve")
|
|
406
|
+
expect(approveResolved.selectedOption.type).toBe("number")
|
|
408
407
|
})
|
|
409
408
|
|
|
410
409
|
it("should detect Result variant (Ok/Err)", () => {
|
|
@@ -423,20 +422,16 @@ describe("ResultFieldVisitor", () => {
|
|
|
423
422
|
|
|
424
423
|
expect(field.type).toBe("variant")
|
|
425
424
|
expect(field.displayType).toBe("result") // Special result type
|
|
426
|
-
expect(field.options).toContain("Ok")
|
|
427
|
-
expect(field.options).toContain("Err")
|
|
428
425
|
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
expect(okField.displayType).toBe("string")
|
|
426
|
+
const okResolved = field.resolve({ Ok: BigInt(1) })
|
|
427
|
+
expect(okResolved.selected).toBe("Ok")
|
|
428
|
+
expect(okResolved.selectedOption.type).toBe("number")
|
|
429
|
+
expect(okResolved.selectedOption.displayType).toBe("string")
|
|
434
430
|
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
expect(errField.displayType).toBe("string")
|
|
431
|
+
const errResolved = field.resolve({ Err: "error" })
|
|
432
|
+
expect(errResolved.selected).toBe("Err")
|
|
433
|
+
expect(errResolved.selectedOption.type).toBe("text")
|
|
434
|
+
expect(errResolved.selectedOption.displayType).toBe("string")
|
|
440
435
|
})
|
|
441
436
|
|
|
442
437
|
it("should detect complex Result variant", () => {
|
|
@@ -475,17 +470,15 @@ describe("ResultFieldVisitor", () => {
|
|
|
475
470
|
|
|
476
471
|
expect(field.displayType).toBe("result")
|
|
477
472
|
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
expect(
|
|
473
|
+
const okResolved = field.resolve({
|
|
474
|
+
Ok: { id: BigInt(1), data: new Uint8Array([1, 2, 3]) },
|
|
475
|
+
})
|
|
476
|
+
expect(okResolved.selected).toBe("Ok")
|
|
477
|
+
expect(okResolved.selectedOption.type).toBe("record")
|
|
483
478
|
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
expect(errField.type).toBe("variant")
|
|
479
|
+
const errResolved = field.resolve({ Err: { NotFound: null } })
|
|
480
|
+
expect(errResolved.selected).toBe("Err")
|
|
481
|
+
expect(errResolved.selectedOption.type).toBe("variant")
|
|
489
482
|
})
|
|
490
483
|
|
|
491
484
|
it("should not detect non-Result variant with Ok and other options", () => {
|
|
@@ -516,9 +509,9 @@ describe("ResultFieldVisitor", () => {
|
|
|
516
509
|
expect(field.type).toBe("tuple")
|
|
517
510
|
expect(field.candidType).toBe("tuple")
|
|
518
511
|
expect(field.displayType).toBe("array")
|
|
519
|
-
expect(field.
|
|
520
|
-
expect(field.
|
|
521
|
-
expect(field.
|
|
512
|
+
expect(field.items).toHaveLength(2)
|
|
513
|
+
expect(field.items[0].type).toBe("text")
|
|
514
|
+
expect(field.items[1].type).toBe("number")
|
|
522
515
|
})
|
|
523
516
|
|
|
524
517
|
it("should handle tuple with mixed types", () => {
|
|
@@ -534,17 +527,17 @@ describe("ResultFieldVisitor", () => {
|
|
|
534
527
|
"data"
|
|
535
528
|
)
|
|
536
529
|
|
|
537
|
-
expect(field.
|
|
538
|
-
expect(field.
|
|
539
|
-
expect(field.
|
|
540
|
-
const numField = field.
|
|
530
|
+
expect(field.items).toHaveLength(4)
|
|
531
|
+
expect(field.items[0].type).toBe("principal")
|
|
532
|
+
expect(field.items[1].type).toBe("number")
|
|
533
|
+
const numField = field.items[1]
|
|
541
534
|
if (numField.type === "number") {
|
|
542
535
|
expect(numField.displayType).toBe("string") // nat64 → string
|
|
543
536
|
} else {
|
|
544
537
|
throw new Error("Expected number field")
|
|
545
538
|
}
|
|
546
|
-
expect(field.
|
|
547
|
-
expect(field.
|
|
539
|
+
expect(field.items[2].type).toBe("boolean")
|
|
540
|
+
expect(field.items[3].type).toBe("blob")
|
|
548
541
|
})
|
|
549
542
|
})
|
|
550
543
|
|
|
@@ -556,7 +549,9 @@ describe("ResultFieldVisitor", () => {
|
|
|
556
549
|
expect(field.type).toBe("optional")
|
|
557
550
|
expect(field.candidType).toBe("opt")
|
|
558
551
|
expect(field.displayType).toBe("nullable") // opt T → T | null
|
|
559
|
-
|
|
552
|
+
// Validate inner by resolving a value
|
|
553
|
+
const optResolved = field.resolve(["Bob"])
|
|
554
|
+
expect((optResolved.value as ResolvedNode).type).toBe("text")
|
|
560
555
|
})
|
|
561
556
|
|
|
562
557
|
it("should handle optional record", () => {
|
|
@@ -568,7 +563,9 @@ describe("ResultFieldVisitor", () => {
|
|
|
568
563
|
const field = visitor.visitOpt(optType, recordInOpt, "metadata")
|
|
569
564
|
|
|
570
565
|
expect(field.type).toBe("optional")
|
|
571
|
-
|
|
566
|
+
// Validate inner by resolving a record
|
|
567
|
+
const metaResolved = field.resolve([{ name: "x", value: BigInt(1) }])
|
|
568
|
+
expect((metaResolved.value as ResolvedNode).type).toBe("record")
|
|
572
569
|
})
|
|
573
570
|
|
|
574
571
|
it("should handle nested optional", () => {
|
|
@@ -577,13 +574,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
577
574
|
const field = visitor.visitOpt(optType, innerOpt, "maybeNumber")
|
|
578
575
|
|
|
579
576
|
expect(field.type).toBe("optional")
|
|
580
|
-
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
throw new Error("Inner field is not optional")
|
|
586
|
-
}
|
|
577
|
+
// Validate nested optional by resolving a nested array
|
|
578
|
+
const nestedResolved = field.resolve([[BigInt(1)]])
|
|
579
|
+
expect((nestedResolved.value as ResolvedNode).type).toBe("optional")
|
|
580
|
+
const innerResolved = nestedResolved.value as OptionalNode
|
|
581
|
+
expect((innerResolved.value as ResolvedNode).type).toBe("number")
|
|
587
582
|
})
|
|
588
583
|
})
|
|
589
584
|
|
|
@@ -595,11 +590,10 @@ describe("ResultFieldVisitor", () => {
|
|
|
595
590
|
expect(field.type).toBe("vector")
|
|
596
591
|
expect(field.candidType).toBe("vec")
|
|
597
592
|
expect(field.displayType).toBe("array")
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
}
|
|
593
|
+
// Validate items by resolving
|
|
594
|
+
const vecResolved = field.resolve(["a", "b", "c"]) as VectorNode
|
|
595
|
+
expect(vecResolved.items).toHaveLength(3)
|
|
596
|
+
expect(vecResolved.items[0].value).toBe("a")
|
|
603
597
|
})
|
|
604
598
|
|
|
605
599
|
it("should handle vector of records", () => {
|
|
@@ -611,11 +605,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
611
605
|
const field = visitor.visitVec(vecType, recType, "items")
|
|
612
606
|
|
|
613
607
|
expect(field.type).toBe("vector")
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
608
|
+
// Validate by resolving
|
|
609
|
+
const itemsResolved = field.resolve([
|
|
610
|
+
{ id: BigInt(1), name: "x" },
|
|
611
|
+
]) as VectorNode
|
|
612
|
+
expect(itemsResolved.items[0].type).toBe("record")
|
|
619
613
|
})
|
|
620
614
|
|
|
621
615
|
it("should handle blob (vec nat8)", () => {
|
|
@@ -625,11 +619,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
625
619
|
expect(field.type).toBe("blob")
|
|
626
620
|
expect(field.candidType).toBe("blob")
|
|
627
621
|
expect(field.displayType).toBe("string") // Blob → hex string
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
622
|
+
// Validate by resolving a Uint8Array
|
|
623
|
+
const blobResolved = field.resolve(
|
|
624
|
+
new Uint8Array([0x12, 0x34, 0xab, 0xcd])
|
|
625
|
+
)
|
|
626
|
+
expect(blobResolved.value).toBe("1234abcd")
|
|
633
627
|
})
|
|
634
628
|
|
|
635
629
|
it("should handle nested vectors", () => {
|
|
@@ -638,11 +632,9 @@ describe("ResultFieldVisitor", () => {
|
|
|
638
632
|
const field = visitor.visitVec(nestedVecType, innerVec, "matrix")
|
|
639
633
|
|
|
640
634
|
expect(field.type).toBe("vector")
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
throw new Error("Field is not a vector")
|
|
645
|
-
}
|
|
635
|
+
// Validate nested items via resolve
|
|
636
|
+
const nestedResolved = field.resolve([[BigInt(1)]]) as VectorNode
|
|
637
|
+
expect(nestedResolved.items[0].type).toBe("vector")
|
|
646
638
|
})
|
|
647
639
|
|
|
648
640
|
it("should handle vec of tuples (Map-like)", () => {
|
|
@@ -652,13 +644,15 @@ describe("ResultFieldVisitor", () => {
|
|
|
652
644
|
mapType,
|
|
653
645
|
tupleType,
|
|
654
646
|
"metadata"
|
|
655
|
-
) as
|
|
647
|
+
) as VectorNode
|
|
656
648
|
|
|
657
649
|
expect(field.type).toBe("vector")
|
|
658
|
-
|
|
659
|
-
const
|
|
660
|
-
|
|
661
|
-
|
|
650
|
+
// Validate by resolving a tuple item
|
|
651
|
+
const vecTupleResolved = field.resolve([["a", BigInt(1)]])
|
|
652
|
+
expect(vecTupleResolved.items[0].type).toBe("tuple")
|
|
653
|
+
const item = vecTupleResolved.items[0] as TupleNode
|
|
654
|
+
if (item.type === "tuple") {
|
|
655
|
+
expect(item.items).toHaveLength(2)
|
|
662
656
|
} else {
|
|
663
657
|
throw new Error("Item field is not tuple")
|
|
664
658
|
}
|
|
@@ -693,17 +687,10 @@ describe("ResultFieldVisitor", () => {
|
|
|
693
687
|
expect(field.type).toBe("recursive")
|
|
694
688
|
expect(field.candidType).toBe("rec")
|
|
695
689
|
expect(field.displayType).toBe("recursive")
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
const extracted = field.extract()
|
|
701
|
-
if (extracted.type !== "variant") {
|
|
702
|
-
throw new Error("Extracted field is not variant")
|
|
703
|
-
}
|
|
704
|
-
expect(extracted.type).toBe("variant")
|
|
705
|
-
expect(extracted.options).toContain("Leaf")
|
|
706
|
-
expect(extracted.options).toContain("Node")
|
|
690
|
+
// Resolve to inspect inner schema
|
|
691
|
+
const treeResolved = field.resolve({ Leaf: BigInt(1) }) as RecursiveNode
|
|
692
|
+
expect(treeResolved.inner.type).toBe("variant")
|
|
693
|
+
expect((treeResolved.inner as VariantNode).selected).toBe("Leaf")
|
|
707
694
|
})
|
|
708
695
|
|
|
709
696
|
it("should handle recursive linked list", () => {
|
|
@@ -732,11 +719,9 @@ describe("ResultFieldVisitor", () => {
|
|
|
732
719
|
|
|
733
720
|
expect(field.type).toBe("recursive")
|
|
734
721
|
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
}
|
|
739
|
-
expect(extracted.options).toEqual(["Nil", "Cons"])
|
|
722
|
+
const listResolved = field.resolve({ Nil: null }) as RecursiveNode
|
|
723
|
+
expect(listResolved.inner.type).toBe("variant")
|
|
724
|
+
expect((listResolved.inner as VariantNode).selected).toBe("Nil")
|
|
740
725
|
})
|
|
741
726
|
})
|
|
742
727
|
|
|
@@ -752,11 +737,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
752
737
|
expect(meta.functionType).toBe("query")
|
|
753
738
|
expect(meta.functionName).toBe("get_balance")
|
|
754
739
|
expect(meta.returnCount).toBe(1)
|
|
755
|
-
expect(meta.
|
|
740
|
+
expect(meta.returns).toHaveLength(1)
|
|
756
741
|
|
|
757
|
-
expect(meta.
|
|
742
|
+
expect(meta.returns).toHaveLength(1)
|
|
758
743
|
|
|
759
|
-
const returnField = meta.
|
|
744
|
+
const returnField = meta.returns[0]
|
|
760
745
|
if (returnField.type === "number") {
|
|
761
746
|
expect(returnField.candidType).toBe("nat")
|
|
762
747
|
expect(returnField.displayType).toBe("string")
|
|
@@ -786,7 +771,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
786
771
|
expect(meta.functionType).toBe("update")
|
|
787
772
|
expect(meta.returnCount).toBe(1)
|
|
788
773
|
|
|
789
|
-
const resultField = meta.
|
|
774
|
+
const resultField = meta.returns[0]
|
|
790
775
|
if (resultField.type === "variant") {
|
|
791
776
|
expect(resultField.displayType).toBe("result")
|
|
792
777
|
} else {
|
|
@@ -799,10 +784,10 @@ describe("ResultFieldVisitor", () => {
|
|
|
799
784
|
const meta = visitor.visitFunc(funcType, "get_info")
|
|
800
785
|
|
|
801
786
|
expect(meta.returnCount).toBe(3)
|
|
802
|
-
expect(meta.
|
|
803
|
-
expect(meta.
|
|
804
|
-
expect(meta.
|
|
805
|
-
expect(meta.
|
|
787
|
+
expect(meta.returns).toHaveLength(3)
|
|
788
|
+
expect(meta.returns[0].type).toBe("text")
|
|
789
|
+
expect(meta.returns[1].type).toBe("number")
|
|
790
|
+
expect(meta.returns[2].type).toBe("boolean")
|
|
806
791
|
})
|
|
807
792
|
|
|
808
793
|
it("should handle function with no returns", () => {
|
|
@@ -810,7 +795,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
810
795
|
const meta = visitor.visitFunc(funcType, "log")
|
|
811
796
|
|
|
812
797
|
expect(meta.returnCount).toBe(0)
|
|
813
|
-
expect(meta.
|
|
798
|
+
expect(meta.returns).toHaveLength(0)
|
|
814
799
|
})
|
|
815
800
|
})
|
|
816
801
|
|
|
@@ -852,8 +837,8 @@ describe("ResultFieldVisitor", () => {
|
|
|
852
837
|
const getBalanceMeta = serviceMeta["get_balance"]
|
|
853
838
|
expect(getBalanceMeta.functionType).toBe("query")
|
|
854
839
|
expect(getBalanceMeta.returnCount).toBe(1)
|
|
855
|
-
expect(getBalanceMeta.
|
|
856
|
-
const balanceField = getBalanceMeta.
|
|
840
|
+
expect(getBalanceMeta.returns[0].type).toBe("number")
|
|
841
|
+
const balanceField = getBalanceMeta.returns[0]
|
|
857
842
|
if (balanceField.type === "number") {
|
|
858
843
|
expect(balanceField.displayType).toBe("string")
|
|
859
844
|
} else {
|
|
@@ -867,7 +852,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
867
852
|
// Check get_metadata
|
|
868
853
|
const getMetadataMeta = serviceMeta["get_metadata"]
|
|
869
854
|
expect(getMetadataMeta.returnCount).toBe(1)
|
|
870
|
-
expect(getMetadataMeta.
|
|
855
|
+
expect(getMetadataMeta.returns[0].type).toBe("vector")
|
|
871
856
|
})
|
|
872
857
|
})
|
|
873
858
|
|
|
@@ -892,7 +877,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
892
877
|
expect(meta.functionType).toBe("query")
|
|
893
878
|
expect(meta.returnCount).toBe(1)
|
|
894
879
|
|
|
895
|
-
const balanceField = meta.
|
|
880
|
+
const balanceField = meta.returns[0]
|
|
896
881
|
if (balanceField.type === "number") {
|
|
897
882
|
expect(balanceField.candidType).toBe("nat")
|
|
898
883
|
expect(balanceField.displayType).toBe("string")
|
|
@@ -942,23 +927,28 @@ describe("ResultFieldVisitor", () => {
|
|
|
942
927
|
|
|
943
928
|
expect(field.displayType).toBe("result")
|
|
944
929
|
|
|
945
|
-
const
|
|
946
|
-
|
|
947
|
-
if (!okField || okField.type !== "number") {
|
|
930
|
+
const okResolved = field.resolve({ Ok: BigInt(123) })
|
|
931
|
+
if ((okResolved.selectedOption as ResolvedNode).type !== "number") {
|
|
948
932
|
throw new Error("Ok field is not number")
|
|
949
933
|
}
|
|
934
|
+
expect((okResolved.selectedOption as ResolvedNode).candidType).toBe("nat")
|
|
935
|
+
expect((okResolved.selectedOption as ResolvedNode).displayType).toBe(
|
|
936
|
+
"string"
|
|
937
|
+
)
|
|
950
938
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
const
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
expect(
|
|
960
|
-
|
|
961
|
-
|
|
939
|
+
const errResolved = field.resolve({
|
|
940
|
+
Err: { InsufficientFunds: { balance: BigInt(0) } },
|
|
941
|
+
})
|
|
942
|
+
const innerErr = errResolved.selectedOption as ResolvedNode
|
|
943
|
+
expect(innerErr.type).toBe("variant")
|
|
944
|
+
const insufficient = (innerErr as any).resolve({
|
|
945
|
+
InsufficientFunds: { balance: BigInt(0) },
|
|
946
|
+
})
|
|
947
|
+
expect(insufficient.selected).toBe("InsufficientFunds")
|
|
948
|
+
const generic = (innerErr as any).resolve({
|
|
949
|
+
GenericError: { error_code: BigInt(1), message: "err" },
|
|
950
|
+
})
|
|
951
|
+
expect(generic.selected).toBe("GenericError")
|
|
962
952
|
})
|
|
963
953
|
|
|
964
954
|
it("should handle SNS canister status return", () => {
|
|
@@ -1011,45 +1001,46 @@ describe("ResultFieldVisitor", () => {
|
|
|
1011
1001
|
expect(field.type).toBe("record")
|
|
1012
1002
|
|
|
1013
1003
|
// Check status variant
|
|
1014
|
-
const statusField = field.fields
|
|
1004
|
+
const statusField = field.fields["status"] as VariantNode
|
|
1015
1005
|
if (!statusField || statusField.type !== "variant") {
|
|
1016
|
-
throw new Error("Status field
|
|
1006
|
+
throw new Error("Status field not found or not variant")
|
|
1017
1007
|
}
|
|
1018
1008
|
expect(statusField.type).toBe("variant")
|
|
1019
|
-
expect(statusField.
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
expect(
|
|
1009
|
+
expect(statusField.displayType).toBe("variant")
|
|
1010
|
+
// Validate via resolving options
|
|
1011
|
+
const statusResolved = statusField.resolve({ running: null })
|
|
1012
|
+
expect(statusResolved.selected).toBe("running")
|
|
1023
1013
|
|
|
1024
1014
|
// Check settings record
|
|
1025
|
-
const settingsField = field.fields
|
|
1015
|
+
const settingsField = field.fields["settings"] as RecordNode
|
|
1026
1016
|
if (!settingsField || settingsField.type !== "record") {
|
|
1027
|
-
throw new Error("Settings field
|
|
1017
|
+
throw new Error("Settings field not found or not record")
|
|
1028
1018
|
}
|
|
1029
1019
|
expect(settingsField.type).toBe("record")
|
|
1020
|
+
expect(settingsField.displayType).toBe("object")
|
|
1030
1021
|
|
|
1031
|
-
const controllersField = settingsField.fields
|
|
1032
|
-
(f) => f.label === "controllers"
|
|
1033
|
-
)
|
|
1022
|
+
const controllersField = settingsField.fields["controllers"] as VectorNode
|
|
1034
1023
|
if (!controllersField || controllersField.type !== "vector") {
|
|
1035
|
-
throw new Error("Controllers field
|
|
1024
|
+
throw new Error("Controllers field not found or not vector")
|
|
1036
1025
|
}
|
|
1037
1026
|
expect(controllersField.type).toBe("vector")
|
|
1038
|
-
|
|
1027
|
+
// Validate item type via resolve
|
|
1028
|
+
const controllersResolved = controllersField.resolve(["aaaaa-aa"])
|
|
1029
|
+
expect(controllersResolved.items[0].type).toBe("principal")
|
|
1039
1030
|
|
|
1040
1031
|
// Check cycles - should detect special format
|
|
1041
|
-
const cyclesField = field.fields
|
|
1032
|
+
const cyclesField = field.fields["cycles"] as NumberNode
|
|
1042
1033
|
if (!cyclesField || cyclesField.type !== "number") {
|
|
1043
|
-
throw new Error("Cycles field
|
|
1034
|
+
throw new Error("Cycles field not found or not number")
|
|
1044
1035
|
}
|
|
1045
|
-
expect(cyclesField.
|
|
1036
|
+
expect(cyclesField.format).toBe("cycle")
|
|
1046
1037
|
|
|
1047
1038
|
// Check module_hash - optional blob
|
|
1048
|
-
const moduleHashField = field.fields
|
|
1049
|
-
(f) => f.label === "module_hash"
|
|
1050
|
-
) as OptionalResultField
|
|
1039
|
+
const moduleHashField = field.fields["module_hash"] as OptionalNode
|
|
1051
1040
|
expect(moduleHashField.type).toBe("optional")
|
|
1052
|
-
|
|
1041
|
+
// Validate via resolving a sample blob
|
|
1042
|
+
const moduleHashResolved = moduleHashField.resolve([new Uint8Array([1])])
|
|
1043
|
+
expect((moduleHashResolved.value as ResolvedNode).type).toBe("blob")
|
|
1053
1044
|
})
|
|
1054
1045
|
|
|
1055
1046
|
it("should handle complex governance proposal types", () => {
|
|
@@ -1114,12 +1105,10 @@ describe("ResultFieldVisitor", () => {
|
|
|
1114
1105
|
)
|
|
1115
1106
|
|
|
1116
1107
|
expect(field.type).toBe("record")
|
|
1117
|
-
expect(field.fields
|
|
1108
|
+
expect(Object.keys(field.fields)).toHaveLength(12)
|
|
1118
1109
|
|
|
1119
1110
|
// Check timestamp field (note: the label pattern matching may not match "proposal_timestamp_seconds")
|
|
1120
|
-
const timestampField = field.fields
|
|
1121
|
-
(f) => f.label === "proposal_timestamp_seconds"
|
|
1122
|
-
)
|
|
1111
|
+
const timestampField = field.fields["proposal_timestamp_seconds"]
|
|
1123
1112
|
if (!timestampField || timestampField.type !== "number") {
|
|
1124
1113
|
throw new Error("Timestamp field not found or not number")
|
|
1125
1114
|
}
|
|
@@ -1127,20 +1116,23 @@ describe("ResultFieldVisitor", () => {
|
|
|
1127
1116
|
expect(timestampField.displayType).toBe("string") // nat64 → string
|
|
1128
1117
|
|
|
1129
1118
|
// Check ballots - vec of tuples
|
|
1130
|
-
const ballotsField = field.fields
|
|
1119
|
+
const ballotsField = field.fields["ballots"]
|
|
1131
1120
|
if (!ballotsField || ballotsField.type !== "vector") {
|
|
1132
1121
|
throw new Error("Ballots field not found or not vector")
|
|
1133
1122
|
}
|
|
1134
1123
|
expect(ballotsField.type).toBe("vector")
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1124
|
+
// Validate via resolve
|
|
1125
|
+
const ballotsResolved = ballotsField.resolve([
|
|
1126
|
+
[BigInt(1), { vote: 1, voting_power: BigInt(2) }],
|
|
1127
|
+
]) as TupleNode
|
|
1128
|
+
expect(ballotsResolved.items).toHaveLength(1)
|
|
1129
|
+
const ballotTuple = ballotsResolved.items[0] as TupleNode
|
|
1138
1130
|
if (ballotTuple.type !== "tuple") {
|
|
1139
1131
|
throw new Error("Ballot item is not tuple")
|
|
1140
1132
|
}
|
|
1141
|
-
expect(ballotTuple.
|
|
1142
|
-
expect(ballotTuple.
|
|
1143
|
-
expect(ballotTuple.
|
|
1133
|
+
expect(ballotTuple.items).toHaveLength(2)
|
|
1134
|
+
expect(ballotTuple.items[0].type).toBe("number") // nat64
|
|
1135
|
+
expect(ballotTuple.items[1].type).toBe("record") // ballot record
|
|
1144
1136
|
})
|
|
1145
1137
|
})
|
|
1146
1138
|
|
|
@@ -1179,7 +1171,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1179
1171
|
if (typeof field === "object" && "displayType" in field) {
|
|
1180
1172
|
expect(field.displayType).toBe(expectedDisplay)
|
|
1181
1173
|
} else {
|
|
1182
|
-
throw new Error("Expected
|
|
1174
|
+
throw new Error("Expected as ResultNode")
|
|
1183
1175
|
}
|
|
1184
1176
|
})
|
|
1185
1177
|
})
|
|
@@ -1194,40 +1186,30 @@ describe("ResultFieldVisitor", () => {
|
|
|
1194
1186
|
it("should resolve text field with value", () => {
|
|
1195
1187
|
const field = visitor.visitText(IDL.Text, "message")
|
|
1196
1188
|
const resolved = field.resolve("Hello World")
|
|
1197
|
-
|
|
1198
|
-
expect(resolved.field).toBe(field)
|
|
1199
1189
|
expect(resolved.value).toBe("Hello World")
|
|
1200
1190
|
})
|
|
1201
1191
|
|
|
1202
1192
|
it("should resolve number field with value", () => {
|
|
1203
1193
|
const field = visitor.visitNat(IDL.Nat, "amount")
|
|
1204
1194
|
const resolved = field.resolve(BigInt(1000000))
|
|
1205
|
-
|
|
1206
|
-
expect(resolved.field).toBe(field)
|
|
1207
1195
|
expect(resolved.value).toBe("1000000")
|
|
1208
1196
|
})
|
|
1209
1197
|
|
|
1210
1198
|
it("should resolve boolean field with value", () => {
|
|
1211
1199
|
const field = visitor.visitBool(IDL.Bool, "active")
|
|
1212
1200
|
const resolved = field.resolve(true)
|
|
1213
|
-
|
|
1214
|
-
expect(resolved.field).toBe(field)
|
|
1215
1201
|
expect(resolved.value).toBe(true)
|
|
1216
1202
|
})
|
|
1217
1203
|
|
|
1218
1204
|
it("should resolve null field", () => {
|
|
1219
1205
|
const field = visitor.visitNull(IDL.Null, "empty")
|
|
1220
1206
|
const resolved = field.resolve(null)
|
|
1221
|
-
|
|
1222
|
-
expect(resolved.field).toBe(field)
|
|
1223
1207
|
expect(resolved.value).toBe(null)
|
|
1224
1208
|
})
|
|
1225
1209
|
|
|
1226
1210
|
it("should resolve principal field with string value", () => {
|
|
1227
1211
|
const field = visitor.visitPrincipal(IDL.Principal, "owner")
|
|
1228
1212
|
const resolved = field.resolve("aaaaa-aa")
|
|
1229
|
-
|
|
1230
|
-
expect(resolved.field).toBe(field)
|
|
1231
1213
|
expect(resolved.value).toBe("aaaaa-aa")
|
|
1232
1214
|
})
|
|
1233
1215
|
})
|
|
@@ -1255,14 +1237,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
1255
1237
|
active: true,
|
|
1256
1238
|
})
|
|
1257
1239
|
|
|
1258
|
-
expect(resolved.
|
|
1259
|
-
const value = resolved.
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
expect(value.name.value).toBe("Alice")
|
|
1264
|
-
expect(value.age.value).toBe(30)
|
|
1265
|
-
expect(value.active.value).toBe(true)
|
|
1240
|
+
expect(resolved.type).toBe(field.type)
|
|
1241
|
+
const value = resolved.fields as Record<string, ResolvedNode>
|
|
1242
|
+
expect(value["name"].value).toBe("Alice")
|
|
1243
|
+
expect(value["age"].value).toBe(30)
|
|
1244
|
+
expect(value["active"].value).toBe(true)
|
|
1266
1245
|
})
|
|
1267
1246
|
|
|
1268
1247
|
it("should handle null record value", () => {
|
|
@@ -1295,13 +1274,10 @@ describe("ResultFieldVisitor", () => {
|
|
|
1295
1274
|
)
|
|
1296
1275
|
|
|
1297
1276
|
const resolved = field.resolve({ Ok: "Success" })
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
}
|
|
1303
|
-
expect(value.option).toBe("Ok")
|
|
1304
|
-
expect(value.value.value).toBe("Success")
|
|
1277
|
+
expect(resolved.type).toBe(field.type)
|
|
1278
|
+
expect(resolved.selected).toBe("Ok")
|
|
1279
|
+
const data = resolved.selectedOption as ResolvedNode
|
|
1280
|
+
expect(data.value).toBe("Success")
|
|
1305
1281
|
})
|
|
1306
1282
|
|
|
1307
1283
|
it("should resolve variant with Err option", () => {
|
|
@@ -1320,12 +1296,9 @@ describe("ResultFieldVisitor", () => {
|
|
|
1320
1296
|
|
|
1321
1297
|
const resolved = field.resolve({ Err: "Something went wrong" })
|
|
1322
1298
|
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
}
|
|
1327
|
-
expect(value.option).toBe("Err")
|
|
1328
|
-
expect(value.value.value).toBe("Something went wrong")
|
|
1299
|
+
expect(resolved.selected).toBe("Err")
|
|
1300
|
+
const data = resolved.selectedOption as ResolvedNode
|
|
1301
|
+
expect(data.value).toBe("Something went wrong")
|
|
1329
1302
|
})
|
|
1330
1303
|
|
|
1331
1304
|
it("should handle null variant value", () => {
|
|
@@ -1356,11 +1329,8 @@ describe("ResultFieldVisitor", () => {
|
|
|
1356
1329
|
|
|
1357
1330
|
const resolved = field.resolve(["hello", 123n, true])
|
|
1358
1331
|
|
|
1359
|
-
expect(resolved.
|
|
1360
|
-
const value = resolved.
|
|
1361
|
-
field: ResultField
|
|
1362
|
-
value: unknown
|
|
1363
|
-
}>
|
|
1332
|
+
expect(resolved.type).toBe(field.type)
|
|
1333
|
+
const value = resolved.items as ResolvedNode[]
|
|
1364
1334
|
expect(value).toHaveLength(3)
|
|
1365
1335
|
expect(value[0].value).toBe("hello")
|
|
1366
1336
|
expect(value[1].value).toBe("123")
|
|
@@ -1384,8 +1354,8 @@ describe("ResultFieldVisitor", () => {
|
|
|
1384
1354
|
|
|
1385
1355
|
const resolved = field.resolve(["Bob"])
|
|
1386
1356
|
|
|
1387
|
-
expect(resolved.
|
|
1388
|
-
const inner = resolved.value as
|
|
1357
|
+
expect(resolved.type).toBe(field.type)
|
|
1358
|
+
const inner = resolved.value as ResolvedNode
|
|
1389
1359
|
expect(inner.value).toBe("Bob")
|
|
1390
1360
|
})
|
|
1391
1361
|
|
|
@@ -1394,8 +1364,6 @@ describe("ResultFieldVisitor", () => {
|
|
|
1394
1364
|
const field = visitor.visitOpt(optType, IDL.Text, "nickname")
|
|
1395
1365
|
|
|
1396
1366
|
const resolved = field.resolve(null)
|
|
1397
|
-
|
|
1398
|
-
expect(resolved.field).toBe(field)
|
|
1399
1367
|
expect(resolved.value).toBe(null)
|
|
1400
1368
|
})
|
|
1401
1369
|
})
|
|
@@ -1405,13 +1373,10 @@ describe("ResultFieldVisitor", () => {
|
|
|
1405
1373
|
const vecType = IDL.Vec(IDL.Text)
|
|
1406
1374
|
const field = visitor.visitVec(vecType, IDL.Text, "tags")
|
|
1407
1375
|
|
|
1408
|
-
const resolved = field.resolve(["a", "b", "c"])
|
|
1376
|
+
const resolved = field.resolve(["a", "b", "c"]) as VectorNode
|
|
1409
1377
|
|
|
1410
|
-
expect(resolved.
|
|
1411
|
-
const value = resolved.
|
|
1412
|
-
field: ResultField
|
|
1413
|
-
value: unknown
|
|
1414
|
-
}>
|
|
1378
|
+
expect(resolved.type).toBe(field.type)
|
|
1379
|
+
const value = resolved.items as ResolvedNode[]
|
|
1415
1380
|
expect(value).toHaveLength(3)
|
|
1416
1381
|
expect(value[0].value).toBe("a")
|
|
1417
1382
|
expect(value[1].value).toBe("b")
|
|
@@ -1422,12 +1387,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
1422
1387
|
const vecType = IDL.Vec(IDL.Nat)
|
|
1423
1388
|
const field = visitor.visitVec(vecType, IDL.Nat, "numbers")
|
|
1424
1389
|
|
|
1425
|
-
const resolved = field.resolve([])
|
|
1390
|
+
const resolved = field.resolve([]) as VectorNode
|
|
1426
1391
|
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
}>
|
|
1392
|
+
expect(resolved.type).toBe(field.type)
|
|
1393
|
+
|
|
1394
|
+
const value = resolved.items as ResolvedNode[]
|
|
1431
1395
|
expect(value).toHaveLength(0)
|
|
1432
1396
|
})
|
|
1433
1397
|
|
|
@@ -1448,7 +1412,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1448
1412
|
|
|
1449
1413
|
const resolved = field.resolve(new Uint8Array([0x12, 0x34, 0xab, 0xcd]))
|
|
1450
1414
|
|
|
1451
|
-
expect(resolved.
|
|
1415
|
+
expect(resolved.type).toBe(field.type)
|
|
1452
1416
|
expect(resolved.value).toBe("1234abcd")
|
|
1453
1417
|
})
|
|
1454
1418
|
})
|
|
@@ -1479,7 +1443,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1479
1443
|
})
|
|
1480
1444
|
|
|
1481
1445
|
// The recursive type should delegate to its inner record type
|
|
1482
|
-
expect(resolved.
|
|
1446
|
+
expect(resolved.type).toBe("recursive")
|
|
1483
1447
|
})
|
|
1484
1448
|
})
|
|
1485
1449
|
|
|
@@ -1519,29 +1483,24 @@ describe("ResultFieldVisitor", () => {
|
|
|
1519
1483
|
},
|
|
1520
1484
|
})
|
|
1521
1485
|
|
|
1522
|
-
const value = resolved.
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
string,
|
|
1532
|
-
{ field: ResultField; value: unknown }
|
|
1533
|
-
>
|
|
1534
|
-
expect(profileValue.name.value).toBe("Alice")
|
|
1535
|
-
expect(profileValue.verified.value).toBe(true)
|
|
1486
|
+
const value = resolved.fields as Record<string, ResolvedNode>
|
|
1487
|
+
const userNode = value.user as RecordNode
|
|
1488
|
+
if (userNode.type !== "record") {
|
|
1489
|
+
throw new Error("User node is not a record")
|
|
1490
|
+
}
|
|
1491
|
+
const profileNode = userNode.fields["profile"] as RecordNode
|
|
1492
|
+
const profileFields = profileNode.fields as Record<string, ResolvedNode>
|
|
1493
|
+
expect(profileFields["name"].value).toBe("Alice")
|
|
1494
|
+
expect(profileFields["verified"].value).toBe(true)
|
|
1536
1495
|
})
|
|
1537
1496
|
})
|
|
1538
1497
|
})
|
|
1539
1498
|
|
|
1540
1499
|
// ════════════════════════════════════════════════════════════════════════
|
|
1541
|
-
//
|
|
1500
|
+
// resolve() Method Tests
|
|
1542
1501
|
// ════════════════════════════════════════════════════════════════════════
|
|
1543
1502
|
|
|
1544
|
-
describe("
|
|
1503
|
+
describe("resolve() Method", () => {
|
|
1545
1504
|
it("should generate metadata for single return value", () => {
|
|
1546
1505
|
const service = IDL.Service({
|
|
1547
1506
|
getName: IDL.Func([], [IDL.Text], ["query"]),
|
|
@@ -1552,13 +1511,13 @@ describe("ResultFieldVisitor", () => {
|
|
|
1552
1511
|
)
|
|
1553
1512
|
const methodMeta = serviceMeta["getName"]
|
|
1554
1513
|
|
|
1555
|
-
const result = methodMeta.
|
|
1514
|
+
const result = methodMeta.resolve("Alice")
|
|
1556
1515
|
|
|
1557
1516
|
expect(result.functionName).toBe("getName")
|
|
1558
1517
|
expect(result.functionType).toBe("query")
|
|
1559
1518
|
expect(result.results).toHaveLength(1)
|
|
1560
1519
|
expect(result.results[0].value).toBe("Alice")
|
|
1561
|
-
expect(result.results[0].
|
|
1520
|
+
expect(result.results[0].type).toBe("text")
|
|
1562
1521
|
})
|
|
1563
1522
|
|
|
1564
1523
|
it("should generate metadata for multiple return values", () => {
|
|
@@ -1571,18 +1530,14 @@ describe("ResultFieldVisitor", () => {
|
|
|
1571
1530
|
)
|
|
1572
1531
|
const methodMeta = serviceMeta["getStats"]
|
|
1573
1532
|
|
|
1574
|
-
const result = methodMeta.
|
|
1575
|
-
BigInt(100),
|
|
1576
|
-
BigInt(200),
|
|
1577
|
-
"active",
|
|
1578
|
-
])
|
|
1533
|
+
const result = methodMeta.resolve([BigInt(100), BigInt(200), "active"])
|
|
1579
1534
|
|
|
1580
1535
|
expect(result.results).toHaveLength(3)
|
|
1581
1536
|
expect(result.results[0].value).toBe("100")
|
|
1582
|
-
expect(result.results[0].
|
|
1537
|
+
expect(result.results[0].type).toBe("number")
|
|
1583
1538
|
expect(result.results[1].value).toBe("200")
|
|
1584
1539
|
expect(result.results[2].value).toBe("active")
|
|
1585
|
-
expect(result.results[2].
|
|
1540
|
+
expect(result.results[2].type).toBe("text")
|
|
1586
1541
|
})
|
|
1587
1542
|
|
|
1588
1543
|
it("should generate metadata for record return value", () => {
|
|
@@ -1599,22 +1554,19 @@ describe("ResultFieldVisitor", () => {
|
|
|
1599
1554
|
)
|
|
1600
1555
|
const methodMeta = serviceMeta["getUser"]
|
|
1601
1556
|
|
|
1602
|
-
const result = methodMeta.
|
|
1557
|
+
const result = methodMeta.resolve({
|
|
1603
1558
|
name: "Bob",
|
|
1604
1559
|
balance: BigInt(1000),
|
|
1605
1560
|
})
|
|
1606
1561
|
|
|
1607
1562
|
expect(result.results).toHaveLength(1)
|
|
1608
|
-
expect(result.results[0].
|
|
1563
|
+
expect(result.results[0].type).toBe("record")
|
|
1609
1564
|
|
|
1610
|
-
const
|
|
1611
|
-
if (
|
|
1612
|
-
throw new Error("Expected record
|
|
1565
|
+
const recordNode = result.results[0] as RecordNode
|
|
1566
|
+
if (recordNode.type !== "record") {
|
|
1567
|
+
throw new Error("Expected record node")
|
|
1613
1568
|
}
|
|
1614
|
-
const val =
|
|
1615
|
-
string,
|
|
1616
|
-
{ field: ResultField; value: unknown }
|
|
1617
|
-
>
|
|
1569
|
+
const val = recordNode.fields as Record<string, ResolvedNode>
|
|
1618
1570
|
expect(val.name.value).toBe("Bob")
|
|
1619
1571
|
expect(val.balance.value).toBe("1000")
|
|
1620
1572
|
})
|
|
@@ -1634,31 +1586,29 @@ describe("ResultFieldVisitor", () => {
|
|
|
1634
1586
|
const methodMeta = serviceMeta["transfer"]
|
|
1635
1587
|
|
|
1636
1588
|
// Test Ok case
|
|
1637
|
-
const okResult = methodMeta.
|
|
1638
|
-
expect(okResult.results[0].
|
|
1639
|
-
if (okResult.results[0].
|
|
1640
|
-
expect(okResult.results[0].
|
|
1589
|
+
const okResult = methodMeta.resolve({ Ok: BigInt(12345) })
|
|
1590
|
+
expect(okResult.results[0].type).toBe("variant")
|
|
1591
|
+
if (okResult.results[0].type === "variant") {
|
|
1592
|
+
expect(okResult.results[0].displayType).toBe("result")
|
|
1641
1593
|
} else {
|
|
1642
1594
|
throw new Error("Expected variant field")
|
|
1643
1595
|
}
|
|
1644
1596
|
|
|
1645
|
-
const okValue = okResult.results[0]
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
expect(okValue.value.value).toBe("12345")
|
|
1597
|
+
const okValue = okResult.results[0] as ResolvedNode
|
|
1598
|
+
expect((okValue as any).selected).toBe("Ok")
|
|
1599
|
+
expect(((okValue as any).selectedOption as ResolvedNode).value).toBe(
|
|
1600
|
+
"12345"
|
|
1601
|
+
)
|
|
1651
1602
|
|
|
1652
1603
|
// Test Err case
|
|
1653
|
-
const errResult = methodMeta.
|
|
1604
|
+
const errResult = methodMeta.resolve({
|
|
1654
1605
|
Err: "Insufficient funds",
|
|
1655
1606
|
})
|
|
1656
|
-
const errValue = errResult.results[0]
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
expect(errValue.value.value).toBe("Insufficient funds")
|
|
1607
|
+
const errValue = errResult.results[0] as ResolvedNode
|
|
1608
|
+
expect((errValue as any).selected).toBe("Err")
|
|
1609
|
+
expect(((errValue as any).selectedOption as ResolvedNode).value).toBe(
|
|
1610
|
+
"Insufficient funds"
|
|
1611
|
+
)
|
|
1662
1612
|
})
|
|
1663
1613
|
|
|
1664
1614
|
it("should generate metadata for optional return value", () => {
|
|
@@ -1672,16 +1622,13 @@ describe("ResultFieldVisitor", () => {
|
|
|
1672
1622
|
const methodMeta = serviceMeta["findUser"]
|
|
1673
1623
|
|
|
1674
1624
|
// Test with value - Optional is [value]
|
|
1675
|
-
const foundResult = methodMeta.
|
|
1676
|
-
expect(foundResult.results[0].
|
|
1677
|
-
const foundInner = foundResult.results[0]
|
|
1678
|
-
|
|
1679
|
-
value: unknown
|
|
1680
|
-
}
|
|
1681
|
-
expect(foundInner.value).toBe("Alice")
|
|
1625
|
+
const foundResult = methodMeta.resolve(["Alice"])
|
|
1626
|
+
expect(foundResult.results[0].type).toBe("optional")
|
|
1627
|
+
const foundInner = foundResult.results[0] as OptionalNode
|
|
1628
|
+
expect(foundInner.value?.value).toBe("Alice")
|
|
1682
1629
|
|
|
1683
1630
|
// Test with null - optional is []
|
|
1684
|
-
const notFoundResult = methodMeta.
|
|
1631
|
+
const notFoundResult = methodMeta.resolve([])
|
|
1685
1632
|
expect(notFoundResult.results[0].value).toBe(null)
|
|
1686
1633
|
})
|
|
1687
1634
|
|
|
@@ -1695,17 +1642,15 @@ describe("ResultFieldVisitor", () => {
|
|
|
1695
1642
|
)
|
|
1696
1643
|
const methodMeta = serviceMeta["getItems"]
|
|
1697
1644
|
|
|
1698
|
-
const result = methodMeta.
|
|
1645
|
+
const result = methodMeta.resolve(["item1", "item2", "item3"])
|
|
1699
1646
|
|
|
1700
|
-
expect(result.results[0].
|
|
1701
|
-
const
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
expect(
|
|
1706
|
-
expect(
|
|
1707
|
-
expect(vecValue[1].value).toBe("item2")
|
|
1708
|
-
expect(vecValue[2].value).toBe("item3")
|
|
1647
|
+
expect(result.results[0].type).toBe("vector")
|
|
1648
|
+
const vecNode = result.results[0] as ResolvedNode
|
|
1649
|
+
const vecItems = (vecNode as any).items as ResolvedNode[]
|
|
1650
|
+
expect(vecItems).toHaveLength(3)
|
|
1651
|
+
expect(vecItems[0].value).toBe("item1")
|
|
1652
|
+
expect(vecItems[1].value).toBe("item2")
|
|
1653
|
+
expect(vecItems[2].value).toBe("item3")
|
|
1709
1654
|
})
|
|
1710
1655
|
|
|
1711
1656
|
it("should generate metadata for update function", () => {
|
|
@@ -1721,7 +1666,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1721
1666
|
expect(methodMeta.functionType).toBe("update")
|
|
1722
1667
|
|
|
1723
1668
|
const rawData = [true]
|
|
1724
|
-
const result = methodMeta.
|
|
1669
|
+
const result = methodMeta.resolve(rawData[0])
|
|
1725
1670
|
|
|
1726
1671
|
expect(result.functionType).toBe("update")
|
|
1727
1672
|
expect(result.functionName).toBe("setName")
|
|
@@ -1754,7 +1699,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1754
1699
|
const methodMeta = serviceMeta["icrc1_transfer"]
|
|
1755
1700
|
|
|
1756
1701
|
// Test successful transfer
|
|
1757
|
-
const successResult = methodMeta.
|
|
1702
|
+
const successResult = methodMeta.resolve({ Ok: BigInt(1000) })
|
|
1758
1703
|
console.log(
|
|
1759
1704
|
"🚀 ~ result:",
|
|
1760
1705
|
JSON.stringify(
|
|
@@ -1764,28 +1709,24 @@ describe("ResultFieldVisitor", () => {
|
|
|
1764
1709
|
)
|
|
1765
1710
|
)
|
|
1766
1711
|
|
|
1767
|
-
const successValue = successResult.results[0]
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
expect(successValue.value.value).toBe("1000")
|
|
1712
|
+
const successValue = successResult.results[0] as ResolvedNode
|
|
1713
|
+
expect((successValue as any).selected).toBe("Ok")
|
|
1714
|
+
expect(((successValue as any).selectedOption as ResolvedNode).value).toBe(
|
|
1715
|
+
"1000"
|
|
1716
|
+
)
|
|
1773
1717
|
|
|
1774
1718
|
// Test error case
|
|
1775
|
-
const errorResult = methodMeta.
|
|
1719
|
+
const errorResult = methodMeta.resolve({
|
|
1776
1720
|
Err: { InsufficientFunds: { balance: BigInt(50) } },
|
|
1777
1721
|
})
|
|
1778
|
-
const errorValue = errorResult.results[0]
|
|
1779
|
-
|
|
1780
|
-
value: { field: ResultField; value: unknown }
|
|
1781
|
-
}
|
|
1782
|
-
expect(errorValue.option).toBe("Err")
|
|
1722
|
+
const errorValue = errorResult.results[0] as ResolvedNode
|
|
1723
|
+
expect((errorValue as any).selected).toBe("Err")
|
|
1783
1724
|
|
|
1784
|
-
const val = errorValue.
|
|
1785
|
-
if (typeof val !== "object" || val === null || !("
|
|
1725
|
+
const val = (errorValue as any).selectedOption as ResolvedNode
|
|
1726
|
+
if (typeof val !== "object" || val === null || !("selected" in val)) {
|
|
1786
1727
|
throw new Error("Expected variant value object")
|
|
1787
1728
|
}
|
|
1788
|
-
expect(val.
|
|
1729
|
+
expect((val as any).selected).toBe("InsufficientFunds")
|
|
1789
1730
|
})
|
|
1790
1731
|
|
|
1791
1732
|
it("should handle empty return", () => {
|
|
@@ -1800,16 +1741,16 @@ describe("ResultFieldVisitor", () => {
|
|
|
1800
1741
|
|
|
1801
1742
|
expect(methodMeta.returnCount).toBe(0)
|
|
1802
1743
|
|
|
1803
|
-
const result = methodMeta.
|
|
1744
|
+
const result = methodMeta.resolve([])
|
|
1804
1745
|
expect(result.results).toHaveLength(0)
|
|
1805
1746
|
})
|
|
1806
1747
|
})
|
|
1807
1748
|
|
|
1808
1749
|
// ════════════════════════════════════════════════════════════════════════════
|
|
1809
|
-
//
|
|
1750
|
+
// resolve() Method Tests
|
|
1810
1751
|
// ════════════════════════════════════════════════════════════════════════════
|
|
1811
1752
|
|
|
1812
|
-
describe("
|
|
1753
|
+
describe("resolve() Method", () => {
|
|
1813
1754
|
it("should include both raw and display values for single return", () => {
|
|
1814
1755
|
const service = IDL.Service({
|
|
1815
1756
|
getBalance: IDL.Func([], [IDL.Nat], ["query"]),
|
|
@@ -1823,7 +1764,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1823
1764
|
// Simulate raw BigInt and display string
|
|
1824
1765
|
const rawData = [BigInt(1000000)]
|
|
1825
1766
|
|
|
1826
|
-
const result = methodMeta.
|
|
1767
|
+
const result = methodMeta.resolve(rawData[0])
|
|
1827
1768
|
|
|
1828
1769
|
expect(result.functionName).toBe("getBalance")
|
|
1829
1770
|
expect(result.functionType).toBe("query")
|
|
@@ -1831,7 +1772,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1831
1772
|
expect(result.results[0].raw).toBe(BigInt(1000000))
|
|
1832
1773
|
expect(result.results[0].value).toBe("1000000")
|
|
1833
1774
|
expect(result.results[0].raw).toBe(BigInt(1000000))
|
|
1834
|
-
expect(result.results[0].
|
|
1775
|
+
expect(result.results[0].type).toBe("number")
|
|
1835
1776
|
})
|
|
1836
1777
|
|
|
1837
1778
|
it("should include both raw and display values for multiple returns", () => {
|
|
@@ -1847,14 +1788,14 @@ describe("ResultFieldVisitor", () => {
|
|
|
1847
1788
|
// Use BigInt with string to safe safe integer
|
|
1848
1789
|
const rawData = [BigInt("9007199254740993"), "active", true]
|
|
1849
1790
|
|
|
1850
|
-
const result = methodMeta.
|
|
1791
|
+
const result = methodMeta.resolve(rawData)
|
|
1851
1792
|
|
|
1852
1793
|
expect(result.results).toHaveLength(3)
|
|
1853
1794
|
|
|
1854
1795
|
// nat64 → string display, BigInt raw
|
|
1855
1796
|
expect(result.results[0].value).toBe("9007199254740993")
|
|
1856
1797
|
expect(result.results[0].raw).toBe(BigInt("9007199254740993"))
|
|
1857
|
-
expect(result.results[0].
|
|
1798
|
+
expect(result.results[0].candidType).toBe("nat64")
|
|
1858
1799
|
|
|
1859
1800
|
// text → same for both
|
|
1860
1801
|
expect(result.results[1].value).toBe("active")
|
|
@@ -1880,21 +1821,18 @@ describe("ResultFieldVisitor", () => {
|
|
|
1880
1821
|
const methodMeta = serviceMeta["getUser"]
|
|
1881
1822
|
|
|
1882
1823
|
const rawData = [{ name: "Alice", balance: BigInt(500) }]
|
|
1883
|
-
const result = methodMeta.
|
|
1824
|
+
const result = methodMeta.resolve(rawData[0])
|
|
1884
1825
|
|
|
1885
1826
|
expect(result.results[0].raw).toEqual({
|
|
1886
1827
|
name: "Alice",
|
|
1887
1828
|
balance: BigInt(500),
|
|
1888
1829
|
})
|
|
1889
1830
|
|
|
1890
|
-
const
|
|
1891
|
-
if (
|
|
1892
|
-
throw new Error("Expected record
|
|
1831
|
+
const recordNode = result.results[0] as RecordNode
|
|
1832
|
+
if (recordNode.type !== "record") {
|
|
1833
|
+
throw new Error("Expected record node")
|
|
1893
1834
|
}
|
|
1894
|
-
const val =
|
|
1895
|
-
string,
|
|
1896
|
-
{ field: ResultField; value: unknown }
|
|
1897
|
-
>
|
|
1835
|
+
const val = recordNode.fields as Record<string, ResolvedNode>
|
|
1898
1836
|
expect(val.name.value).toBe("Alice")
|
|
1899
1837
|
expect(val.balance.value).toBe("500")
|
|
1900
1838
|
})
|
|
@@ -1916,20 +1854,13 @@ describe("ResultFieldVisitor", () => {
|
|
|
1916
1854
|
// Test Ok case with raw BigInt
|
|
1917
1855
|
const rawData = [{ Ok: BigInt(12345) }]
|
|
1918
1856
|
|
|
1919
|
-
const result = methodMeta.
|
|
1857
|
+
const result = methodMeta.resolve(rawData[0])
|
|
1920
1858
|
|
|
1921
1859
|
expect(result.results[0].raw).toEqual({ Ok: BigInt(12345) })
|
|
1922
1860
|
|
|
1923
|
-
const variantValue = result.results[0]
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
variantValue === null ||
|
|
1927
|
-
!("option" in variantValue)
|
|
1928
|
-
) {
|
|
1929
|
-
throw new Error("Expected variant value object")
|
|
1930
|
-
}
|
|
1931
|
-
expect(variantValue.option).toBe("Ok")
|
|
1932
|
-
const innerVal = variantValue.value
|
|
1861
|
+
const variantValue = result.results[0] as ResolvedNode
|
|
1862
|
+
expect((variantValue as any).selected).toBe("Ok")
|
|
1863
|
+
const innerVal = (variantValue as any).selectedOption as ResolvedNode
|
|
1933
1864
|
expect(innerVal.value).toBe("12345")
|
|
1934
1865
|
})
|
|
1935
1866
|
|
|
@@ -1948,11 +1879,11 @@ describe("ResultFieldVisitor", () => {
|
|
|
1948
1879
|
const principal = Principal.fromText("aaaaa-aa")
|
|
1949
1880
|
const rawData = [principal]
|
|
1950
1881
|
|
|
1951
|
-
const result = methodMeta.
|
|
1882
|
+
const result = methodMeta.resolve(rawData[0])
|
|
1952
1883
|
|
|
1953
1884
|
expect(result.results[0].value).toBe("aaaaa-aa")
|
|
1954
1885
|
expect(result.results[0].raw).toBe(principal)
|
|
1955
|
-
expect(result.results[0].
|
|
1886
|
+
expect(result.results[0].type).toBe("principal")
|
|
1956
1887
|
})
|
|
1957
1888
|
|
|
1958
1889
|
it("should handle vector with raw and display values", () => {
|
|
@@ -1967,12 +1898,10 @@ describe("ResultFieldVisitor", () => {
|
|
|
1967
1898
|
|
|
1968
1899
|
const rawData = [[BigInt(100), BigInt(200), BigInt(300)]]
|
|
1969
1900
|
|
|
1970
|
-
const result = methodMeta.
|
|
1901
|
+
const result = methodMeta.resolve(rawData[0])
|
|
1971
1902
|
|
|
1972
|
-
const
|
|
1973
|
-
|
|
1974
|
-
throw new Error("Expected vector value array")
|
|
1975
|
-
}
|
|
1903
|
+
const vecNode = result.results[0] as ResolvedNode
|
|
1904
|
+
const vecValue = (vecNode as any).items as ResolvedNode[]
|
|
1976
1905
|
expect(vecValue).toHaveLength(3)
|
|
1977
1906
|
expect(vecValue[0].value).toBe("100")
|
|
1978
1907
|
expect(vecValue[1].value).toBe("200")
|
|
@@ -1992,7 +1921,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
1992
1921
|
// Test with value - Optional is [value]
|
|
1993
1922
|
const rawDataWithValue = [[BigInt(999)]]
|
|
1994
1923
|
|
|
1995
|
-
const resultWithValue = methodMeta.
|
|
1924
|
+
const resultWithValue = methodMeta.resolve(rawDataWithValue[0])
|
|
1996
1925
|
|
|
1997
1926
|
expect(resultWithValue.results[0].raw).toEqual([BigInt(999)])
|
|
1998
1927
|
const innerValue = resultWithValue.results[0].value
|
|
@@ -2008,7 +1937,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
2008
1937
|
// Test with null - Optional is []
|
|
2009
1938
|
const rawDataNull = [[]]
|
|
2010
1939
|
|
|
2011
|
-
const resultNull = methodMeta.
|
|
1940
|
+
const resultNull = methodMeta.resolve(rawDataNull[0])
|
|
2012
1941
|
expect(resultNull.results[0].raw).toEqual([])
|
|
2013
1942
|
expect(resultNull.results[0].value).toBe(null)
|
|
2014
1943
|
})
|
|
@@ -2023,7 +1952,7 @@ describe("ResultFieldVisitor", () => {
|
|
|
2023
1952
|
)
|
|
2024
1953
|
const methodMeta = serviceMeta["doNothing"]
|
|
2025
1954
|
|
|
2026
|
-
const result = methodMeta.
|
|
1955
|
+
const result = methodMeta.resolve([])
|
|
2027
1956
|
|
|
2028
1957
|
expect(result.results).toHaveLength(0)
|
|
2029
1958
|
})
|