mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-03 01:39:21 +02:00
test(adb): add tests for base64 module
This commit is contained in:
parent
e5f6b34ed0
commit
8b648991e8
9 changed files with 5019 additions and 32 deletions
6
.github/workflows/nodejs.yml
vendored
6
.github/workflows/nodejs.yml
vendored
|
@ -28,6 +28,6 @@ jobs:
|
|||
env:
|
||||
CI: true
|
||||
- run: npm run build --if-present
|
||||
# - run: npm test
|
||||
# env:
|
||||
# CI: true
|
||||
- run: npm test
|
||||
env:
|
||||
CI: true
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
"build": "lerna run --scope @yume-chan/adb-backend-web build",
|
||||
"build:watch": "lerna run --scope @yume-chan/adb-backend-web --stream build:watch",
|
||||
"build:demo": "lerna run --scope demo --stream build",
|
||||
"start:demo": "lerna run --scope demo --stream start"
|
||||
"start:demo": "lerna run --scope demo --stream start",
|
||||
"test": "lerna run --stream test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"lerna": "3.22.1"
|
||||
|
|
4
packages/adb/.npmignore
Normal file
4
packages/adb/.npmignore
Normal file
|
@ -0,0 +1,4 @@
|
|||
__snapshots__
|
||||
**/*.spec.*
|
||||
jest.config.js
|
||||
tsconfig.tsbuildinfo
|
5
packages/adb/jest.config.js
Normal file
5
packages/adb/jest.config.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testRegex: 'src/.*/*.spec.tsx?$',
|
||||
testEnvironment: 'node',
|
||||
};
|
4798
packages/adb/package-lock.json
generated
4798
packages/adb/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -15,12 +15,16 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "tsc -b",
|
||||
"build:watch": "tsc -b -w"
|
||||
"build:watch": "tsc -b -w",
|
||||
"test": "jest"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/yume-chan/ya-webadb/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "26.0.19",
|
||||
"jest": "26.6.3",
|
||||
"ts-jest": "26.4.4",
|
||||
"typescript": "4.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -71,7 +71,7 @@ export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
|
|||
}
|
||||
|
||||
const publicKeyLength = calculatePublicKeyLength();
|
||||
const publicKeyBase64Length = calculateBase64EncodedLength(publicKeyLength);
|
||||
const [publicKeyBase64Length] = calculateBase64EncodedLength(publicKeyLength);
|
||||
|
||||
// The public key is null terminated,
|
||||
// So we allocate the buffer with one extra byte.
|
||||
|
|
170
packages/adb/src/utils/base64.spec.ts
Normal file
170
packages/adb/src/utils/base64.spec.ts
Normal file
|
@ -0,0 +1,170 @@
|
|||
import { calculateBase64EncodedLength, decodeBase64, encodeBase64 } from './base64';
|
||||
|
||||
describe('base64', () => {
|
||||
describe('calculateBase64EncodedLength', () => {
|
||||
it('input 0', () => {
|
||||
expect(calculateBase64EncodedLength(0)).toEqual([0, 0]);
|
||||
});
|
||||
|
||||
it('input 1', () => {
|
||||
expect(calculateBase64EncodedLength(1)).toEqual([4, 2]);
|
||||
});
|
||||
|
||||
it('input 2', () => {
|
||||
expect(calculateBase64EncodedLength(2)).toEqual([4, 1]);
|
||||
});
|
||||
|
||||
it('input 3', () => {
|
||||
expect(calculateBase64EncodedLength(3)).toEqual([4, 0]);
|
||||
});
|
||||
|
||||
it('input 4', () => {
|
||||
expect(calculateBase64EncodedLength(4)).toEqual([8, 2]);
|
||||
});
|
||||
|
||||
it('input 5', () => {
|
||||
expect(calculateBase64EncodedLength(5)).toEqual([8, 1]);
|
||||
});
|
||||
|
||||
it('input 6', () => {
|
||||
expect(calculateBase64EncodedLength(6)).toEqual([8, 0]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('decodeBase64', () => {
|
||||
it("input length 0", () => {
|
||||
expect(new Uint8Array(decodeBase64(''))).toEqual(new Uint8Array());
|
||||
});
|
||||
|
||||
it("input length 1", () => {
|
||||
expect(new Uint8Array(decodeBase64('AA=='))).toEqual(new Uint8Array([0]));
|
||||
});
|
||||
|
||||
it("input length 2", () => {
|
||||
expect(new Uint8Array(decodeBase64('AAE='))).toEqual(new Uint8Array([0, 1]));
|
||||
});
|
||||
|
||||
it("input length 3", () => {
|
||||
expect(new Uint8Array(decodeBase64('AAEC'))).toEqual(new Uint8Array([0, 1, 2]));
|
||||
});
|
||||
|
||||
it("input length 4", () => {
|
||||
expect(new Uint8Array(decodeBase64('AAECAw=='))).toEqual(new Uint8Array([0, 1, 2, 3]));
|
||||
});
|
||||
|
||||
it("input length 5", () => {
|
||||
expect(new Uint8Array(decodeBase64('AAECAwQ='))).toEqual(new Uint8Array([0, 1, 2, 3, 4]));
|
||||
});
|
||||
|
||||
it("input length 6", () => {
|
||||
expect(new Uint8Array(decodeBase64('AAECAwQF'))).toEqual(new Uint8Array([0, 1, 2, 3, 4, 5]));
|
||||
});
|
||||
|
||||
it("all byte values", () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
decodeBase64(
|
||||
'AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=='
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array(Array.from({ length: 256 }, (_, index) => index)));
|
||||
});
|
||||
});
|
||||
|
||||
describe('encodeBase64', () => {
|
||||
it('input length 0', () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array()
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array());
|
||||
});
|
||||
|
||||
it('input length 1', () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array(
|
||||
[0]
|
||||
)
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array([65, 65, 61, 61])); // AA==
|
||||
});
|
||||
|
||||
it('input length 2', () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array(
|
||||
[0, 1]
|
||||
)
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array([65, 65, 69, 61])); // AAE=
|
||||
});
|
||||
|
||||
it('input length 3', () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array(
|
||||
[0, 1, 2]
|
||||
)
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array([65, 65, 69, 67])); // AAEC
|
||||
});
|
||||
|
||||
it('input length 4', () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array(
|
||||
[0, 1, 2, 3]
|
||||
)
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array([65, 65, 69, 67, 65, 119, 61, 61])); // AAECAw==
|
||||
});
|
||||
|
||||
it('input length 5', () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array(
|
||||
[0, 1, 2, 3, 4]
|
||||
)
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array([65, 65, 69, 67, 65, 119, 81, 61])); // AAECAwQ=
|
||||
});
|
||||
|
||||
it('input length 6', () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array(
|
||||
[0, 1, 2, 3, 4, 5]
|
||||
)
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array([65, 65, 69, 67, 65, 119, 81, 70])); // AAECAwQF
|
||||
});
|
||||
|
||||
it("all byte values", () => {
|
||||
expect(
|
||||
new Uint8Array(
|
||||
encodeBase64(
|
||||
new Uint8Array(
|
||||
Array.from({ length: 256 }, (_, index) => index)
|
||||
)
|
||||
)
|
||||
)
|
||||
).toEqual(new Uint8Array([65, 65, 69, 67, 65, 119, 81, 70, 66, 103, 99, 73, 67, 81, 111, 76, 68, 65, 48, 79, 68, 120, 65, 82, 69, 104, 77, 85, 70, 82, 89, 88, 71, 66, 107, 97, 71, 120, 119, 100, 72, 104, 56, 103, 73, 83, 73, 106, 74, 67, 85, 109, 74, 121, 103, 112, 75, 105, 115, 115, 76, 83, 52, 118, 77, 68, 69, 121, 77, 122, 81, 49, 78, 106, 99, 52, 79, 84, 111, 55, 80, 68, 48, 43, 80, 48, 66, 66, 81, 107, 78, 69, 82, 85, 90, 72, 83, 69, 108, 75, 83, 48, 120, 78, 84, 107, 57, 81, 85, 86, 74, 84, 86, 70, 86, 87, 86, 49, 104, 90, 87, 108, 116, 99, 88, 86, 53, 102, 89, 71, 70, 105, 89, 50, 82, 108, 90, 109, 100, 111, 97, 87, 112, 114, 98, 71, 49, 117, 98, 51, 66, 120, 99, 110, 78, 48, 100, 88, 90, 51, 101, 72, 108, 54, 101, 51, 120, 57, 102, 110, 43, 65, 103, 89, 75, 68, 104, 73, 87, 71, 104, 52, 105, 74, 105, 111, 117, 77, 106, 89, 54, 80, 107, 74, 71, 83, 107, 53, 83, 86, 108, 112, 101, 89, 109, 90, 113, 98, 110, 74, 50, 101, 110, 54, 67, 104, 111, 113, 79, 107, 112, 97, 97, 110, 113, 75, 109, 113, 113, 54, 121, 116, 114, 113, 43, 119, 115, 98, 75, 122, 116, 76, 87, 50, 116, 55, 105, 53, 117, 114, 117, 56, 118, 98, 54, 47, 119, 77, 72, 67, 119, 56, 84, 70, 120, 115, 102, 73, 121, 99, 114, 76, 122, 77, 51, 79, 122, 57, 68, 82, 48, 116, 80, 85, 49, 100, 98, 88, 50, 78, 110, 97, 50, 57, 122, 100, 51, 116, 47, 103, 52, 101, 76, 106, 53, 79, 88, 109, 53, 43, 106, 112, 54, 117, 118, 115, 55, 101, 55, 118, 56, 80, 72, 121, 56, 47, 84, 49, 57, 118, 102, 52, 43, 102, 114, 55, 47, 80, 51, 43, 47, 119, 61, 61]));
|
||||
// AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
// Prepare maps for O(1) searching
|
||||
const charToIndex: Record<string, number> = {};
|
||||
const indexToChar: number[] = [];
|
||||
const padding = '='.charCodeAt(0);
|
||||
const paddingChar = '='.charCodeAt(0);
|
||||
|
||||
function addRange(start: string, end: string) {
|
||||
const charCodeStart = start.charCodeAt(0);
|
||||
|
@ -20,40 +20,42 @@ addRange('0', '9');
|
|||
addRange('+', '+');
|
||||
addRange('/', '/');
|
||||
|
||||
export function calculateBase64EncodedLength(inputLength: number): number {
|
||||
return Math.ceil(inputLength / 3) * 4;
|
||||
export function calculateBase64EncodedLength(inputLength: number): [outputLength: number, paddingLength: number] {
|
||||
const remainder = inputLength % 3;
|
||||
const paddingLength = remainder !== 0 ? 3 - remainder : 0;
|
||||
return [(inputLength + paddingLength) / 3 * 4, paddingLength];
|
||||
}
|
||||
|
||||
export function encodeBase64(
|
||||
input: ArrayBuffer | Uint8Array,
|
||||
inputOffset?: number,
|
||||
inputLength?: number,
|
||||
): ArrayBuffer;
|
||||
): ArrayBuffer; // overload 1
|
||||
export function encodeBase64(
|
||||
input: ArrayBuffer | Uint8Array,
|
||||
output: ArrayBuffer | Uint8Array,
|
||||
outputOffset?: number
|
||||
): number;
|
||||
): number; // overload 2
|
||||
export function encodeBase64(
|
||||
input: ArrayBuffer | Uint8Array,
|
||||
inputOffset: number,
|
||||
output: ArrayBuffer | Uint8Array,
|
||||
outputOffset?: number
|
||||
): number;
|
||||
): number; // overload 3
|
||||
export function encodeBase64(
|
||||
input: ArrayBuffer | Uint8Array,
|
||||
inputOffset: number,
|
||||
inputLength: number,
|
||||
output: ArrayBuffer | Uint8Array,
|
||||
outputOffset?: number
|
||||
): number;
|
||||
): number; // overload 4
|
||||
export function encodeBase64(
|
||||
input: ArrayBuffer | Uint8Array,
|
||||
arg1?: number | ArrayBuffer | Uint8Array,
|
||||
arg2?: number | ArrayBuffer | Uint8Array,
|
||||
_arg3?: number | ArrayBuffer | Uint8Array,
|
||||
_arg4?: number,
|
||||
): ArrayBuffer | Uint8Array | number {
|
||||
): ArrayBuffer | number {
|
||||
if (input instanceof ArrayBuffer) {
|
||||
input = new Uint8Array(input);
|
||||
}
|
||||
|
@ -71,23 +73,27 @@ export function encodeBase64(
|
|||
let outputOffset: number;
|
||||
|
||||
let outputArgumentIndex: number;
|
||||
if (typeof arg1 !== 'number') {
|
||||
if (typeof arg1 === 'number') {
|
||||
// overload 1, 3, 4
|
||||
inputOffset = arg1;
|
||||
|
||||
if (typeof arg2 === 'number') {
|
||||
// overload 1, 4
|
||||
inputLength = arg2;
|
||||
outputArgumentIndex = 3;
|
||||
} else {
|
||||
// overload 3
|
||||
inputLength = input.byteLength - inputOffset;
|
||||
outputArgumentIndex = 2;
|
||||
}
|
||||
} else {
|
||||
// overload 2
|
||||
inputOffset = 0;
|
||||
inputLength = input.byteLength;
|
||||
outputArgumentIndex = 1;
|
||||
} else {
|
||||
inputOffset = arg1;
|
||||
|
||||
if (typeof arg2 !== 'number') {
|
||||
inputLength = input.byteLength - inputOffset;
|
||||
outputArgumentIndex = 2;
|
||||
} else {
|
||||
inputLength = arg2;
|
||||
outputArgumentIndex = 3;
|
||||
}
|
||||
}
|
||||
|
||||
const outputLength = calculateBase64EncodedLength(inputLength);
|
||||
const [outputLength, paddingLength] = calculateBase64EncodedLength(inputLength);
|
||||
|
||||
let maybeOutput: ArrayBuffer | Uint8Array | undefined = arguments[outputArgumentIndex];
|
||||
let outputType: 'ArrayBuffer' | 'number';
|
||||
|
@ -134,16 +140,15 @@ export function encodeBase64(
|
|||
let inputIndex = inputOffset + inputLength - 1;
|
||||
let outputIndex = outputOffset + outputLength - 1;
|
||||
|
||||
const extraBytes = inputLength % 3;
|
||||
if (extraBytes === 1) {
|
||||
if (paddingLength === 2) {
|
||||
// aaaaaabb
|
||||
const x = input[inputIndex];
|
||||
inputIndex -= 1;
|
||||
|
||||
output[outputIndex] = padding;
|
||||
output[outputIndex] = paddingChar;
|
||||
outputIndex -= 1;
|
||||
|
||||
output[outputIndex] = padding;
|
||||
output[outputIndex] = paddingChar;
|
||||
outputIndex -= 1;
|
||||
|
||||
output[outputIndex] = indexToChar[((x & 0b11) << 4)];
|
||||
|
@ -151,7 +156,7 @@ export function encodeBase64(
|
|||
|
||||
output[outputIndex] = indexToChar[x >> 2];
|
||||
outputIndex -= 1;
|
||||
} else if (extraBytes === 2) {
|
||||
} else if (paddingLength === 1) {
|
||||
// bbbbcccc
|
||||
const y = input[inputIndex];
|
||||
inputIndex -= 1;
|
||||
|
@ -160,7 +165,7 @@ export function encodeBase64(
|
|||
const x = input[inputIndex];
|
||||
inputIndex -= 1;
|
||||
|
||||
output[outputIndex] = padding;
|
||||
output[outputIndex] = paddingChar;
|
||||
outputIndex -= 1;
|
||||
|
||||
output[outputIndex] = indexToChar[((y & 0b1111) << 2)];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue