node-qrcode-lite/test/unit/core/version.test.js
2020-04-16 22:50:11 +01:00

183 lines
9.1 KiB
JavaScript

const test = require('tap').test
const Version = require('core/version')
const VersionCheck = require('core/version-check')
const ECLevel = require('core/error-correction-level')
const Mode = require('core/mode')
const NumericData = require('core/numeric-data')
const AlphanumericData = require('core/alphanumeric-data')
const KanjiData = require('core/kanji-data')
const ByteData = require('core/byte-data')
const EC_LEVELS = [ECLevel.L, ECLevel.M, ECLevel.Q, ECLevel.H]
const EXPECTED_NUMERIC_CAPACITY = [
[41, 34, 27, 17], [77, 63, 48, 34], [127, 101, 77, 58], [187, 149, 111, 82],
[255, 202, 144, 106], [322, 255, 178, 139], [370, 293, 207, 154], [461, 365, 259, 202],
[552, 432, 312, 235], [652, 513, 364, 288], [772, 604, 427, 331], [883, 691, 489, 374],
[1022, 796, 580, 427], [1101, 871, 621, 468], [1250, 991, 703, 530], [1408, 1082, 775, 602],
[1548, 1212, 876, 674], [1725, 1346, 948, 746], [1903, 1500, 1063, 813], [2061, 1600, 1159, 919],
[2232, 1708, 1224, 969], [2409, 1872, 1358, 1056], [2620, 2059, 1468, 1108], [2812, 2188, 1588, 1228],
[3057, 2395, 1718, 1286], [3283, 2544, 1804, 1425], [3517, 2701, 1933, 1501], [3669, 2857, 2085, 1581],
[3909, 3035, 2181, 1677], [4158, 3289, 2358, 1782], [4417, 3486, 2473, 1897], [4686, 3693, 2670, 2022],
[4965, 3909, 2805, 2157], [5253, 4134, 2949, 2301], [5529, 4343, 3081, 2361], [5836, 4588, 3244, 2524],
[6153, 4775, 3417, 2625], [6479, 5039, 3599, 2735], [6743, 5313, 3791, 2927], [7089, 5596, 3993, 3057]
]
const EXPECTED_ALPHANUMERIC_CAPACITY = [
[25, 20, 16, 10], [47, 38, 29, 20], [77, 61, 47, 35], [114, 90, 67, 50],
[154, 122, 87, 64], [195, 154, 108, 84], [224, 178, 125, 93], [279, 221, 157, 122],
[335, 262, 189, 143], [395, 311, 221, 174], [468, 366, 259, 200], [535, 419, 296, 227],
[619, 483, 352, 259], [667, 528, 376, 283], [758, 600, 426, 321], [854, 656, 470, 365],
[938, 734, 531, 408], [1046, 816, 574, 452], [1153, 909, 644, 493], [1249, 970, 702, 557],
[1352, 1035, 742, 587], [1460, 1134, 823, 640], [1588, 1248, 890, 672], [1704, 1326, 963, 744],
[1853, 1451, 1041, 779], [1990, 1542, 1094, 864], [2132, 1637, 1172, 910], [2223, 1732, 1263, 958],
[2369, 1839, 1322, 1016], [2520, 1994, 1429, 1080], [2677, 2113, 1499, 1150], [2840, 2238, 1618, 1226],
[3009, 2369, 1700, 1307], [3183, 2506, 1787, 1394], [3351, 2632, 1867, 1431], [3537, 2780, 1966, 1530],
[3729, 2894, 2071, 1591], [3927, 3054, 2181, 1658], [4087, 3220, 2298, 1774], [4296, 3391, 2420, 1852]
]
const EXPECTED_KANJI_CAPACITY = [
[10, 8, 7, 4], [20, 16, 12, 8], [32, 26, 20, 15], [48, 38, 28, 21],
[65, 52, 37, 27], [82, 65, 45, 36], [95, 75, 53, 39], [118, 93, 66, 52],
[141, 111, 80, 60], [167, 131, 93, 74], [198, 155, 109, 85], [226, 177, 125, 96],
[262, 204, 149, 109], [282, 223, 159, 120], [320, 254, 180, 136], [361, 277, 198, 154],
[397, 310, 224, 173], [442, 345, 243, 191], [488, 384, 272, 208], [528, 410, 297, 235],
[572, 438, 314, 248], [618, 480, 348, 270], [672, 528, 376, 284], [721, 561, 407, 315],
[784, 614, 440, 330], [842, 652, 462, 365], [902, 692, 496, 385], [940, 732, 534, 405],
[1002, 778, 559, 430], [1066, 843, 604, 457], [1132, 894, 634, 486], [1201, 947, 684, 518],
[1273, 1002, 719, 553], [1347, 1060, 756, 590], [1417, 1113, 790, 605], [1496, 1176, 832, 647],
[1577, 1224, 876, 673], [1661, 1292, 923, 701], [1729, 1362, 972, 750], [1817, 1435, 1024, 784]
]
const EXPECTED_BYTE_CAPACITY = [
[17, 14, 11, 7], [32, 26, 20, 14], [53, 42, 32, 24], [78, 62, 46, 34],
[106, 84, 60, 44], [134, 106, 74, 58], [154, 122, 86, 64], [192, 152, 108, 84],
[230, 180, 130, 98], [271, 213, 151, 119], [321, 251, 177, 137], [367, 287, 203, 155],
[425, 331, 241, 177], [458, 362, 258, 194], [520, 412, 292, 220], [586, 450, 322, 250],
[644, 504, 364, 280], [718, 560, 394, 310], [792, 624, 442, 338], [858, 666, 482, 382],
[929, 711, 509, 403], [1003, 779, 565, 439], [1091, 857, 611, 461], [1171, 911, 661, 511],
[1273, 997, 715, 535], [1367, 1059, 751, 593], [1465, 1125, 805, 625], [1528, 1190, 868, 658],
[1628, 1264, 908, 698], [1732, 1370, 982, 742], [1840, 1452, 1030, 790], [1952, 1538, 1112, 842],
[2068, 1628, 1168, 898], [2188, 1722, 1228, 958], [2303, 1809, 1283, 983], [2431, 1911, 1351, 1051],
[2563, 1989, 1423, 1093], [2699, 2099, 1499, 1139], [2809, 2213, 1579, 1219], [2953, 2331, 1663, 1273]
]
const EXPECTED_VERSION_BITS = [
0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D,
0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683, 0x168C9,
0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75,
0x1F250, 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B, 0x2542E, 0x26A64,
0x27541, 0x28C69
]
test('Version validity', function (t) {
t.notOk(VersionCheck.isValid(), 'Should return false if no input')
t.notOk(VersionCheck.isValid(''), 'Should return false if version is not a number')
t.notOk(VersionCheck.isValid(0), 'Should return false if version is not in range')
t.notOk(VersionCheck.isValid(41), 'Should return false if version is not in range')
t.end()
})
test('Version from value', function (t) {
t.equal(Version.from(5), 5, 'Should return correct version from a number')
t.equal(Version.from('5'), 5, 'Should return correct version from a string')
t.equal(Version.from(0, 1), 1, 'Should return default value if version is invalid')
t.equal(Version.from(null, 1), 1, 'Should return default value if version is undefined')
t.end()
})
test('Version capacity', function (t) {
t.throws(function () { Version.getCapacity() }, 'Should throw if version is undefined')
t.throws(function () { Version.getCapacity('') }, 'Should throw if version is not a number')
t.throws(function () { Version.getCapacity(0) }, 'Should throw if version is not in range')
t.throws(function () { Version.getCapacity(41) }, 'Should throw if version is not in range')
for (let l = 0; l < EC_LEVELS.length; l++) {
for (let i = 1; i <= 40; i++) {
t.equal(Version.getCapacity(i, EC_LEVELS[l], Mode.NUMERIC),
EXPECTED_NUMERIC_CAPACITY[i - 1][l], 'Should return correct numeric mode capacity')
t.equal(Version.getCapacity(i, EC_LEVELS[l], Mode.ALPHANUMERIC),
EXPECTED_ALPHANUMERIC_CAPACITY[i - 1][l], 'Should return correct alphanumeric mode capacity')
t.equal(Version.getCapacity(i, EC_LEVELS[l], Mode.KANJI),
EXPECTED_KANJI_CAPACITY[i - 1][l], 'Should return correct kanji mode capacity')
t.equal(Version.getCapacity(i, EC_LEVELS[l], Mode.BYTE),
EXPECTED_BYTE_CAPACITY[i - 1][l], 'Should return correct byte mode capacity')
t.equal(Version.getCapacity(i, EC_LEVELS[l]),
EXPECTED_BYTE_CAPACITY[i - 1][l], 'Should return correct byte mode capacity')
}
}
t.end()
})
test('Version best match', function (t) {
function testBestVersionForCapacity (expectedCapacity, DataCtor) {
for (let v = 0; v < 40; v++) {
for (let l = 0; l < EC_LEVELS.length; l++) {
const capacity = expectedCapacity[v][l]
const data = new DataCtor(new Array(capacity + 1).join('-'))
t.equal(Version.getBestVersionForData(data, EC_LEVELS[l]), v + 1, 'Should return best version')
t.equal(Version.getBestVersionForData([data], EC_LEVELS[l]), v + 1, 'Should return best version')
if (l === 1) {
t.equal(Version.getBestVersionForData(data, null), v + 1,
'Should return best version for ECLevel.M if error level is undefined')
t.equal(Version.getBestVersionForData([data], null), v + 1,
'Should return best version for ECLevel.M if error level is undefined')
}
}
}
for (let i = 0; i < EC_LEVELS.length; i++) {
const exceededCapacity = expectedCapacity[39][i] + 1
const tooBigData = new DataCtor(new Array(exceededCapacity + 1).join('-'))
const tooBigDataArray = [
new DataCtor(new Array(Math.floor(exceededCapacity / 2)).join('-')),
new DataCtor(new Array(Math.floor(exceededCapacity / 2) + 1).join('-'))
]
t.notOk(Version.getBestVersionForData(tooBigData, EC_LEVELS[i]),
'Should return undefined if data is too big')
t.notOk(Version.getBestVersionForData([tooBigData], EC_LEVELS[i]),
'Should return undefined if data is too big')
t.notOk(Version.getBestVersionForData(tooBigDataArray, EC_LEVELS[i]),
'Should return undefined if data is too big')
}
}
testBestVersionForCapacity(EXPECTED_NUMERIC_CAPACITY, NumericData)
testBestVersionForCapacity(EXPECTED_ALPHANUMERIC_CAPACITY, AlphanumericData)
testBestVersionForCapacity(EXPECTED_KANJI_CAPACITY, KanjiData)
testBestVersionForCapacity(EXPECTED_BYTE_CAPACITY, ByteData)
t.ok(Version.getBestVersionForData([new ByteData('abc'), new NumericData('1234')]),
'Should return a version number if input array is valid')
t.equal(Version.getBestVersionForData([]), 1,
'Should return 1 if array is empty')
t.end()
})
test('Version encoded info', function (t) {
let v
for (v = 0; v < 7; v++) {
t.throws(function () { Version.getEncodedBits(v) },
'Should throw if version is invalid or less than 7')
}
for (v = 7; v <= 40; v++) {
const bch = Version.getEncodedBits(v)
t.equal(bch, EXPECTED_VERSION_BITS[v - 7], 'Should return correct bits')
}
t.end()
})