Skip to content

Commit

Permalink
Merge pull request #1336 from demergent-labs/recursion_clean_up
Browse files Browse the repository at this point in the history
Recursion clean up
  • Loading branch information
lastmjs authored Oct 4, 2023
2 parents 4931af3 + 43fad0d commit 421c446
Show file tree
Hide file tree
Showing 12 changed files with 383 additions and 268 deletions.
126 changes: 75 additions & 51 deletions examples/recursion/src/recursion/index.did
Original file line number Diff line number Diff line change
@@ -1,53 +1,77 @@
type rec_21 = func (rec_21) -> (rec_21) query;
type rec_22 = func (rec_22) -> (rec_22) query;
type rec_23 = func (rec_23) -> (rec_23) query;
type rec_0 = record {myOpt:opt rec_0};
type rec_1 = record {myOpt:opt rec_1};
type rec_12 = record {myOpt:opt rec_12};
type rec_4 = record {myVar:variant {num:int8; varRec:rec_4}};
type rec_5 = record {myVar:variant {num:int8; varRec:rec_5}};
type rec_14 = record {myVar:variant {num:int8; varRec:rec_14}};
type rec_2 = record {myVecRecords:vec rec_2};
type rec_3 = record {myVecRecords:vec rec_3};
type rec_13 = record {myVecRecords:vec rec_13};
type rec_26 = service {getMessage: () -> (text) query; myQuery: (rec_26) -> (rec_26) query;};
type rec_27 = service {getMessage: () -> (text) query; myQuery: (rec_27) -> (rec_27) query;};
type rec_29 = service {getMessage: () -> (text) query; myQuery: (rec_29) -> (rec_29) query;};
type rec_30 = service {getMessage: () -> (text) query; myQuery: (rec_30) -> (rec_30) query;};
type rec_28 = service {getMessage: () -> (text) query; myQuery: (rec_28) -> (rec_28) query;};
type rec_24 = service {myQuery: (rec_24) -> (rec_24) query;};
type rec_25 = service {myQuery: (rec_25) -> (rec_25) query;};
type rec_8 = record {opt rec_8; opt rec_8};
type rec_9 = record {opt rec_9; opt rec_9};
type rec_16 = record {opt rec_16; opt rec_16};
type rec_18 = record {variant {num:int8; varTuple:rec_18}; variant {num:int8; varTuple:rec_18}};
type rec_19 = record {variant {num:int8; varTuple:rec_19}; variant {num:int8; varTuple:rec_19}};
type rec_20 = record {variant {num:int8; varTuple:rec_20}; variant {num:int8; varTuple:rec_20}};
type rec_10 = record {vec rec_10; vec rec_10};
type rec_11 = record {vec rec_11; vec rec_11};
type rec_17 = record {vec rec_17; vec rec_17};
type rec_6 = variant {num:int8; recVariant:rec_6};
type rec_7 = variant {num:int8; recVariant:rec_7};
type rec_15 = variant {num:int8; recVariant:rec_15};
type rec_37 = func (rec_37) -> (rec_37) query;
type rec_38 = func (rec_38) -> (rec_38) query;
type rec_39 = func (rec_39) -> (rec_39) query;
type rec_10 = opt rec_10;
type rec_11 = opt rec_11;
type rec_12 = opt record {rec_12; rec_12};
type rec_13 = opt record {rec_13; rec_13};
type rec_8 = opt variant {Leaf:int8; Branch:rec_8};
type rec_9 = opt variant {Leaf:int8; Branch:rec_9};
type rec_14 = opt vec rec_14;
type rec_15 = opt vec rec_15;
type rec_16 = record {myOpt:opt rec_16};
type rec_17 = record {myOpt:opt rec_17};
type rec_28 = record {myOpt:opt rec_28};
type rec_20 = record {myVar:variant {num:int8; varRec:rec_20}};
type rec_21 = record {myVar:variant {num:int8; varRec:rec_21}};
type rec_30 = record {myVar:variant {num:int8; varRec:rec_30}};
type rec_18 = record {myVecRecords:vec rec_18};
type rec_19 = record {myVecRecords:vec rec_19};
type rec_29 = record {myVecRecords:vec rec_29};
type rec_42 = service {getMessage: () -> (text) query; myQuery: (rec_42) -> (rec_42) query;};
type rec_43 = service {getMessage: () -> (text) query; myQuery: (rec_43) -> (rec_43) query;};
type rec_45 = service {getMessage: () -> (text) query; myQuery: (rec_45) -> (rec_45) query;};
type rec_46 = service {getMessage: () -> (text) query; myQuery: (rec_46) -> (rec_46) query;};
type rec_44 = service {getMessage: () -> (text) query; myQuery: (rec_44) -> (rec_44) query;};
type rec_40 = service {myQuery: (rec_40) -> (rec_40) query;};
type rec_41 = service {myQuery: (rec_41) -> (rec_41) query;};
type rec_24 = record {opt rec_24; opt rec_24};
type rec_25 = record {opt rec_25; opt rec_25};
type rec_32 = record {opt rec_32; opt rec_32};
type rec_34 = record {variant {num:int8; varTuple:rec_34}; variant {num:int8; varTuple:rec_34}};
type rec_35 = record {variant {num:int8; varTuple:rec_35}; variant {num:int8; varTuple:rec_35}};
type rec_36 = record {variant {num:int8; varTuple:rec_36}; variant {num:int8; varTuple:rec_36}};
type rec_26 = record {vec rec_26; vec rec_26};
type rec_27 = record {vec rec_27; vec rec_27};
type rec_33 = record {vec rec_33; vec rec_33};
type rec_22 = variant {num:int8; recVariant:rec_22};
type rec_23 = variant {num:int8; recVariant:rec_23};
type rec_31 = variant {num:int8; recVariant:rec_31};
type rec_2 = vec opt rec_2;
type rec_3 = vec opt rec_3;
type rec_4 = vec record {rec_4; rec_4};
type rec_5 = vec record {rec_5; rec_5};
type rec_0 = vec variant {Leaf:int8; Branch:rec_0};
type rec_1 = vec variant {Leaf:int8; Branch:rec_1};
type rec_6 = vec rec_6;
type rec_7 = vec rec_7;
service: () -> {
testRecFunc: (rec_21) -> (rec_22) query;
testRecFuncReturn: () -> (rec_23) query;
testRecRecordWithOpt: (rec_0) -> (rec_1) query;
testRecRecordWithOptReturn: () -> (rec_12) query;
testRecRecordWithVariant: (rec_4) -> (rec_5) query;
testRecRecordWithVariantReturn: () -> (rec_14) query;
testRecRecordWithVec: (rec_2) -> (rec_3) query;
testRecRecordWithVecReturn: () -> (rec_13) query;
testRecService: (rec_26) -> (rec_27) query;
testRecServiceCall: (rec_29) -> (rec_30);
testRecServiceReturn: () -> (rec_28) query;
testRecServiceSimple: (rec_24) -> (rec_25) query;
testRecTupleWithOpt: (rec_8) -> (rec_9) query;
testRecTupleWithOptReturn: () -> (rec_16) query;
testRecTupleWithVariant: (rec_18) -> (rec_19) query;
testRecTupleWithVariantReturn: () -> (rec_20) query;
testRecTupleWithVec: (rec_10) -> (rec_11) query;
testRecTupleWithVecReturn: () -> (rec_17) query;
testRecVariant: (rec_6) -> (rec_7) query;
testRecVariantReturn: () -> (rec_15) query;
testRecFunc: (rec_37) -> (rec_38) query;
testRecFuncReturn: () -> (rec_39) query;
testRecOptWithOpt: (rec_10) -> (rec_11) query;
testRecOptWithTuple: (rec_12) -> (rec_13) query;
testRecOptWithVariant: (rec_8) -> (rec_9) query;
testRecOptWithVec: (rec_14) -> (rec_15) query;
testRecRecordWithOpt: (rec_16) -> (rec_17) query;
testRecRecordWithOptReturn: () -> (rec_28) query;
testRecRecordWithVariant: (rec_20) -> (rec_21) query;
testRecRecordWithVariantReturn: () -> (rec_30) query;
testRecRecordWithVec: (rec_18) -> (rec_19) query;
testRecRecordWithVecReturn: () -> (rec_29) query;
testRecService: (rec_42) -> (rec_43) query;
testRecServiceCall: (rec_45) -> (rec_46);
testRecServiceReturn: () -> (rec_44) query;
testRecServiceSimple: (rec_40) -> (rec_41) query;
testRecTupleWithOpt: (rec_24) -> (rec_25) query;
testRecTupleWithOptReturn: () -> (rec_32) query;
testRecTupleWithVariant: (rec_34) -> (rec_35) query;
testRecTupleWithVariantReturn: () -> (rec_36) query;
testRecTupleWithVec: (rec_26) -> (rec_27) query;
testRecTupleWithVecReturn: () -> (rec_33) query;
testRecVariant: (rec_22) -> (rec_23) query;
testRecVariantReturn: () -> (rec_31) query;
testRecVecWithOpt: (rec_2) -> (rec_3) query;
testRecVecWithTuple: (rec_4) -> (rec_5) query;
testRecVecWithVariant: (rec_0) -> (rec_1) query;
testRecVecWithVec: (rec_6) -> (rec_7) query;
}
22 changes: 19 additions & 3 deletions examples/recursion/src/recursion/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import MyFullCanister from '../recursive_canister';
// These are the types that can be recursive
// Record
// Record can't be recursive by itself. It needs something to be able to terminate it. It needs to work with Variants, Opts, and Vec
const varRecord = Recursive(() => Record({ myVar }));
const varRecord = Recursive(() =>
Record({ myVar: Variant({ num: int8, varRec: varRecord }) })
);
const vecRecord = Recursive(() => Record({ myVecRecords: Vec(vecRecord) }));
const optRecord = Recursive(() => Record({ myOpt: Opt(optRecord) }));
const myVar = Variant({ num: int8, varRec: varRecord });
// Variant
// Variant is the only type that can be recursive all by itself but it does need a way to end the recursion
const recVariant = Recursive(() =>
Expand All @@ -35,8 +36,15 @@ const vecTuple = Recursive(() => Tuple(Vec(vecTuple), Vec(vecTuple)));
const varTuple = Recursive(() => Tuple(myTupleVar, myTupleVar));
const myTupleVar = Variant({ num: int8, varTuple });
// Vec
// Vec can't be recursive by itself. At the end of it all it needs to have a concrete type.
const varVec = Recursive(() => Vec(Variant({ Leaf: int8, Branch: varVec })));
const optVec = Recursive(() => Vec(Opt(optVec)));
const tupleVec = Recursive(() => Vec(Tuple(tupleVec, tupleVec)));
const vecVec = Recursive(() => Vec(vecVec));
// Opt
const varOpt = Recursive(() => Opt(Variant({ Leaf: int8, Branch: varOpt })));
const optOpt = Recursive(() => Opt(optOpt));
const tupleOpt = Recursive(() => Opt(Tuple(tupleOpt, tupleOpt)));
const vecOpt = Recursive(() => Opt(Vec(vecOpt)));
// Service
const MyCanister = Recursive(() =>
Canister({
Expand All @@ -47,6 +55,14 @@ const MyCanister = Recursive(() =>
const myFunc = Recursive(() => Func([myFunc], myFunc, 'query'));

export default Canister({
testRecVecWithVariant: query([varVec], varVec, (param) => param),
testRecVecWithOpt: query([optVec], optVec, (param) => param),
testRecVecWithTuple: query([tupleVec], tupleVec, (param) => param),
testRecVecWithVec: query([vecVec], vecVec, (param) => param),
testRecOptWithVariant: query([varOpt], varOpt, (param) => param),
testRecOptWithOpt: query([optOpt], optOpt, (param) => param),
testRecOptWithTuple: query([tupleOpt], tupleOpt, (param) => param),
testRecOptWithVec: query([vecOpt], vecOpt, (param) => param),
testRecRecordWithOpt: query([optRecord], optRecord, (param) => param),
testRecRecordWithVec: query([vecRecord], vecRecord, (param) => param),
testRecRecordWithVariant: query([varRecord], varRecord, (param) => param),
Expand Down
133 changes: 129 additions & 4 deletions examples/recursion/test/tests.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { Test, getCanisterId } from 'azle/test';
import {
_SERVICE,
rec_313,
rec_321
rec_0,
rec_10,
rec_12,
rec_14,
rec_2,
rec_24,
rec_26,
rec_4,
rec_6,
rec_8
} from './dfx_generated/recursion/recursion.did';
import { _SERVICE as _REC_SERVICE } from './dfx_generated/recursive_canister/recursive_canister.did';
import { ActorSubclass } from '@dfinity/agent';
Expand Down Expand Up @@ -199,7 +207,7 @@ export function getTests(recursion_canister: ActorSubclass<_SERVICE>): Test[] {
{
name: 'recursive tuples with vec',
test: async () => {
const input: rec_321 = [[[[], [[[], []]]]], []];
const input: rec_26 = [[[[], [[[], []]]]], []];
const result =
await recursion_canister.testRecTupleWithVec(input);

Expand Down Expand Up @@ -231,7 +239,7 @@ export function getTests(recursion_canister: ActorSubclass<_SERVICE>): Test[] {
{
name: 'recursive tuples with opt',
test: async () => {
const input: rec_313 = [[[[], [[[], []]]]], []];
const input: rec_24 = [[[[], [[[], []]]]], []];
const result =
await recursion_canister.testRecTupleWithOpt(input);

Expand Down Expand Up @@ -390,6 +398,123 @@ export function getTests(recursion_canister: ActorSubclass<_SERVICE>): Test[] {
Ok: result === `(service "${principalId}")`
};
}
},
{
name: 'recursive vec with variant',
test: async () => {
const input: rec_0 = [
{ Leaf: 1 },
{ Branch: [{ Leaf: 2 }] },
{ Leaf: 3 },
{
Branch: [
{
Branch: [
{ Branch: [{ Leaf: 4 }, { Leaf: 5 }] },
{ Leaf: 6 }
]
}
]
}
];
const result =
await recursion_canister.testRecVecWithVariant(input);

return {
Ok: deepCompare(result, input)
};
}
},
{
name: 'recursive vec with tuple',
test: async () => {
const input: rec_4 = [
[[], []],
[[[[], []]], []],
[[], [[[], []]]],
[[[[], []]], [[[], []]]]
];
const result =
await recursion_canister.testRecVecWithTuple(input);

return {
Ok: deepCompare(result, input)
};
}
},
{
name: 'recursive vec with opt',
test: async () => {
const input: rec_2 = [[[[], [[[], []]]]], []];
const result =
await recursion_canister.testRecVecWithOpt(input);

return {
Ok: deepCompare(result, input)
};
}
},
{
name: 'recursive vec with vec',
test: async () => {
const input: rec_6 = [[[[], [[[], []]]]], []];
const result =
await recursion_canister.testRecVecWithVec(input);

return {
Ok: deepCompare(result, input)
};
}
},
{
name: 'recursive opt with vec',
test: async () => {
const input: rec_14 = [[[], [], [], []]];
const result =
await recursion_canister.testRecOptWithVec(input);

return {
Ok: deepCompare(result, input)
};
}
},
{
name: 'recursive opt with tuple',
test: async () => {
const input: rec_12 = [[[], []]];
const result =
await recursion_canister.testRecOptWithTuple(input);

return {
Ok: deepCompare(result, input)
};
}
},
{
name: 'recursive opt with variant',
test: async () => {
const input: rec_8 = [{ Branch: [] }];
const result =
await recursion_canister.testRecOptWithVariant(input);

return {
Ok: deepCompare(result, input)
};
}
},
{
name: 'recursive opt with opt',
test: async () => {
const input: rec_10 = [
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
];
const result =
await recursion_canister.testRecOptWithOpt(input);

return {
Ok: deepCompare(result, input)
};
}
}
];
}
Expand Down
Loading

0 comments on commit 421c446

Please sign in to comment.