Skip to content

Commit

Permalink
Merge pull request #1420 from demergent-labs/property_tests_nan_error
Browse files Browse the repository at this point in the history
add test support for NaNs and infinities
  • Loading branch information
lastmjs authored Oct 23, 2023
2 parents 583f193 + 08d689f commit ab55f50
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 61 deletions.
60 changes: 30 additions & 30 deletions examples/primitive_types/src/index.did
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
service: () -> {
getBool: () -> (bool) query;
getEmpty: () -> (empty) query;
getFloat32: () -> (float32) query;
getFloat64: () -> (float64) query;
getInt: () -> (int) query;
getInt16: () -> (int16) query;
getInt32: () -> (int32) query;
getInt64: () -> (int64) query;
getInt8: () -> (int8) query;
getNat: () -> (nat) query;
getNat16: () -> (nat16) query;
getNat32: () -> (nat32) query;
getNat64: () -> (nat64) query;
getNat8: () -> (nat8) query;
getNull: () -> (null) query;
getNumber: () -> (float64) query;
getPrincipal: () -> (principal) query;
getReserved: () -> (reserved) query;
getString: () -> (text) query;
printString: (text) -> (text) query;
getText: () -> (text) query;
printText: (text) -> (text) query;
getNumber: () -> (float64) query;
printNumber: (float64) -> (float64) query;
getInt: () -> (int) query;
printBool: (bool) -> (bool) query;
printEmpty: (empty) -> (empty) query;
printFloat32: (float32) -> (float32) query;
printFloat64: (float64) -> (float64) query;
printInt: (int) -> (int) query;
getInt64: () -> (int64) query;
printInt64: (int64) -> (int64) query;
getInt32: () -> (int32) query;
printInt32: (int32) -> (int32) query;
getInt16: () -> (int16) query;
printInt16: (int16) -> (int16) query;
getInt8: () -> (int8) query;
printInt32: (int32) -> (int32) query;
printInt64: (int64) -> (int64) query;
printInt8: (int8) -> (int8) query;
getNat: () -> (nat) query;
printNat: (nat) -> (nat) query;
getNat64: () -> (nat64) query;
printNat64: (nat64) -> (nat64) query;
getNat32: () -> (nat32) query;
printNat32: (nat32) -> (nat32) query;
getNat16: () -> (nat16) query;
printNat16: (nat16) -> (nat16) query;
getNat8: () -> (nat8) query;
printNat32: (nat32) -> (nat32) query;
printNat64: (nat64) -> (nat64) query;
printNat8: (nat8) -> (nat8) query;
getFloat64: () -> (float64) query;
printFloat64: (float64) -> (float64) query;
getFloat32: () -> (float32) query;
printFloat32: (float32) -> (float32) query;
getBool: () -> (bool) query;
printBool: (bool) -> (bool) query;
getPrincipal: () -> (principal) query;
printPrincipal: (principal) -> (principal) query;
getNull: () -> (null) query;
printNull: (null) -> (null) query;
getReserved: () -> (reserved) query;
printNumber: (float64) -> (float64) query;
printPrincipal: (principal) -> (principal) query;
printReserved: (reserved) -> (reserved) query;
getEmpty: () -> (empty) query;
printEmpty: (empty) -> (empty) query;
printString: (text) -> (text) query;
printText: (text) -> (text) query;
}
130 changes: 101 additions & 29 deletions examples/primitive_types/test/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ export function getTests(
{
name: 'printString',
test: async () => {
const result = await primitiveTypesCanister.printString(
'string'
);
const result =
await primitiveTypesCanister.printString('string');

return {
Ok: result === 'string'
Expand Down Expand Up @@ -62,9 +61,8 @@ export function getTests(
{
name: 'printNumber',
test: async () => {
const result = await primitiveTypesCanister.printNumber(
90071992547409.05
);
const result =
await primitiveTypesCanister.printNumber(90071992547409.05);

return {
Ok: result.toString() === '90071992547409.05'
Expand All @@ -86,9 +84,10 @@ export function getTests(
{
name: 'printInt',
test: async () => {
const result = await primitiveTypesCanister.printInt(
170_141_183_460_469_231_731_687_303_715_884_105_727n
);
const result =
await primitiveTypesCanister.printInt(
170_141_183_460_469_231_731_687_303_715_884_105_727n
);

return {
Ok:
Expand All @@ -110,9 +109,10 @@ export function getTests(
{
name: 'printInt64',
test: async () => {
const result = await primitiveTypesCanister.printInt(
9_223_372_036_854_775_807n
);
const result =
await primitiveTypesCanister.printInt(
9_223_372_036_854_775_807n
);

return {
Ok: result === 9_223_372_036_854_775_807n
Expand All @@ -132,9 +132,8 @@ export function getTests(
{
name: 'printInt32',
test: async () => {
const result = await primitiveTypesCanister.printInt32(
2_147_483_647
);
const result =
await primitiveTypesCanister.printInt32(2_147_483_647);

return {
Ok: result === 2_147_483_647
Expand Down Expand Up @@ -196,9 +195,10 @@ export function getTests(
{
name: 'printNat',
test: async () => {
const result = await primitiveTypesCanister.printNat(
340_282_366_920_938_463_463_374_607_431_768_211_455n
);
const result =
await primitiveTypesCanister.printNat(
340_282_366_920_938_463_463_374_607_431_768_211_455n
);

return {
Ok:
Expand All @@ -220,9 +220,10 @@ export function getTests(
{
name: 'printNat64',
test: async () => {
const result = await primitiveTypesCanister.printNat64(
18_446_744_073_709_551_615n
);
const result =
await primitiveTypesCanister.printNat64(
18_446_744_073_709_551_615n
);

return {
Ok: result === 18_446_744_073_709_551_615n
Expand All @@ -242,9 +243,8 @@ export function getTests(
{
name: 'printNat32',
test: async () => {
const result = await primitiveTypesCanister.printNat32(
4_294_967_295
);
const result =
await primitiveTypesCanister.printNat32(4_294_967_295);

return {
Ok: result === 4_294_967_295
Expand Down Expand Up @@ -303,13 +303,50 @@ export function getTests(
},
{
name: 'printFloat64',
test: async () => {
const result =
await primitiveTypesCanister.printFloat64(
2.718281828459045
);

return {
Ok: result.toString() === '2.718281828459045'
};
}
},
{
name: 'print Float64.Nan',
test: async () => {
const result = await primitiveTypesCanister.printFloat64(
2.718281828459045
Number.NaN
);

return {
Ok: result.toString() === '2.718281828459045'
Ok: Number.isNaN(result)
};
}
},
{
name: 'print positive Float64.Infinity',
test: async () => {
const result = await primitiveTypesCanister.printFloat64(
Number.POSITIVE_INFINITY
);

return {
Ok: !Number.isFinite(result)
};
}
},
{
name: 'print negative Float64.Infinity',
test: async () => {
const result = await primitiveTypesCanister.printFloat64(
Number.NEGATIVE_INFINITY
);

return {
Ok: !Number.isFinite(result)
};
}
},
Expand All @@ -327,16 +364,51 @@ export function getTests(
{
name: 'printFloat32',
test: async () => {
const result = await primitiveTypesCanister.printFloat32(
3.1415927
);
const result =
await primitiveTypesCanister.printFloat32(3.1415927);

return {
// Ok: result.toString() === '3.1415927' // TODO on the command line this is returned
Ok: result.toString() === '3.1415927410125732'
};
}
},
{
name: 'print Float32.Nan',
test: async () => {
const result = await primitiveTypesCanister.printFloat32(
Number.NaN
);

return {
Ok: Number.isNaN(result)
};
}
},
{
name: 'print positive Float32.Infinity',
test: async () => {
const result = await primitiveTypesCanister.printFloat32(
Number.POSITIVE_INFINITY
);

return {
Ok: !Number.isFinite(result)
};
}
},
{
name: 'print negative Float32.Infinity',
test: async () => {
const result = await primitiveTypesCanister.printFloat32(
Number.NEGATIVE_INFINITY
);

return {
Ok: !Number.isFinite(result)
};
}
},
{
name: 'getBool',
test: async () => {
Expand Down
7 changes: 7 additions & 0 deletions property_tests/are_equal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function areFloatsEqual(paramName: string, paramValue: number) {
if (Number.isNaN(paramValue)) {
return `(Number.isNaN(${paramName}) && Number.isNaN(${paramValue}))`;
} else {
return `${paramName} === ${paramValue}`;
}
}
13 changes: 12 additions & 1 deletion property_tests/tests/float32/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createUniquePrimitiveArb } from '../../../arbitraries/unique_primitive_
import { JsFunctionNameArb } from '../../../arbitraries/js_function_name_arb';
import { runPropTests } from '../../..';
import { Float32Arb } from '../../../arbitraries/candid/primitive/floats/float32_arb';
import { areFloatsEqual } from '../../../are_equal';

const Float32TestArb = fc
.tuple(createUniquePrimitiveArb(JsFunctionNameArb), fc.array(Float32Arb))
Expand All @@ -25,7 +26,11 @@ const Float32TestArb = fc

const paramsCorrectlyOrdered = paramNames
.map((paramName, index) => {
return `if (${paramName} !== ${paramSamples[index]}) throw new Error('${paramName} is incorrectly ordered')`;
const areFloat32sEqual = areFloatsEqual(
paramName,
paramSamples[index]
);
return `if (!${areFloat32sEqual}) throw new Error('${paramName} is incorrectly ordered')`;
})
.join('\n');

Expand All @@ -50,6 +55,12 @@ const Float32TestArb = fc

const result = await actor[functionName](...float32s);

if (Number.isNaN(expectedResult)) {
return {
Ok: Number.isNaN(result)
};
}

return {
Ok: result === expectedResult
};
Expand Down
13 changes: 12 additions & 1 deletion property_tests/tests/float64/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createUniquePrimitiveArb } from '../../../arbitraries/unique_primitive_
import { JsFunctionNameArb } from '../../../arbitraries/js_function_name_arb';
import { runPropTests } from '../../..';
import { Float64ArrayArb } from '../../../arbitraries/candid/primitive/floats/float64_arb';
import { areFloatsEqual } from '../../../are_equal';

const Float64TestArb = fc
.tuple(createUniquePrimitiveArb(JsFunctionNameArb), Float64ArrayArb)
Expand Down Expand Up @@ -33,7 +34,11 @@ const Float64TestArb = fc

const paramsCorrectlyOrdered = paramNames
.map((paramName, index) => {
return `if (${paramName} !== ${paramSamples[index]}) throw new Error('${paramName} is incorrectly ordered')`;
const areFloat64sEqual = areFloatsEqual(
paramName,
paramSamples[index]
);
return `if (!${areFloat64sEqual}) throw new Error('${paramName} is incorrectly ordered')`;
})
.join('\n');

Expand All @@ -58,6 +63,12 @@ const Float64TestArb = fc

const result = await actor[functionName](...float64s);

if (Number.isNaN(expectedResult)) {
return {
Ok: Number.isNaN(result)
};
}

return {
Ok: result === expectedResult
};
Expand Down

0 comments on commit ab55f50

Please sign in to comment.