Files
juzi/taobao/test/camera-pixel-calibration.test.cjs
T
xsl 774376fa16 feat: 完善淘宝小程序拍照、报告与登录流程
接入本地实时识别和自动三连拍,调整报告裁切、商品跳转、分享标题及居中页眉;完善游客会话、后台渠道隔离、部署脚本与回归测试。
2026-11-04 15:07:51 +08:00

116 lines
7.1 KiB
JavaScript

'use strict';
const { test } = require('node:test'), assert = require('node:assert/strict');
const fs = require('node:fs'), path = require('node:path'), vm = require('node:vm');
const jpeg = 'data:image/jpeg;base64,/9j/2Q==';
function setup() {
const writes = [], dimensions = [], module = { exports: {} };
const context = { putImageData(value) { writes.push(value); value.success(); },
toDataURL(value) { value.success(jpeg); } };
vm.runInNewContext(fs.readFileSync(path.resolve(__dirname, '../utils/image.js'), 'utf8'), {
module, Promise, setTimeout, clearTimeout, Uint8Array, Uint8ClampedArray, ArrayBuffer,
my: { createCanvasContext(id) { assert.equal(id, 'compress-canvas'); return context; },
getImageInfo() { throw Error('raw pixels were incorrectly treated as an encoded file'); },
canvasPutImageData() { throw Error('Taobao context.putImageData must be used when available'); } }
});
return { image: module.exports, writes, dimensions, page: { alive: true,
setData(value, callback) { dimensions.push(value); callback(); } } };
}
function frame(bytes = [9, 33, 201, 255, 41, 52, 63, 255]) {
return { width: 2, height: 1, capturedImage: new Uint8Array(bytes).buffer, anchors: [{ private: true }] };
}
test('unknown raw pixels stay blocked until explicit confirmation; a preview alone never chooses the production layout', async () => {
const f = setup(), source = frame();
assert.deepEqual(Array.from(f.image.frameCalibrationFormats(source)), ['RGBA', 'BGRA', 'ARGB', 'ABGR']);
await assert.rejects(f.image.captureFrameToBase64(source, f.page), /格式尚未确认/);
assert.equal(await f.image.captureFrameToBase64(source, f.page, { pixelFormat: 'BGRA', maxSide: 480 }), jpeg);
assert.deepEqual(Array.from(f.writes[0].data), [201, 33, 9, 255, 63, 52, 41, 255]);
assert.equal(f.image.confirmedFramePixelFormat(), '');
await assert.rejects(f.image.captureFrameToBase64(source, f.page), /格式尚未确认/);
assert.equal(f.image.confirmFramePixelFormat(source, 'BGRA'), 'BGRA');
assert.equal(await f.image.captureFrameToBase64(source, f.page), jpeg);
assert.deepEqual(Array.from(f.writes[1].data), [201, 33, 9, 255, 63, 52, 41, 255]);
assert.equal(f.image.confirmedFramePixelFormat(), 'BGRA');
await assert.rejects(f.image.captureFrameToBase64({ width: 2, height: 1, data: source.capturedImage }, f.page), /格式尚未确认/);
assert.equal(setup().image.confirmedFramePixelFormat(), '', 'a cold runtime does not restore the choice from Storage');
});
test('candidate decoders produce the same RGB colors for all four explicitly described byte orders', async () => {
const rgb = [17, 58, 203, 255, 91, 34, 16, 255];
const candidates = {
RGBA: [17, 58, 203, 255, 91, 34, 16, 255],
BGRA: [203, 58, 17, 255, 16, 34, 91, 255],
ARGB: [255, 17, 58, 203, 255, 91, 34, 16],
ABGR: [255, 203, 58, 17, 255, 16, 34, 91]
};
for (const [format, bytes] of Object.entries(candidates)) {
const f = setup();
await f.image.captureFrameToBase64(frame(bytes), f.page, { pixelFormat: format });
assert.deepEqual(Array.from(f.writes[0].data), rgb, format);
}
});
test('calibration freezes only the raw image once, preserving its field path while excluding face landmarks', async () => {
const f = setup(), source = frame();
const snapshot = f.image.freezeCalibrationFrame(source);
assert.equal(snapshot.anchors, undefined);
assert.notEqual(snapshot.capturedImage, source.capturedImage);
new Uint8Array(source.capturedImage).fill(0);
await f.image.captureFrameToBase64(snapshot, f.page, { pixelFormat: 'RGBA' });
assert.deepEqual(Array.from(f.writes[0].data), [9, 33, 201, 255, 41, 52, 63, 255]);
const nested = { width: 2, height: 1, capture: { image: { bytes: frame().capturedImage } } };
const nestedSnapshot = f.image.freezeCalibrationFrame(nested);
f.image.confirmFramePixelFormat(nestedSnapshot, 'RGBA');
await f.image.captureFrameToBase64(nested, f.page);
assert.equal(f.writes.length, 2);
});
test('native format declarations cannot be overwritten by a calibration choice and invalid choices never unlock capture', async () => {
const f = setup(), source = frame();
assert.throws(() => f.image.confirmFramePixelFormat(source, 'NV21'), /未通过/);
assert.equal(f.image.confirmedFramePixelFormat(), '');
const unsupported = { ...source, pixelFormat: 'NV21' };
assert.deepEqual(Array.from(f.image.frameCalibrationFormats(unsupported)), []);
await assert.rejects(f.image.captureFrameToBase64(unsupported, f.page, { pixelFormat: 'RGBA' }), /格式尚未确认/);
const declared = { ...frame(), pixelFormat: 'RGBA8888' };
await f.image.captureFrameToBase64(declared, f.page, { pixelFormat: 'BGRA' });
assert.deepEqual(Array.from(f.writes[0].data), [9, 33, 201, 255, 41, 52, 63, 255]);
});
test('calibration thumbnails use the Taobao canvas and a 480px limit while formal capture retains its 1280px limit', async () => {
const f = setup(), source = { width: 720, height: 1280, capturedImage: new Uint8Array(720 * 1280 * 4).buffer };
await f.image.captureFrameToBase64(source, f.page, { pixelFormat: 'RGBA', maxSide: 480 });
assert.equal(f.writes[0].width, 270); assert.equal(f.writes[0].height, 480);
f.image.confirmFramePixelFormat(source, 'RGBA');
await f.image.captureFrameToBase64(source, f.page);
assert.equal(f.writes[1].width, 720); assert.equal(f.writes[1].height, 1280);
});
test('raw pixel values resembling JPEG or PNG headers are never decoded as compressed images', async () => {
for (const pixels of [[255, 216, 255, 255, 1, 2, 3, 255], [137, 80, 78, 71, 1, 2, 3, 255]]) {
const f = setup();
await f.image.captureFrameToBase64(frame(pixels), f.page, { pixelFormat: 'RGBA' });
assert.equal(f.writes.length, 1);
assert.deepEqual(Array.from(f.writes[0].data).slice(0, 3), pixels.slice(0, 3));
}
});
test('the application default exports unlabelled four-channel photos without calibration and never records confirmation', async () => {
const f = setup(), source = frame();
assert.equal(await f.image.captureFrameToBase64(source, f.page, { defaultPixelFormat: 'RGBA' }), jpeg);
assert.deepEqual(Array.from(f.writes[0].data), [9, 33, 201, 255, 41, 52, 63, 255]);
assert.equal(f.image.confirmedFramePixelFormat(), '');
await assert.rejects(f.image.captureFrameToBase64(source, f.page), /格式尚未确认/);
});
test('application default is lower priority than platform metadata and an optional confirmed format', async () => {
const f = setup(), source = frame();
await f.image.captureFrameToBase64({ ...source, pixelFormat: 'BGRA' }, f.page, { defaultPixelFormat: 'RGBA' });
assert.deepEqual(Array.from(f.writes[0].data), [201, 33, 9, 255, 63, 52, 41, 255]);
f.image.confirmFramePixelFormat(source, 'BGRA');
await f.image.captureFrameToBase64(source, f.page, { defaultPixelFormat: 'RGBA' });
assert.deepEqual(Array.from(f.writes[1].data), [201, 33, 9, 255, 63, 52, 41, 255]);
await assert.rejects(f.image.captureFrameToBase64({ ...source, pixelFormat: 'NV21' }, f.page, { defaultPixelFormat: 'RGBA' }), /格式尚未确认/);
await assert.rejects(f.image.captureFrameToBase64({ width: 2, height: 1, capturedImage: new Uint8Array(3).buffer }, f.page, { defaultPixelFormat: 'RGBA' }), /未收到可导出/);
});