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

291 lines
7.9 KiB
JavaScript
Executable file

const test = require('tap').test
const BitMatrix = require('core/bit-matrix')
const MaskPattern = require('core/mask-pattern')
test('Mask pattern - Pattern references', function (t) {
const patternsCount = Object.keys(MaskPattern.Patterns).length
t.equals(patternsCount, 8, 'Should return 8 patterns')
t.end()
})
const expectedPattern000 = [
1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1
]
const expectedPattern001 = [
1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0
]
const expectedPattern010 = [
1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0,
1, 0, 0, 1, 0, 0
]
const expectedPattern011 = [
1, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 1,
0, 1, 0, 0, 1, 0,
1, 0, 0, 1, 0, 0,
0, 0, 1, 0, 0, 1,
0, 1, 0, 0, 1, 0
]
const expectedPattern100 = [
1, 1, 1, 0, 0, 0,
1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 1,
0, 0, 0, 1, 1, 1,
1, 1, 1, 0, 0, 0,
1, 1, 1, 0, 0, 0
]
const expectedPattern101 = [
1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 0,
1, 0, 0, 1, 0, 0,
1, 0, 1, 0, 1, 0,
1, 0, 0, 1, 0, 0,
1, 0, 0, 0, 0, 0
]
const expectedPattern110 = [
1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0,
1, 1, 0, 1, 1, 0,
1, 0, 1, 0, 1, 0,
1, 0, 1, 1, 0, 1,
1, 0, 0, 0, 1, 1
]
const expectedPattern111 = [
1, 0, 1, 0, 1, 0,
0, 0, 0, 1, 1, 1,
1, 0, 0, 0, 1, 1,
0, 1, 0, 1, 0, 1,
1, 1, 1, 0, 0, 0,
0, 1, 1, 1, 0, 0
]
test('MaskPattern validity', function (t) {
t.notOk(MaskPattern.isValid(), 'Should return false if no input')
t.notOk(MaskPattern.isValid(''), 'Should return false if value is not a number')
t.notOk(MaskPattern.isValid(-1), 'Should return false if value is not in range')
t.notOk(MaskPattern.isValid(8), 'Should return false if value is not in range')
t.end()
})
test('MaskPattern from value', function (t) {
t.equal(MaskPattern.from(5), 5, 'Should return correct mask pattern from a number')
t.equal(MaskPattern.from('5'), 5, 'Should return correct mask pattern from a string')
t.equal(MaskPattern.from(-1), undefined, 'Should return undefined if value is invalid')
t.equal(MaskPattern.from(null), undefined, 'Should return undefined if value is null')
t.end()
})
test('Mask pattern - Apply mask', function (t) {
const patterns = Object.keys(MaskPattern.Patterns).length
const expectedPatterns = [
expectedPattern000, expectedPattern001, expectedPattern010, expectedPattern011,
expectedPattern100, expectedPattern101, expectedPattern110, expectedPattern111
]
for (let p = 0; p < patterns; p++) {
const matrix = new BitMatrix(6)
MaskPattern.applyMask(p, matrix)
t.deepEqual(matrix.data, new Uint8Array(expectedPatterns[p]), 'Should return correct pattern')
}
const matrix = new BitMatrix(2)
matrix.set(0, 0, false, true)
matrix.set(0, 1, false, true)
matrix.set(1, 0, false, true)
matrix.set(1, 1, false, true)
MaskPattern.applyMask(0, matrix)
t.deepEqual(matrix.data, new Uint8Array([false, false, false, false]), 'Should leave reserved bit unchanged')
t.throws(function () { MaskPattern.applyMask(-1, new BitMatrix(1)) }, 'Should throw if pattern is invalid')
t.end()
})
test('Mask pattern - Penalty N1', function (t) {
let matrix = new BitMatrix(11)
matrix.data = [
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1
]
t.equals(MaskPattern.getPenaltyN1(matrix), 59,
'Should return correct penalty points')
matrix = new BitMatrix(6)
matrix.data = expectedPattern000
t.equals(MaskPattern.getPenaltyN1(matrix), 0,
'Should return correct penalty points')
matrix.data = expectedPattern001
t.equals(MaskPattern.getPenaltyN1(matrix), 24,
'Should return correct penalty points')
matrix.data = expectedPattern010
t.equals(MaskPattern.getPenaltyN1(matrix), 24,
'Should return correct penalty points')
matrix.data = expectedPattern101
t.equals(MaskPattern.getPenaltyN1(matrix), 20,
'Should return correct penalty points')
t.end()
})
test('Mask pattern - Penalty N2', function (t) {
let matrix = new BitMatrix(8)
matrix.data = [
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 1, 1,
0, 1, 1, 1, 0, 0, 1, 1,
1, 0, 0, 0, 1, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 1, 0, 0, 0, 0,
1, 1, 1, 1, 1, 0, 0, 0,
1, 1, 0, 0, 1, 0, 1, 1
]
t.equals(MaskPattern.getPenaltyN2(matrix), 45,
'Should return correct penalty points')
matrix = new BitMatrix(6)
matrix.data = expectedPattern000
t.equals(MaskPattern.getPenaltyN2(matrix), 0,
'Should return correct penalty points')
matrix.data = expectedPattern010
t.equals(MaskPattern.getPenaltyN2(matrix), 30,
'Should return correct penalty points')
matrix.data = expectedPattern100
t.equals(MaskPattern.getPenaltyN2(matrix), 36,
'Should return correct penalty points')
t.end()
})
test('Mask pattern - Penalty N3', function (t) {
const matrix = new BitMatrix(11)
matrix.data = [
0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1,
0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1,
0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1,
0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0
]
t.equals(MaskPattern.getPenaltyN3(matrix), 160,
'Should return correct penalty points')
matrix.data = [
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1,
1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1,
0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,
1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1
]
t.equals(MaskPattern.getPenaltyN3(matrix), 280,
'Should return correct penalty points')
t.end()
})
test('Mask pattern - Penalty N4', function (t) {
const matrix = new BitMatrix(10)
matrix.data = new Array(50).fill(1).concat(new Array(50).fill(0))
t.equals(MaskPattern.getPenaltyN4(matrix), 0,
'Should return correct penalty points')
const matrix2 = new BitMatrix(21)
matrix2.data = new Array(190).fill(1).concat(new Array(251).fill(0))
t.equals(MaskPattern.getPenaltyN4(matrix2), 10,
'Should return correct penalty points')
const matrix3 = new BitMatrix(10)
matrix3.data = new Array(22).fill(1).concat(new Array(78).fill(0))
t.equals(MaskPattern.getPenaltyN4(matrix3), 50,
'Should return correct penalty points')
t.end()
})
test('Mask pattern - Best mask', function (t) {
const matrix = new BitMatrix(11)
matrix.data = [
0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1,
0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1,
0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1,
0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0,
1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0
]
const mask = MaskPattern.getBestMask(matrix, function () {})
t.ok(!isNaN(mask), 'Should return a number')
t.ok(mask >= 0 && mask < 8,
'Should return a number in range 0,7')
t.end()
})