diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fe3b9c6ca7..4c464c8781 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -223,15 +223,15 @@ jobs: - if: ${{ needs.release-candidate-deploy.outputs.should_run_tests }} shell: bash -l {0} working-directory: ${{ matrix.example_directories }} - run: AZLE_NUM_PROPTEST_RUNS=10 npm test + run: AZLE_PROPTEST_NUM_RUNS=10 npm test - if: ${{ needs.release-candidate-deploy.outputs.should_run_tests && contains(github.head_ref, 'release--') }} shell: bash -l {0} working-directory: ${{ matrix.example_directories }} - run: AZLE_NUM_PROPTEST_RUNS=100 npm test + run: AZLE_PROPTEST_NUM_RUNS=100 npm test - if: ${{ needs.release-candidate-deploy.outputs.should_run_tests && (github.ref == 'refs/heads/main' && contains(github.event.head_commit.message, 'Merge pull request') && contains(github.event.head_commit.message, 'demergent-labs/release--')) }} shell: bash -l {0} working-directory: ${{ matrix.example_directories }} - run: AZLE_NUM_PROPTEST_RUNS=100 npm test + run: AZLE_PROPTEST_NUM_RUNS=100 npm test check-basic-integration-tests-success: needs: basic-integration-tests diff --git a/property_tests/arbitraries/candid/constructed/opt_arb.ts b/property_tests/arbitraries/candid/constructed/opt_arb.ts index f19c6171e0..6baa4c167e 100644 --- a/property_tests/arbitraries/candid/constructed/opt_arb.ts +++ b/property_tests/arbitraries/candid/constructed/opt_arb.ts @@ -1,69 +1,16 @@ import fc from 'fast-check'; -import { IntArb } from '../primitive/ints/int_arb'; -import { Int8Arb } from '../primitive/ints/int8_arb'; -import { Int16Arb } from '../primitive/ints/int16_arb'; -import { Int32Arb } from '../primitive/ints/int32_arb'; -import { Int64Arb } from '../primitive/ints/int64_arb'; -import { NatArb } from '../primitive/nats/nat_arb'; -import { Nat8Arb } from '../primitive/nats/nat8_arb'; -import { Nat16Arb } from '../primitive/nats/nat16_arb'; -import { Nat32Arb } from '../primitive/nats/nat32_arb'; -import { Nat64Arb } from '../primitive/nats/nat64_arb'; -import { Float32Arb } from '../primitive/floats/float32_arb'; -import { Float64Arb } from '../primitive/floats/float64_arb'; -import { TextArb } from '../primitive/text'; -import { NullArb } from '../primitive/null'; -import { BoolArb } from '../primitive/bool'; -import { Candid } from '../../candid'; -import { PrincipalArb } from '../reference/principal_arb'; -import { Principal } from '@dfinity/principal'; - -type InnerOpt = number | bigint | null | string | boolean | Opt | Principal; -type InnerOptArb = Candid<{ Some?: Candid; None?: null }>; +import { Candid, CandidType, CandidTypeArb } from '../../candid'; + +type InnerOptArb = ['Some' | 'None', Candid]; // This gives us a random Some or None, which means the default depth of all Opts is at least one -const InnerOptArb = (arb: fc.Arbitrary>) => { +const InnerOptArb = (arb: fc.Arbitrary>) => { return fc.constantFrom('Some', 'None').chain((keySample) => { return arb.map((innerValueSample): InnerOptArb => { if (keySample === 'Some') { - return { - value: { Some: innerValueSample }, - src: { - candidType: `Opt(${innerValueSample.src.candidType})`, - imports: new Set([ - ...innerValueSample.src.imports, - 'Opt' - ]), - valueLiteral: `{Some: ${innerValueSample.src.valueLiteral}}` - }, - equals: (a, b) => { - if (a.Some === undefined || b.Some === undefined) { - return false; - } - return innerValueSample.equals( - a.Some.value, - b.Some.value - ); - } - }; + return ['Some', innerValueSample]; } else { - return { - value: { None: null }, - src: { - candidType: `Opt(${innerValueSample.src.candidType})`, - imports: new Set([ - ...innerValueSample.src.imports, - 'Opt' - ]), - valueLiteral: '{None: null}' - }, - equals: (a, b) => { - if (a.None === undefined || b.None === undefined) { - return false; - } - return a.None === b.None; - } - }; + return ['None', innerValueSample]; } }); }); @@ -71,31 +18,14 @@ const InnerOptArb = (arb: fc.Arbitrary>) => { // TODO look into making this recursive // TODO we need to add all constructed and reference types -export const PrimitiveOptArb = fc.oneof( - InnerOptArb(Float32Arb), - InnerOptArb(Float64Arb), - InnerOptArb(IntArb), - InnerOptArb(Int8Arb), - InnerOptArb(Int16Arb), - InnerOptArb(Int32Arb), - InnerOptArb(Int64Arb), - InnerOptArb(NatArb), - InnerOptArb(Nat8Arb), - InnerOptArb(Nat16Arb), - InnerOptArb(Nat32Arb), - InnerOptArb(Nat64Arb), - InnerOptArb(BoolArb), - InnerOptArb(TextArb), - InnerOptArb(NullArb), - InnerOptArb(PrincipalArb) -); +export const PrimitiveOptArb = InnerOptArb(CandidTypeArb); type RecursiveOpt = { base: T; nextLayer: RecursiveOpt | null; }; -export type Opt = [InnerOpt] | never[]; +export type Opt = [CandidType | Opt] | never[]; export const OptArb = fc .letrec((tie) => ({ @@ -121,7 +51,7 @@ export const OptArb = fc function generateCandidType(recursiveOpt: RecursiveOpt): string { if (recursiveOpt.nextLayer === null) { // base case - return recursiveOpt.base.src.candidType; + return `Opt(${recursiveOpt.base[1].src.candidType})`; } else { return `Opt(${generateCandidType(recursiveOpt.nextLayer)})`; } @@ -130,7 +60,7 @@ function generateCandidType(recursiveOpt: RecursiveOpt): string { function generateImports(recursiveOpt: RecursiveOpt): Set { if (recursiveOpt.nextLayer === null) { // base case - return recursiveOpt.base.src.imports; + return new Set([...recursiveOpt.base[1].src.imports, 'Opt']); } else { return generateImports(recursiveOpt.nextLayer); } @@ -139,8 +69,8 @@ function generateImports(recursiveOpt: RecursiveOpt): Set { function generateValue(recursiveOpt: RecursiveOpt): Opt { if (recursiveOpt.nextLayer === null) { // base case - if (recursiveOpt.base.value.Some !== undefined) { - return [recursiveOpt.base.value.Some.value]; + if (recursiveOpt.base[0] === 'Some') { + return [recursiveOpt.base[1].value]; } else { return []; } @@ -152,7 +82,11 @@ function generateValue(recursiveOpt: RecursiveOpt): Opt { function generateValueLiteral(recursiveOpt: RecursiveOpt): string { if (recursiveOpt.nextLayer === null) { // base case - return recursiveOpt.base.src.valueLiteral; + if (recursiveOpt.base[0] === 'Some') { + return `{Some: ${recursiveOpt.base[1].src.valueLiteral}}`; + } else { + return `{None: null}`; + } } else { return `{ Some: ${generateValueLiteral(recursiveOpt.nextLayer)} @@ -188,8 +122,8 @@ function getBaseEquals( ): (a: any, b: any) => boolean { if (recursiveOpt.nextLayer === null) { // base case - if (recursiveOpt.base.value.Some !== undefined) { - return recursiveOpt.base.value.Some.equals; + if (recursiveOpt.base[0] === 'Some') { + return recursiveOpt.base[1].equals; } else { return (a: null, b: null) => a === b; } @@ -210,12 +144,13 @@ function areOptsEqual( return false; } - function isNone(value: any | []) { - return Array.isArray(value) && value.length === 0; - } if (isNone(value1) && isNone(value2)) { return true; } return equals(value1, value2); } + +function isNone(value: any | []) { + return Array.isArray(value) && value.length === 0; +} diff --git a/property_tests/arbitraries/candid/constructed/vec_arb.ts b/property_tests/arbitraries/candid/constructed/vec_arb.ts index 7412eba7b7..6f7a00cb80 100644 --- a/property_tests/arbitraries/candid/constructed/vec_arb.ts +++ b/property_tests/arbitraries/candid/constructed/vec_arb.ts @@ -17,6 +17,7 @@ import { Float64Arb } from '../primitive/floats/float64_arb'; import { NullArb } from '../primitive/null'; import { TextArb } from '../primitive/text'; import { deepEqual } from 'fast-equals'; +import { BlobArb } from './blob_arb'; const VecInnerArb = (arb: fc.Arbitrary>) => { return fc.tuple(fc.array(arb), arb).map(([sample, src]): Candid => { @@ -62,7 +63,8 @@ export const VecArb = fc.oneof( VecInnerArb(Nat64Arb), VecInnerArb(BoolArb), VecInnerArb(TextArb), - VecInnerArb(PrincipalArb) + VecInnerArb(PrincipalArb), + VecInnerArb(BlobArb) // VecInnerArb(NullArb) ); diff --git a/property_tests/index.ts b/property_tests/index.ts index 068762fda4..e7dcc11251 100644 --- a/property_tests/index.ts +++ b/property_tests/index.ts @@ -38,7 +38,7 @@ export function runPropTests(testArb: fc.Arbitrary) { ); }), { - numRuns: Number(process.env.AZLE_NUM_PROPTEST_RUNS ?? 1), + numRuns: Number(process.env.AZLE_PROPTEST_NUM_RUNS ?? 1), endOnFailure: true // TODO This essentially disables shrinking. We don't know how to do shrinking well yet } );