Skip to content

Commit

Permalink
Merge 1490003 into 5721c91
Browse files Browse the repository at this point in the history
  • Loading branch information
dubzzz committed Nov 29, 2020
2 parents 5721c91 + 1490003 commit 9c3d9d6
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/distribution/UniformArrayIntDistribution.ts
Expand Up @@ -11,7 +11,7 @@ import { uniformArrayIntDistributionInternal } from './internals/UniformArrayInt

/** @internal */
function uniformArrayIntInternal(from: ArrayInt, to: ArrayInt, rng: RandomGenerator): [ArrayInt, RandomGenerator] {
const rangeSize = addOneToPositiveArrayInt(substractArrayIntToNew(to, from));
const rangeSize = trimArrayIntInplace(addOneToPositiveArrayInt(substractArrayIntToNew(to, from)));
const emptyArrayIntData = rangeSize.data.slice(0);
const g = uniformArrayIntDistributionInternal(emptyArrayIntData, rangeSize.data, rng);
return [trimArrayIntInplace(addArrayIntToNew({ sign: 1, data: g[0] }, from)), g[1]];
Expand Down
Expand Up @@ -15,6 +15,7 @@ describe('uniformArrayIntDistribution [non regression]', () => {
${{ sign: 1, data: [0x00000000, 0x00000000] }} | ${{ sign: 1, data: [0xffffffff, 0xffffffff] }} | ${'64-bit unsigned'}
${{ sign: -1, data: [0x80000000, 0, 0, 0] }} | ${{ sign: 1, data: [0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff] }} | ${'128-bit signed'}
${{ sign: 1, data: [0x12345678, 0x90abcdef] }} | ${{ sign: 1, data: [0xfedcba09, 0x87654321] }} | ${'fuzzy'}
${{ sign: 1, data: [0, 0] }} | ${{ sign: 1, data: [0, 5] }} | ${'trailing zeros'}
`('Should not change its output in asked range except for major bumps ($topic)', ({ from, to }) => {
// Remark:
// ========================
Expand Down
88 changes: 77 additions & 11 deletions test/unit/distribution/UniformArrayIntDistribution.spec.ts
Expand Up @@ -21,26 +21,73 @@ describe('uniformArrayIntDistribution', () => {
// Skip next tests if BigInt is not supported
if (typeof BigInt === 'undefined') return it('no test', () => expect(true).toBe(true));

it('Should call uniformIntDistributionInternal with correct size of range and source rng', () =>
it('Should call uniformArrayIntDistributionInternal with correct range and source rng', () =>
fc.assert(
fc
.property(arrayIntArb(), arrayIntArb(), (a, b) => {
// Arrange
const { uniformArrayIntDistributionInternal } = mocked(UniformArrayIntDistributionInternalMock);
uniformArrayIntDistributionInternal.mockImplementation((out, _rangeSize, rng) => [out, rng]);
const [from, to] = arrayIntToBigInt(a) < arrayIntToBigInt(b) ? [a, b] : [b, a];
const rng = buildUniqueRng();
const { uniformArrayIntDistributionInternal, from, to } = mockInternals(a, b);
const expectedRangeSize = arrayIntToBigInt(to) - arrayIntToBigInt(from) + BigInt(1);
const expectedRng = buildUniqueRng();

// Act
uniformArrayIntDistribution(from, to, rng);
uniformArrayIntDistribution(from, to, expectedRng);

// Assert
expect(uniformArrayIntDistributionInternal).toHaveBeenCalledTimes(1);
expect(uniformArrayIntDistributionInternal).toHaveBeenCalledWith(expect.any(Array), expect.any(Array), rng);
const params = uniformArrayIntDistributionInternal.mock.calls[0];
const rangeSize = params[1];
const { rangeSize, rng } = extractParams(uniformArrayIntDistributionInternal);
expect(arrayIntToBigInt({ sign: 1, data: rangeSize })).toBe(expectedRangeSize);
expect(rng).toBe(expectedRng);
})
.beforeEach(clean)
));

it('Should call uniformArrayIntDistributionInternal with non-empty range', () =>
fc.assert(
fc
.property(arrayIntArb(), arrayIntArb(), (a, b) => {
// Arrange
const { uniformArrayIntDistributionInternal, from, to } = mockInternals(a, b);

// Act
uniformArrayIntDistribution(from, to, buildUniqueRng());

// Assert
const { rangeSize } = extractParams(uniformArrayIntDistributionInternal);
expect(rangeSize.length).toBeGreaterThanOrEqual(1);
})
.beforeEach(clean)
));

it('Should call uniformArrayIntDistributionInternal with trimmed range (no trailing zeros)', () =>
fc.assert(
fc
.property(arrayIntArb(), arrayIntArb(), (a, b) => {
// Arrange
const { uniformArrayIntDistributionInternal, from, to } = mockInternals(a, b);

// Act
uniformArrayIntDistribution(from, to, buildUniqueRng());

// Assert
const { rangeSize } = extractParams(uniformArrayIntDistributionInternal);
expect(rangeSize[0]).not.toBe(0); // rangeSize >= 1
})
.beforeEach(clean)
));

it('Should call uniformArrayIntDistributionInternal with out having same length as range', () =>
fc.assert(
fc
.property(arrayIntArb(), arrayIntArb(), (a, b) => {
// Arrange
const { uniformArrayIntDistributionInternal, from, to } = mockInternals(a, b);

// Act
uniformArrayIntDistribution(from, to, buildUniqueRng());

// Assert
const { out, rangeSize } = extractParams(uniformArrayIntDistributionInternal);
expect(out).toHaveLength(rangeSize.length);
})
.beforeEach(clean)
));
Expand All @@ -63,4 +110,23 @@ function arrayIntToBigInt(arrayInt: ArrayInt): bigint {
return current * BigInt(arrayInt.sign);
}

//const { uniformArrayIntDistributionInternal } = mocked(UniformArrayIntDistributionInternalMock)
function mockInternals(a: ArrayInt, b: ArrayInt) {
const { uniformArrayIntDistributionInternal } = mocked(UniformArrayIntDistributionInternalMock);
uniformArrayIntDistributionInternal.mockImplementation((out, _rangeSize, rng) => [out, rng]);
const [from, to] = arrayIntToBigInt(a) < arrayIntToBigInt(b) ? [a, b] : [b, a];
return { uniformArrayIntDistributionInternal, from, to };
}

function extractParams(
uniformArrayIntDistributionInternal: ReturnType<typeof mockInternals>['uniformArrayIntDistributionInternal']
) {
expect(uniformArrayIntDistributionInternal).toHaveBeenCalledTimes(1);
expect(uniformArrayIntDistributionInternal).toHaveBeenCalledWith(
expect.any(Array),
expect.any(Array),
expect.anything()
);
const params = uniformArrayIntDistributionInternal.mock.calls[0];
const [out, rangeSize, rng] = params;
return { out, rangeSize, rng };
}
Expand Up @@ -579,3 +579,68 @@ Array [
},
]
`;

exports[`uniformArrayIntDistribution [non regression] Should not change its output in asked range except for major bumps (trailing zeros) 1`] = `
Array [
Object {
"data": Array [
4,
],
"sign": 1,
},
Object {
"data": Array [
3,
],
"sign": 1,
},
Object {
"data": Array [
0,
],
"sign": 1,
},
Object {
"data": Array [
2,
],
"sign": 1,
},
Object {
"data": Array [
1,
],
"sign": 1,
},
Object {
"data": Array [
2,
],
"sign": 1,
},
Object {
"data": Array [
3,
],
"sign": 1,
},
Object {
"data": Array [
4,
],
"sign": 1,
},
Object {
"data": Array [
5,
],
"sign": 1,
},
Object {
"data": Array [
2,
],
"sign": 1,
},
]
`;

0 comments on commit 9c3d9d6

Please sign in to comment.