From c61f3ffb9da83ef82e1b1bbde17dfaffb99a45bf Mon Sep 17 00:00:00 2001 From: Erisu Date: Wed, 19 Nov 2025 02:21:47 +0900 Subject: [PATCH] feat: add pair and unpair support --- simctl.js | 8 +++++++ test/simctl.js | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/simctl.js b/simctl.js index 89e2cc2..a2904ea 100644 --- a/simctl.js +++ b/simctl.js @@ -173,5 +173,13 @@ module.exports = { } else { return spawnSync('xcrun', ['simctl', 'help']) } + }, + + pair: function (watchDevice, phoneDevice) { + return spawnSync('xcrun', ['simctl', 'pair', watchDevice, phoneDevice]) + }, + + unpair: function (pairUUID) { + return spawnSync('xcrun', ['simctl', 'unpair', pairUUID]) } } diff --git a/test/simctl.js b/test/simctl.js index 8f8835e..1115194 100644 --- a/test/simctl.js +++ b/test/simctl.js @@ -54,6 +54,8 @@ test('exports', (t) => { t.assert.equal(typeof simctl.icloud_sync, 'function') t.assert.equal(typeof simctl.create, 'function') t.assert.equal(typeof simctl.help, 'function') + t.assert.equal(typeof simctl.pair, 'function') + t.assert.equal(typeof simctl.unpair, 'function') }) test('check_prerequisites fail', (t) => { @@ -208,3 +210,59 @@ test('simctl help', async (ctx) => { t.assert.deepEqual(spawnMock.mock.calls[0].arguments[1], ['simctl', 'help', 'launch']) }) }) + +test('simctl pair', async (ctx) => { + ctx.beforeEach((t) => { + spawnMock.mock.resetCalls() + }) + + await ctx.test('with no arguments', (t) => { + t.assert ||= require('node:assert') + + spawnMock.mock.mockImplementationOnce(() => { + return { status: 0, stdout: '' } + }) + + simctl.pair() + t.assert.deepEqual(spawnMock.mock.calls[0].arguments[1], ['simctl', 'pair', undefined, undefined]) + }) + + await ctx.test('with fake watchDevice & phoneDevice', (t) => { + t.assert ||= require('node:assert') + + spawnMock.mock.mockImplementationOnce(() => { + return { status: 0, stdout: '' } + }) + + simctl.pair('foobarWatch', 'foobarPhone') + t.assert.deepEqual(spawnMock.mock.calls[0].arguments[1], ['simctl', 'pair', 'foobarWatch', 'foobarPhone']) + }) +}) + +test('simctl unpair', async (ctx) => { + ctx.beforeEach((t) => { + spawnMock.mock.resetCalls() + }) + + await ctx.test('with no arguments', (t) => { + t.assert ||= require('node:assert') + + spawnMock.mock.mockImplementationOnce(() => { + return { status: 0, stdout: '' } + }) + + simctl.unpair() + t.assert.deepEqual(spawnMock.mock.calls[0].arguments[1], ['simctl', 'unpair', undefined]) + }) + + await ctx.test('with fake deviceUUID', (t) => { + t.assert ||= require('node:assert') + + spawnMock.mock.mockImplementationOnce(() => { + return { status: 0, stdout: '' } + }) + + simctl.unpair('foobar') + t.assert.deepEqual(spawnMock.mock.calls[0].arguments[1], ['simctl', 'unpair', 'foobar']) + }) +})