import {stringToUint8Array} from '../../src/utils/string';
import {
arraySortEquals,
parseMultipart,
buildMultipart
} from '../../src/utils/array';
/**
* Tests for the 'utils/array' file.
*/
/** @module tests/utils */
// Do not warn if these variables were not defined before.
/* global QUnit */
QUnit.module('utils');
/**
* Tests for {@link arraySortEquals}.
*
* @function module:tests/utils~arraySortEquals
*/
QUnit.test('Test arraySortEquals.', function (assert) {
// null
assert.notOk(arraySortEquals(null, null), '2 null arrays');
assert.notOk(arraySortEquals(null, [1, 2, 3]), 'left null array');
assert.notOk(arraySortEquals([1, 2, 3], null), 'right null array');
// undefined
assert.notOk(arraySortEquals(undefined, undefined),
'2 undefined arrays');
assert.notOk(arraySortEquals(undefined, [1, 2, 3]),
'left undefined arrays');
assert.notOk(arraySortEquals([1, 2, 3], undefined),
'right undefined arrays');
// empty
assert.notOk(arraySortEquals([1], []), 'right empty array');
assert.notOk(arraySortEquals([], [1]), 'left empty array');
assert.ok(arraySortEquals([], []), '2 empty arrays');
// simple arrays
const arr00 = [1, 2, 3];
assert.ok(arraySortEquals(arr00, arr00), 'array equal #0');
const arr01 = [3, 2, 1];
assert.ok(arraySortEquals(arr00, arr01), 'array equal #1');
const arr02 = [1, 2, 3, 4];
assert.notOk(arraySortEquals(arr00, arr02), 'array equal #2');
const arr03 = [1, 'a', null, undefined];
assert.ok(arraySortEquals(arr03, arr03), 'array equal #3');
// array of object
const arr10 = [{a: 0}];
const arr11 = [{a: 0}];
assert.notOk(arraySortEquals(arr10, arr11),
'array of object equal #0');
const obj = {a: 0};
const arr12 = [obj];
const arr13 = [obj];
assert.ok(arraySortEquals(arr12, arr13),
'array of object equal #1');
});
// test data
let multipart01 = 'preamble\r\n';
multipart01 += '--boundary\r\n';
multipart01 += '\r\n';
multipart01 += '--boundary--';
// (inspired from https://github.com/jmhmd/parse-multipart-data/blob/master/src/multipart.ts)
let str10 = '------WebKitFormBoundaryvef1fLxmoUdYZWXp\r\n';
str10 +=
'Content-Disposition: form-data; name="uploads[]"; filename="A.txt"\r\n';
str10 += 'Content-Type: text/plain\r\n';
str10 += '\r\n';
str10 += '@11X111Y\r\n';
str10 += '111Z\rCCCC\nCCCC\r\nCCCCC@\r\n';
str10 += '\r\n';
str10 += '------WebKitFormBoundaryvef1fLxmoUdYZWXp\r\n';
str10 +=
'Content-Disposition: form-data; name="uploads[]"; filename="B.txt"\r\n';
str10 += 'Content-Type: text/plain\r\n';
str10 += '\r\n';
str10 += '@22X222Y\r\n';
str10 += '222Z\r222W\n2220\r\n';
str10 += '666@\r\n';
str10 += '\r\n';
str10 += '------WebKitFormBoundaryvef1fLxmoUdYZWXp\r\n';
str10 += 'Content-Disposition: form-data; name="input1"\r\n';
str10 += '\r\n';
str10 += 'value1\r\n';
str10 += '\r\n';
str10 += '------WebKitFormBoundaryvef1fLxmoUdYZWXp--\r\n';
/* eslint-disable array-element-newline */
const multipart10 = {
str: str10,
parts: [
{
'Content-Disposition': 'form-data; name="uploads[]"; filename="A.txt"',
'Content-Type': 'text/plain',
data: new Uint8Array([
64, 49, 49, 88, 49, 49, 49, 89, 13, 10,
49, 49, 49, 90, 13, 67, 67, 67, 67, 10, 67, 67, 67, 67, 13, 10,
67, 67, 67, 67, 67, 64, 13, 10
])
},
{
'Content-Disposition': 'form-data; name="uploads[]"; filename="B.txt"',
'Content-Type': 'text/plain',
data: new Uint8Array([
64, 50, 50, 88, 50, 50, 50, 89, 13, 10,
50, 50, 50, 90, 13, 50, 50, 50, 87, 10, 50, 50, 50, 48, 13, 10,
54, 54, 54, 64, 13, 10
])
},
{
'Content-Disposition': 'form-data; name="input1"',
data: new Uint8Array([
118, 97, 108, 117, 101, 49, 13, 10
])
}
]
};
/* eslint-enable array-element-newline */
// with preamble and epilogue
let str11 = 'preamble\r\n';
str11 += str10;
str11 += 'epilogue\r\n';
const multipart11 = {
str: str11
};
const compareMultipartObjects = function (obj0, obj1) {
if (obj0.length !== obj1.length) {
return false;
}
for (let i = 0; i < obj0.length; ++i) {
const keys = Object.keys(obj0[i]);
for (let k = 0; k < keys.length; ++k) {
const key = keys[k];
if (key !== 'data') {
if (obj0[i][key] !== obj1[i][key]) {
return false;
}
} else {
for (let j = 0; j < obj0[i].data.length; ++j) {
if (obj0[i].data[j] !== obj1[i].data[j]) {
return false;
}
}
}
}
}
return true;
};
const compareBuffers = function (buf1, buf2) {
if (buf1.byteLength !== buf2.byteLength) {
console.log('compareBuffers: length', buf1.byteLength, buf2.byteLength);
return false;
}
const dv1 = new Int8Array(buf1);
const dv2 = new Int8Array(buf2);
for (let i = 0; i !== buf1.byteLength; i++) {
if (dv1[i] !== dv2[i]) {
console.log('compareBuffers: buffer', i, dv1[i], dv2[i]);
return false;
}
}
return true;
};
/**
* Tests for {@link parseMultipart}.
*
* @function module:tests/utils~parseMultipart
*/
QUnit.test('Test parseMultipart.', function (assert) {
// empty
const res00 = parseMultipart(new Uint8Array(0).buffer);
assert.equal(res00.length, 0, 'Empty multipart length');
// empty part
const u8Test01 = stringToUint8Array(multipart01);
const res01 = parseMultipart(u8Test01.buffer);
assert.equal(res01.length, 1, 'Empty multipart part length');
const keys01 = Object.keys(res01);
assert.equal(keys01.length, 1, 'Empty multipart part keys length');
assert.ok(typeof res01[0].data !== 'undefined',
'Empty multipart part has data');
assert.equal(res01[0].data.length, 0, 'Empty multipart part data length');
// test #10
// parse multipart
const u8Test10 = stringToUint8Array(multipart10.str);
const resMulti10 = parseMultipart(u8Test10.buffer);
assert.ok(compareMultipartObjects(resMulti10, multipart10.parts),
'Compare multipart object #10');
// build multipart
const resBuff10 = buildMultipart(multipart10.parts,
'----WebKitFormBoundaryvef1fLxmoUdYZWXp');
assert.ok(compareBuffers(resBuff10, u8Test10),
'Compare multipart buffer #10');
// test #11: with preamble and epilogue
const u8Test11 = stringToUint8Array(multipart11.str);
const resMulti11 = parseMultipart(u8Test11.buffer);
assert.ok(compareMultipartObjects(resMulti11, multipart10.parts),
'Compare multipart object #11');
});