Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 12x 204x 12x 12x 12x 1x 1000x 1000x 1x 1x 1x 22x 200000x 200000x 4400000x 4400000x 22x 1x 21x 1348x 1348x 1348x 1348x | /**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect } from 'chai';
import { stub } from 'sinon';
import '../testing/setup';
import { generateFid } from './generate-fid';
/** A few random values to generate a FID from. */
// prettier-ignore
const MOCK_RANDOM_VALUES = [
[14, 107, 44, 183, 190, 84, 253, 45, 219, 233, 43, 190, 240, 152, 195, 222, 237],
[184, 251, 91, 157, 125, 225, 209, 15, 116, 66, 46, 113, 194, 126, 16, 13, 226],
[197, 123, 13, 142, 239, 129, 252, 139, 156, 36, 219, 192, 153, 52, 182, 231, 177],
[69, 154, 197, 91, 156, 196, 125, 111, 3, 67, 212, 132, 169, 11, 14, 254, 125],
[193, 102, 58, 19, 244, 69, 36, 135, 170, 106, 98, 216, 246, 209, 24, 155, 149],
[252, 59, 222, 160, 82, 160, 82, 186, 14, 172, 196, 114, 146, 191, 196, 194, 146],
[64, 147, 153, 236, 225, 142, 235, 109, 184, 249, 174, 127, 33, 238, 227, 172, 111],
[129, 137, 136, 120, 248, 206, 253, 78, 159, 201, 216, 15, 246, 80, 118, 185, 211],
[117, 150, 2, 180, 116, 230, 45, 188, 183, 43, 152, 100, 50, 255, 101, 175, 190],
[156, 129, 30, 101, 58, 137, 217, 249, 12, 227, 235, 80, 248, 81, 191, 2, 5],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
];
/** The FIDs that should be generated based on MOCK_RANDOM_VALUES. */
const EXPECTED_FIDS = [
'fmsst75U_S3b6Su-8JjD3u',
'ePtbnX3h0Q90Qi5xwn4QDe',
'dXsNju-B_IucJNvAmTS257',
'dZrFW5zEfW8DQ9SEqQsO_n',
'cWY6E_RFJIeqamLY9tEYm5',
'fDveoFKgUroOrMRykr_Ewp',
'cJOZ7OGO6224-a5_Ie7jrG',
'cYmIePjO_U6fydgP9lB2ud',
'dZYCtHTmLby3K5hkMv9lr7',
'fIEeZTqJ2fkM4-tQ-FG_Ag',
'cAAAAAAAAAAAAAAAAAAAAA',
'f_____________________'
];
const VALID_FID = /^[cdef][A-Za-z0-9_-]{21}$/;
describe('generateFid', () => {
it('deterministically generates FIDs based on crypto.getRandomValues', () => {
let randomValueIndex = 0;
stub(crypto, 'getRandomValues').callsFake(array => {
if (!(array instanceof Uint8Array)) {
throw new Error('what');
}
const values = MOCK_RANDOM_VALUES[randomValueIndex++];
for (let i = 0; i < array.length; i++) {
array[i] = values[i];
}
return array;
});
for (const expectedFid of EXPECTED_FIDS) {
expect(generateFid()).to.deep.equal(expectedFid);
}
});
it('generates valid FIDs', () => {
for (let i = 0; i < 1000; i++) {
const fid = generateFid();
expect(VALID_FID.test(fid)).to.equal(true, `${fid} is not a valid FID`);
}
});
it('generates FIDs where each character is equally likely to appear in each location', () => {
const numTries = 200000;
const charOccurrencesMapList: Array<Map<string, number>> = new Array(22);
for (let i = 0; i < charOccurrencesMapList.length; i++) {
charOccurrencesMapList[i] = new Map();
}
for (let i = 0; i < numTries; i++) {
const fid = generateFid();
Array.from(fid).forEach((char, location) => {
const map = charOccurrencesMapList[location];
map.set(char, (map.get(char) || 0) + 1);
});
}
for (let i = 0; i < charOccurrencesMapList.length; i++) {
const map = charOccurrencesMapList[i];
if (i === 0) {
// In the first location only 4 characters (c, d, e, f) are valid.
expect(map.size).to.equal(4);
} else {
// In locations other than the first, all 64 characters are valid.
expect(map.size).to.equal(64);
}
Array.from(map.entries()).forEach(([_, occurrence]) => {
const expectedOccurrence = numTries / map.size;
// 10% margin of error
expect(occurrence).to.be.above(expectedOccurrence * 0.9);
expect(occurrence).to.be.below(expectedOccurrence * 1.1);
});
}
}).timeout(30000);
});
|