appium-ios-remotexpc 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/build/src/base-plist-service.d.ts +51 -0
- package/build/src/base-plist-service.d.ts.map +1 -0
- package/build/src/base-plist-service.js +61 -0
- package/build/src/base-socket-service.d.ts +15 -0
- package/build/src/base-socket-service.d.ts.map +1 -0
- package/build/src/base-socket-service.js +46 -0
- package/build/src/index.d.ts +9 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +7 -0
- package/build/src/lib/apple-tv/constants.d.ts +49 -0
- package/build/src/lib/apple-tv/constants.d.ts.map +1 -0
- package/build/src/lib/apple-tv/constants.js +71 -0
- package/build/src/lib/apple-tv/errors.d.ts +17 -0
- package/build/src/lib/apple-tv/errors.d.ts.map +1 -0
- package/build/src/lib/apple-tv/errors.js +30 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts +19 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/decoder.js +49 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts +10 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/encoder.js +20 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts +4 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/index.js +3 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts +14 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.js +27 -0
- package/build/src/lib/apple-tv/types.d.ts +36 -0
- package/build/src/lib/apple-tv/types.d.ts.map +1 -0
- package/build/src/lib/apple-tv/types.js +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts +40 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.js +76 -0
- package/build/src/lib/apple-tv/utils/index.d.ts +3 -0
- package/build/src/lib/apple-tv/utils/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/index.js +2 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts +9 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.js +36 -0
- package/build/src/lib/lockdown/index.d.ts +87 -0
- package/build/src/lib/lockdown/index.d.ts.map +1 -0
- package/build/src/lib/lockdown/index.js +324 -0
- package/build/src/lib/pair-record/index.d.ts +3 -0
- package/build/src/lib/pair-record/index.d.ts.map +1 -0
- package/build/src/lib/pair-record/index.js +2 -0
- package/build/src/lib/pair-record/pair-record.d.ts +48 -0
- package/build/src/lib/pair-record/pair-record.d.ts.map +1 -0
- package/build/src/lib/pair-record/pair-record.js +85 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-creator.js +475 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-parser.js +449 -0
- package/build/src/lib/plist/constants.d.ts +36 -0
- package/build/src/lib/plist/constants.d.ts.map +1 -0
- package/build/src/lib/plist/constants.js +43 -0
- package/build/src/lib/plist/index.d.ts +14 -0
- package/build/src/lib/plist/index.d.ts.map +1 -0
- package/build/src/lib/plist/index.js +16 -0
- package/build/src/lib/plist/length-based-splitter.d.ts +43 -0
- package/build/src/lib/plist/length-based-splitter.d.ts.map +1 -0
- package/build/src/lib/plist/length-based-splitter.js +228 -0
- package/build/src/lib/plist/plist-creator.d.ts +8 -0
- package/build/src/lib/plist/plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/plist-creator.js +33 -0
- package/build/src/lib/plist/plist-decoder.d.ts +25 -0
- package/build/src/lib/plist/plist-decoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-decoder.js +103 -0
- package/build/src/lib/plist/plist-encoder.d.ts +10 -0
- package/build/src/lib/plist/plist-encoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-encoder.js +27 -0
- package/build/src/lib/plist/plist-parser.d.ts +9 -0
- package/build/src/lib/plist/plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/plist-parser.js +109 -0
- package/build/src/lib/plist/plist-service.d.ts +86 -0
- package/build/src/lib/plist/plist-service.d.ts.map +1 -0
- package/build/src/lib/plist/plist-service.js +180 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts +9 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-creator.js +14 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts +8 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-parser.js +23 -0
- package/build/src/lib/plist/utils.d.ts +97 -0
- package/build/src/lib/plist/utils.d.ts.map +1 -0
- package/build/src/lib/plist/utils.js +287 -0
- package/build/src/lib/remote-xpc/constants.d.ts +20 -0
- package/build/src/lib/remote-xpc/constants.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/constants.js +21 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts +74 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake-frames.js +285 -0
- package/build/src/lib/remote-xpc/handshake.d.ts +14 -0
- package/build/src/lib/remote-xpc/handshake.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake.js +95 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts +55 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.js +365 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts +22 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/xpc-protocol.js +368 -0
- package/build/src/lib/tunnel/index.d.ts +69 -0
- package/build/src/lib/tunnel/index.d.ts.map +1 -0
- package/build/src/lib/tunnel/index.js +205 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts +46 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-client.js +152 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts +37 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-server.js +109 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts +85 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-api-client.js +207 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts +68 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-registry-server.js +351 -0
- package/build/src/lib/types.d.ts +238 -0
- package/build/src/lib/types.d.ts.map +1 -0
- package/build/src/lib/types.js +4 -0
- package/build/src/lib/usbmux/index.d.ts +177 -0
- package/build/src/lib/usbmux/index.d.ts.map +1 -0
- package/build/src/lib/usbmux/index.js +490 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts +19 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-decoder.js +38 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts +12 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-encoder.js +32 -0
- package/build/src/service-connection.d.ts +34 -0
- package/build/src/service-connection.d.ts.map +1 -0
- package/build/src/service-connection.js +51 -0
- package/build/src/services/index.d.ts +6 -0
- package/build/src/services/index.d.ts.map +1 -0
- package/build/src/services/index.js +5 -0
- package/build/src/services/ios/base-service.d.ts +35 -0
- package/build/src/services/ios/base-service.d.ts.map +1 -0
- package/build/src/services/ios/base-service.js +55 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts +46 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/index.js +169 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts +5 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/keys.js +770 -0
- package/build/src/services/ios/syslog-service/index.d.ts +91 -0
- package/build/src/services/ios/syslog-service/index.d.ts.map +1 -0
- package/build/src/services/ios/syslog-service/index.js +323 -0
- package/build/src/services/ios/tunnel-service/index.d.ts +17 -0
- package/build/src/services/ios/tunnel-service/index.d.ts.map +1 -0
- package/build/src/services/ios/tunnel-service/index.js +57 -0
- package/build/src/services.d.ts +14 -0
- package/build/src/services.d.ts.map +1 -0
- package/build/src/services.js +48 -0
- package/package.json +12 -3
- package/.github/dependabot.yml +0 -38
- package/.github/workflows/format-check.yml +0 -43
- package/.github/workflows/lint-and-build.yml +0 -40
- package/.github/workflows/pr-title.yml +0 -16
- package/.github/workflows/publish.js.yml +0 -41
- package/.github/workflows/test-validation.yml +0 -40
- package/.mocharc.json +0 -8
- package/.prettierignore +0 -3
- package/.prettierrc +0 -17
- package/.releaserc +0 -48
- package/assets/images/ios-arch.png +0 -0
- package/eslint.config.js +0 -45
- package/npm-shrinkwrap.json +0 -2711
- package/test/integration/diagnostics-test.ts +0 -44
- package/test/integration/read-pair-record-test.ts +0 -39
- package/test/integration/tunnel-test.ts +0 -104
- package/test/unit/apple-tv/tlv/decoder.spec.ts +0 -144
- package/test/unit/apple-tv/tlv/encoder.spec.ts +0 -91
- package/test/unit/apple-tv/tlv/pairing-tlv.spec.ts +0 -101
- package/test/unit/apple-tv/tlv/tlv-integration.spec.ts +0 -146
- package/test/unit/apple-tv/utils/buffer-utils.spec.ts +0 -74
- package/test/unit/apple-tv/utils/uuid-generator.spec.ts +0 -39
- package/test/unit/fixtures/index.ts +0 -88
- package/test/unit/fixtures/usbmuxconnectmessage.bin +0 -0
- package/test/unit/fixtures/usbmuxlistdevicemessage.bin +0 -0
- package/test/unit/plist/error-handling.spec.ts +0 -101
- package/test/unit/plist/fixtures/sample.binary.plist +0 -0
- package/test/unit/plist/fixtures/sample.xml.plist +0 -38
- package/test/unit/plist/plist-parser.spec.ts +0 -283
- package/test/unit/plist/plist.spec.ts +0 -205
- package/test/unit/plist/tag-position-handling.spec.ts +0 -90
- package/test/unit/plist/unified-plist-parser.spec.ts +0 -227
- package/test/unit/plist/utils.spec.ts +0 -249
- package/test/unit/plist/xml-cleaning.spec.ts +0 -60
- package/test/unit/tunnel/tunnel-registry-server.spec.ts +0 -194
- package/test/unit/usbmux/usbmux-specs.ts +0 -71
- package/tsconfig.json +0 -36
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
bigIntToBuffer,
|
|
5
|
-
bigIntToMinimalBuffer,
|
|
6
|
-
bufferToBigInt,
|
|
7
|
-
modPow,
|
|
8
|
-
} from '../../../../src/lib/apple-tv/utils/buffer-utils.js';
|
|
9
|
-
|
|
10
|
-
describe('buffer-utils', () => {
|
|
11
|
-
describe('bigIntToBuffer', () => {
|
|
12
|
-
it('should convert bigint to fixed-length buffer', () => {
|
|
13
|
-
const result = bigIntToBuffer(255n, 4);
|
|
14
|
-
expect(result).to.deep.equal(Buffer.from([0x00, 0x00, 0x00, 0xff]));
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('should throw error for negative values', () => {
|
|
18
|
-
expect(() => bigIntToBuffer(-1n, 4)).to.throw(
|
|
19
|
-
RangeError,
|
|
20
|
-
'Negative values not supported',
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should throw error when value is too large', () => {
|
|
25
|
-
expect(() => bigIntToBuffer(0xffffn, 1)).to.throw(
|
|
26
|
-
RangeError,
|
|
27
|
-
'too large to fit',
|
|
28
|
-
);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('bufferToBigInt', () => {
|
|
33
|
-
it('should convert buffer to bigint', () => {
|
|
34
|
-
const buffer = Buffer.from([0x01, 0x02, 0x03]);
|
|
35
|
-
const result = bufferToBigInt(buffer);
|
|
36
|
-
expect(result).to.equal(0x010203n);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
describe('bigIntToMinimalBuffer', () => {
|
|
41
|
-
it('should convert bigint to minimal buffer', () => {
|
|
42
|
-
const result = bigIntToMinimalBuffer(255n);
|
|
43
|
-
expect(result).to.deep.equal(Buffer.from([0xff]));
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should throw error for negative values', () => {
|
|
47
|
-
expect(() => bigIntToMinimalBuffer(-1n)).to.throw(
|
|
48
|
-
RangeError,
|
|
49
|
-
'Negative values not supported',
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe('modPow', () => {
|
|
55
|
-
it('should compute modular exponentiation', () => {
|
|
56
|
-
const result = modPow(2n, 3n, 5n);
|
|
57
|
-
expect(result).to.equal(3n); // (2^3) % 5 = 8 % 5 = 3
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should throw error for zero modulus', () => {
|
|
61
|
-
expect(() => modPow(2n, 3n, 0n)).to.throw(
|
|
62
|
-
RangeError,
|
|
63
|
-
'Modulus must be non-zero',
|
|
64
|
-
);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('should throw error for negative exponent', () => {
|
|
68
|
-
expect(() => modPow(2n, -1n, 5n)).to.throw(
|
|
69
|
-
RangeError,
|
|
70
|
-
'Negative exponents not supported',
|
|
71
|
-
);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
|
|
3
|
-
import { generateHostId } from '../../../../src/lib/apple-tv/utils/uuid-generator.js';
|
|
4
|
-
|
|
5
|
-
describe('uuid-generator', () => {
|
|
6
|
-
describe('generateHostId', () => {
|
|
7
|
-
it('should generate deterministic UUID from hostname', () => {
|
|
8
|
-
const hostname = 'example.com';
|
|
9
|
-
const uuid1 = generateHostId(hostname);
|
|
10
|
-
const uuid2 = generateHostId(hostname);
|
|
11
|
-
|
|
12
|
-
expect(uuid1).to.equal(uuid2);
|
|
13
|
-
expect(uuid1).to.match(
|
|
14
|
-
/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/,
|
|
15
|
-
);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should generate different UUIDs for different hostnames', () => {
|
|
19
|
-
const uuid1 = generateHostId('example.com');
|
|
20
|
-
const uuid2 = generateHostId('test.com');
|
|
21
|
-
|
|
22
|
-
expect(uuid1).to.not.equal(uuid2);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('should throw error for empty string', () => {
|
|
26
|
-
expect(() => generateHostId('')).to.throw(
|
|
27
|
-
TypeError,
|
|
28
|
-
'Hostname must be a non-empty string',
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('should throw error for non-string input', () => {
|
|
33
|
-
expect(() => generateHostId(null as any)).to.throw(
|
|
34
|
-
TypeError,
|
|
35
|
-
'Hostname must be a non-empty string',
|
|
36
|
-
);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { fs, logger } from '@appium/support';
|
|
2
|
-
import { Server, Socket, createConnection, createServer } from 'node:net';
|
|
3
|
-
import { resolve } from 'node:path';
|
|
4
|
-
|
|
5
|
-
const log = logger.getLogger('fixtures');
|
|
6
|
-
|
|
7
|
-
export const UDID = '63c3d055c4f83e960e5980fa68be0fbf7d4ba74c';
|
|
8
|
-
|
|
9
|
-
let fixtureContents: Record<string, Buffer> | null = null;
|
|
10
|
-
|
|
11
|
-
export const fixtures = {
|
|
12
|
-
DEVICE_LIST: 'deviceList',
|
|
13
|
-
DEVICE_LIST_2: 'deviceList2',
|
|
14
|
-
DEVICE_CONNECT: 'deviceConnect',
|
|
15
|
-
USBMUX_TO_LOCKDOWN: 'usbmuxToLockdown',
|
|
16
|
-
LOCKDOWN_GET_VALUE_OS_VERSION: 'lockdownGetValueOsVersion',
|
|
17
|
-
LOCKDOWN_GET_VALUE_TIME: 'lockdownGetValueTime',
|
|
18
|
-
LOCKDOWN_QUERY_TYPE: 'lockdownQueryType',
|
|
19
|
-
SYSLOG_MESSAGES: 'syslogMessage',
|
|
20
|
-
SYSLOG_SPLIT_MESSAGE_1: 'syslogSplitMessage1',
|
|
21
|
-
SYSLOG_SPLIT_MESSAGE_2: 'syslogSplitMessage2',
|
|
22
|
-
WEBINSPECTOR_MESSAGES: 'webinspector',
|
|
23
|
-
WEBINSPECTOR_PARTIAL_MESSAGES: 'webinspectorPartialMessages',
|
|
24
|
-
INSTALLATION_PROXY_LIST_MESSAGE: 'installationProxyListMessage',
|
|
25
|
-
INSTALLATION_PROXY_INSTALL_MESSAGE: 'installationProxyInstallMessage',
|
|
26
|
-
AFC_SUCCESS_RESPONSE: 'afcSuccessResponse',
|
|
27
|
-
AFC_LIST_DIR_RESPONSE: 'afcListDirResponse',
|
|
28
|
-
AFC_FILE_INFO_RESPONSE: 'afcFileInfoResponse',
|
|
29
|
-
INSTRUMENTS_LAUNCH_APP: 'instrumentsLaunchApp',
|
|
30
|
-
INSTRUMENTS_FPS: 'instrumentsFps',
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
function getFixturePath(file: string): string {
|
|
34
|
-
return resolve(__dirname, file);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async function initFixtures(): Promise<void> {
|
|
38
|
-
if (fixtureContents) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
fixtureContents = {
|
|
43
|
-
[fixtures.DEVICE_LIST]: await fs.readFile(
|
|
44
|
-
getFixturePath('usbmuxlistdevicemessage.bin'),
|
|
45
|
-
),
|
|
46
|
-
[fixtures.DEVICE_CONNECT]: await fs.readFile(
|
|
47
|
-
getFixturePath('usbmuxconnectmessage.bin'),
|
|
48
|
-
),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
interface ServerFixtureResult {
|
|
53
|
-
server: Server;
|
|
54
|
-
socket: Socket;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export async function getServerWithFixtures(
|
|
58
|
-
...args: string[]
|
|
59
|
-
): Promise<ServerFixtureResult> {
|
|
60
|
-
await initFixtures();
|
|
61
|
-
|
|
62
|
-
if (!fixtureContents) {
|
|
63
|
-
throw new Error('Fixtures not initialized');
|
|
64
|
-
}
|
|
65
|
-
const fixturesToUse = args.map((key) => fixtureContents![key]);
|
|
66
|
-
|
|
67
|
-
const server = createServer();
|
|
68
|
-
server.listen();
|
|
69
|
-
const address = server.address();
|
|
70
|
-
if (!address || typeof address === 'string') {
|
|
71
|
-
throw new Error('Invalid server address');
|
|
72
|
-
}
|
|
73
|
-
const socket = createConnection(address.port);
|
|
74
|
-
server.on('connection', function (socket) {
|
|
75
|
-
let i = 0;
|
|
76
|
-
socket.on('data', function () {
|
|
77
|
-
if (i < fixturesToUse.length) {
|
|
78
|
-
log.debug(`Writing to socket. Message #${i}`);
|
|
79
|
-
socket.write(fixturesToUse[i++]);
|
|
80
|
-
log.debug(`Wrote to socket. Message #${i}`);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
return {
|
|
85
|
-
server,
|
|
86
|
-
socket,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
Binary file
|
|
Binary file
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
|
|
3
|
-
import { parsePlist as parseXmlPlist } from '../../../src/lib/plist/plist-parser.js';
|
|
4
|
-
import { parsePlist as unifiedParsePlist } from '../../../src/lib/plist/unified-plist-parser.js';
|
|
5
|
-
import type { PlistDictionary } from '../../../src/lib/types.js';
|
|
6
|
-
|
|
7
|
-
describe('XML Error Handling', function () {
|
|
8
|
-
describe('Unicode Replacement Character Handling', function () {
|
|
9
|
-
it('should handle Unicode replacement characters at the beginning', function () {
|
|
10
|
-
const xml =
|
|
11
|
-
'�<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>';
|
|
12
|
-
const result = parseXmlPlist(xml) as PlistDictionary;
|
|
13
|
-
expect(result).to.have.property('test', 'value');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('should handle Unicode replacement characters at the end', function () {
|
|
17
|
-
const xml =
|
|
18
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>�';
|
|
19
|
-
const result = parseXmlPlist(xml) as PlistDictionary;
|
|
20
|
-
expect(result).to.have.property('test', 'value');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should handle Unicode replacement characters between tags', function () {
|
|
24
|
-
const xml =
|
|
25
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist>�<dict><key>test</key><string>value</string></dict></plist>';
|
|
26
|
-
const result = parseXmlPlist(xml) as PlistDictionary;
|
|
27
|
-
expect(result).to.have.property('test', 'value');
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
describe('Extra Content Handling', function () {
|
|
32
|
-
it('should handle extra content at the end of the document', function () {
|
|
33
|
-
const xml =
|
|
34
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>extra content';
|
|
35
|
-
|
|
36
|
-
const result = parseXmlPlist(xml) as PlistDictionary;
|
|
37
|
-
expect(result).to.have.property('test', 'value');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should handle extra content before the XML declaration', function () {
|
|
41
|
-
const xml =
|
|
42
|
-
'extra content<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>';
|
|
43
|
-
const result = parseXmlPlist(xml) as PlistDictionary;
|
|
44
|
-
expect(result).to.have.property('test', 'value');
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
describe('Unclosed Tags Handling', function () {
|
|
49
|
-
it('should handle unclosed plist tag', function () {
|
|
50
|
-
const xml =
|
|
51
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict>';
|
|
52
|
-
|
|
53
|
-
try {
|
|
54
|
-
parseXmlPlist(xml);
|
|
55
|
-
expect.fail('Should have thrown an error for unclosed plist tag');
|
|
56
|
-
} catch (error) {
|
|
57
|
-
expect(error).to.exist;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should handle unclosed dict tag', function () {
|
|
62
|
-
const xml =
|
|
63
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></plist>';
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
parseXmlPlist(xml);
|
|
67
|
-
expect.fail('Should have thrown an error for unclosed dict tag');
|
|
68
|
-
} catch (error) {
|
|
69
|
-
expect(error).to.exist;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe('Combined Error Scenarios', function () {
|
|
75
|
-
it('should handle both Unicode replacement characters and extra content', function () {
|
|
76
|
-
const xml =
|
|
77
|
-
'�<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>extra content';
|
|
78
|
-
|
|
79
|
-
const result = parseXmlPlist(xml) as PlistDictionary;
|
|
80
|
-
expect(result).to.have.property('test', 'value');
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should handle multiple Unicode replacement characters', function () {
|
|
84
|
-
const xml =
|
|
85
|
-
'�<?xml version="1.0" encoding="UTF-8"?>�<plist><dict><key>test</key><string>value</string></dict></plist>�';
|
|
86
|
-
|
|
87
|
-
const result = parseXmlPlist(xml) as PlistDictionary;
|
|
88
|
-
expect(result).to.have.property('test', 'value');
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('Unified Parser Error Handling', function () {
|
|
93
|
-
it('should handle errors in the unified parser for XML content', function () {
|
|
94
|
-
const xml =
|
|
95
|
-
'�<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>extra content';
|
|
96
|
-
|
|
97
|
-
const result = unifiedParsePlist(xml) as PlistDictionary;
|
|
98
|
-
expect(result).to.have.property('test', 'value');
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
});
|
|
Binary file
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>stringValue</key>
|
|
6
|
-
<string>Hello, World!</string>
|
|
7
|
-
<key>integerValue</key>
|
|
8
|
-
<integer>42</integer>
|
|
9
|
-
<key>realValue</key>
|
|
10
|
-
<real>3.14159</real>
|
|
11
|
-
<key>booleanTrue</key>
|
|
12
|
-
<true/>
|
|
13
|
-
<key>booleanFalse</key>
|
|
14
|
-
<false/>
|
|
15
|
-
<key>dateValue</key>
|
|
16
|
-
<date>2023-01-01T12:00:00Z</date>
|
|
17
|
-
<key>dataValue</key>
|
|
18
|
-
<data>SGVsbG8sIFdvcmxkIQ==</data>
|
|
19
|
-
<key>arrayValue</key>
|
|
20
|
-
<array>
|
|
21
|
-
<string>Item 1</string>
|
|
22
|
-
<string>Item 2</string>
|
|
23
|
-
<integer>3</integer>
|
|
24
|
-
</array>
|
|
25
|
-
<key>dictValue</key>
|
|
26
|
-
<dict>
|
|
27
|
-
<key>nestedKey</key>
|
|
28
|
-
<string>Nested Value</string>
|
|
29
|
-
<key>nestedArray</key>
|
|
30
|
-
<array>
|
|
31
|
-
<integer>1</integer>
|
|
32
|
-
<integer>2</integer>
|
|
33
|
-
</array>
|
|
34
|
-
</dict>
|
|
35
|
-
<key>specialChars</key>
|
|
36
|
-
<string><Hello & World></string>
|
|
37
|
-
</dict>
|
|
38
|
-
</plist>
|
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import { expect } from 'chai';
|
|
2
|
-
|
|
3
|
-
import { parsePlist as parseXmlPlist } from '../../../src/lib/plist/plist-parser.js';
|
|
4
|
-
import {
|
|
5
|
-
findFirstReplacementCharacter,
|
|
6
|
-
fixMultipleXmlDeclarations,
|
|
7
|
-
hasUnicodeReplacementCharacter,
|
|
8
|
-
isValidXml,
|
|
9
|
-
trimBeforeXmlDeclaration,
|
|
10
|
-
} from '../../../src/lib/plist/utils.js';
|
|
11
|
-
import type {
|
|
12
|
-
PlistArray,
|
|
13
|
-
PlistDictionary,
|
|
14
|
-
PlistValue,
|
|
15
|
-
} from '../../../src/lib/types.js';
|
|
16
|
-
|
|
17
|
-
describe('Plist Parser', function () {
|
|
18
|
-
describe('XML Cleaning Logic', function () {
|
|
19
|
-
it('should detect Unicode replacement characters', function () {
|
|
20
|
-
const validXml =
|
|
21
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>';
|
|
22
|
-
const invalidXml =
|
|
23
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>val�ue</string></dict></plist>';
|
|
24
|
-
|
|
25
|
-
expect(hasUnicodeReplacementCharacter(validXml)).to.be.false;
|
|
26
|
-
expect(hasUnicodeReplacementCharacter(invalidXml)).to.be.true;
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should find the position of the first replacement character', function () {
|
|
30
|
-
const xml =
|
|
31
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>val�ue</string></dict></plist>';
|
|
32
|
-
const position = findFirstReplacementCharacter(xml);
|
|
33
|
-
|
|
34
|
-
expect(position).to.equal(xml.indexOf('�'));
|
|
35
|
-
expect(position).to.be.greaterThan(0);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('should handle the case where there is no tag before the replacement character', function () {
|
|
39
|
-
const xml =
|
|
40
|
-
'�<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>';
|
|
41
|
-
|
|
42
|
-
const result = parseXmlPlist(xml);
|
|
43
|
-
|
|
44
|
-
expect(result).to.have.property('test', 'value');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should handle the case where there is no tag after the replacement character', function () {
|
|
48
|
-
const xml =
|
|
49
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist><dict><key>test</key><string>value</string></dict></plist>�';
|
|
50
|
-
|
|
51
|
-
const result = parseXmlPlist(xml);
|
|
52
|
-
|
|
53
|
-
expect(result).to.have.property('test', 'value');
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe('XML Preprocessing Functions', function () {
|
|
58
|
-
it('should trim content before XML declaration', function () {
|
|
59
|
-
const xml =
|
|
60
|
-
'garbage data<?xml version="1.0" encoding="UTF-8"?><plist></plist>';
|
|
61
|
-
const trimmed = trimBeforeXmlDeclaration(xml);
|
|
62
|
-
|
|
63
|
-
expect(trimmed).to.equal(
|
|
64
|
-
'<?xml version="1.0" encoding="UTF-8"?><plist></plist>',
|
|
65
|
-
);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should fix multiple XML declarations', function () {
|
|
69
|
-
const xml =
|
|
70
|
-
'<?xml version="1.0" encoding="UTF-8"?><some-tag><?xml version="1.1"?><plist></plist>';
|
|
71
|
-
const fixed = fixMultipleXmlDeclarations(xml);
|
|
72
|
-
|
|
73
|
-
expect(fixed).to.include('<?xml version="1.0" encoding="UTF-8"?>');
|
|
74
|
-
expect(fixed).to.include('<some-tag>');
|
|
75
|
-
expect(fixed).to.include('<plist></plist>');
|
|
76
|
-
expect(fixed).not.to.include('<?xml version="1.1"?>');
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should validate XML content', function () {
|
|
80
|
-
expect(isValidXml('<?xml version="1.0"?><plist></plist>')).to.be.true;
|
|
81
|
-
expect(isValidXml('')).to.be.false;
|
|
82
|
-
expect(isValidXml(' ')).to.be.false;
|
|
83
|
-
expect(isValidXml('not xml')).to.be.false;
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe('Error Handling', function () {
|
|
88
|
-
it('should handle completely invalid XML', function () {
|
|
89
|
-
try {
|
|
90
|
-
parseXmlPlist('not xml at all');
|
|
91
|
-
expect.fail('Should have thrown an error for invalid XML');
|
|
92
|
-
} catch (error) {
|
|
93
|
-
expect(error).to.exist;
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should handle XML without a plist element', function () {
|
|
98
|
-
try {
|
|
99
|
-
parseXmlPlist('<?xml version="1.0"?><not-a-plist></not-a-plist>');
|
|
100
|
-
expect.fail('Should have thrown an error for missing plist element');
|
|
101
|
-
} catch (error) {
|
|
102
|
-
expect(error).to.exist;
|
|
103
|
-
}
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should handle XML with malformed tags', function () {
|
|
107
|
-
try {
|
|
108
|
-
parseXmlPlist(
|
|
109
|
-
'<?xml version="1.0"?><plist><dict><key>test</key><string>value</string></dict>',
|
|
110
|
-
);
|
|
111
|
-
expect.fail('Should have thrown an error for malformed tags');
|
|
112
|
-
} catch (error) {
|
|
113
|
-
expect(error).to.exist;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
describe('Complex XML Structures', function () {
|
|
119
|
-
it('should parse nested dictionaries correctly', function () {
|
|
120
|
-
const xml = `
|
|
121
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
122
|
-
<plist version="1.0">
|
|
123
|
-
<dict>
|
|
124
|
-
<key>level1</key>
|
|
125
|
-
<dict>
|
|
126
|
-
<key>level2</key>
|
|
127
|
-
<dict>
|
|
128
|
-
<key>level3</key>
|
|
129
|
-
<string>deep value</string>
|
|
130
|
-
</dict>
|
|
131
|
-
</dict>
|
|
132
|
-
</dict>
|
|
133
|
-
</plist>
|
|
134
|
-
`;
|
|
135
|
-
|
|
136
|
-
const result = parseXmlPlist(xml);
|
|
137
|
-
expect(result).to.have.property('level1');
|
|
138
|
-
|
|
139
|
-
// Type assertions for nested properties
|
|
140
|
-
const level1 = result.level1 as PlistDictionary;
|
|
141
|
-
expect(level1).to.have.property('level2');
|
|
142
|
-
|
|
143
|
-
const level2 = level1.level2 as PlistDictionary;
|
|
144
|
-
expect(level2).to.have.property('level3', 'deep value');
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it('should parse mixed arrays and dictionaries', function () {
|
|
148
|
-
const xml = `
|
|
149
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
150
|
-
<plist version="1.0">
|
|
151
|
-
<dict>
|
|
152
|
-
<key>mixedArray</key>
|
|
153
|
-
<array>
|
|
154
|
-
<string>text</string>
|
|
155
|
-
<integer>123</integer>
|
|
156
|
-
<dict>
|
|
157
|
-
<key>nestedKey</key>
|
|
158
|
-
<string>nestedValue</string>
|
|
159
|
-
</dict>
|
|
160
|
-
</array>
|
|
161
|
-
</dict>
|
|
162
|
-
</plist>
|
|
163
|
-
`;
|
|
164
|
-
|
|
165
|
-
const result = parseXmlPlist(xml);
|
|
166
|
-
expect(result).to.have.property('mixedArray').that.is.an('array');
|
|
167
|
-
|
|
168
|
-
// Type assertion for array
|
|
169
|
-
const mixedArray = result.mixedArray as PlistArray;
|
|
170
|
-
expect(mixedArray).to.have.lengthOf(3);
|
|
171
|
-
expect(mixedArray[0]).to.equal('text');
|
|
172
|
-
expect(mixedArray[1]).to.equal(123);
|
|
173
|
-
|
|
174
|
-
// Type assertion for nested object in array
|
|
175
|
-
const nestedObj = mixedArray[2] as PlistDictionary;
|
|
176
|
-
expect(nestedObj).to.have.property('nestedKey', 'nestedValue');
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('should handle XML with comments', function () {
|
|
180
|
-
const xml = `
|
|
181
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
182
|
-
<plist version="1.0">
|
|
183
|
-
<dict>
|
|
184
|
-
<!-- This is a comment -->
|
|
185
|
-
<key>commentedKey</key>
|
|
186
|
-
<string>value</string>
|
|
187
|
-
</dict>
|
|
188
|
-
</plist>
|
|
189
|
-
`;
|
|
190
|
-
|
|
191
|
-
const result = parseXmlPlist(xml);
|
|
192
|
-
expect(result).to.have.property('commentedKey', 'value');
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it('should handle XML with CDATA sections', function () {
|
|
196
|
-
const xml = `
|
|
197
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
198
|
-
<plist version="1.0">
|
|
199
|
-
<dict>
|
|
200
|
-
<key>cdataKey</key>
|
|
201
|
-
<string><![CDATA[<html>This is HTML content</html>]]></string>
|
|
202
|
-
</dict>
|
|
203
|
-
</plist>
|
|
204
|
-
`;
|
|
205
|
-
|
|
206
|
-
const result = parseXmlPlist(xml);
|
|
207
|
-
expect(result).to.have.property(
|
|
208
|
-
'cdataKey',
|
|
209
|
-
'<html>This is HTML content</html>',
|
|
210
|
-
);
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
describe('Special Data Types', function () {
|
|
215
|
-
it('should parse date values correctly', function () {
|
|
216
|
-
const xml = `
|
|
217
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
218
|
-
<plist version="1.0">
|
|
219
|
-
<dict>
|
|
220
|
-
<key>dateKey</key>
|
|
221
|
-
<date>2023-05-21T12:34:56Z</date>
|
|
222
|
-
</dict>
|
|
223
|
-
</plist>
|
|
224
|
-
`;
|
|
225
|
-
|
|
226
|
-
const result = parseXmlPlist(xml);
|
|
227
|
-
expect(result).to.have.property('dateKey');
|
|
228
|
-
|
|
229
|
-
// Type assertion for date
|
|
230
|
-
const dateValue = result.dateKey as Date;
|
|
231
|
-
expect(dateValue).to.be.instanceOf(Date);
|
|
232
|
-
expect(dateValue.toISOString()).to.equal('2023-05-21T12:34:56.000Z');
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it('should parse data values correctly', function () {
|
|
236
|
-
const xml = `
|
|
237
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
238
|
-
<plist version="1.0">
|
|
239
|
-
<dict>
|
|
240
|
-
<key>dataKey</key>
|
|
241
|
-
<data>SGVsbG8gV29ybGQ=</data>
|
|
242
|
-
</dict>
|
|
243
|
-
</plist>
|
|
244
|
-
`;
|
|
245
|
-
|
|
246
|
-
const result = parseXmlPlist(xml);
|
|
247
|
-
expect(result).to.have.property('dataKey');
|
|
248
|
-
|
|
249
|
-
// Type assertion for buffer
|
|
250
|
-
const dataValue = result.dataKey as Buffer;
|
|
251
|
-
expect(Buffer.isBuffer(dataValue)).to.be.true;
|
|
252
|
-
expect(dataValue.toString()).to.equal('Hello World');
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('should handle empty elements correctly', function () {
|
|
256
|
-
const xml = `
|
|
257
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
258
|
-
<plist version="1.0">
|
|
259
|
-
<dict>
|
|
260
|
-
<key>emptyString</key>
|
|
261
|
-
<string></string>
|
|
262
|
-
<key>emptyArray</key>
|
|
263
|
-
<array></array>
|
|
264
|
-
<key>emptyDict</key>
|
|
265
|
-
<dict></dict>
|
|
266
|
-
</dict>
|
|
267
|
-
</plist>
|
|
268
|
-
`;
|
|
269
|
-
|
|
270
|
-
const result = parseXmlPlist(xml);
|
|
271
|
-
expect(result).to.have.property('emptyString', '');
|
|
272
|
-
expect(result)
|
|
273
|
-
.to.have.property('emptyArray')
|
|
274
|
-
.that.is.an('array')
|
|
275
|
-
.with.lengthOf(0);
|
|
276
|
-
expect(result).to.have.property('emptyDict').that.is.an('object');
|
|
277
|
-
|
|
278
|
-
// Type assertion for empty dictionary
|
|
279
|
-
const emptyDict = result.emptyDict as PlistDictionary;
|
|
280
|
-
expect(Object.keys(emptyDict)).to.have.lengthOf(0);
|
|
281
|
-
});
|
|
282
|
-
});
|
|
283
|
-
});
|