simctl 1.2.3 → 1.3.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/Gemfile.lock +1 -1
- data/lib/simctl/command/create.rb +2 -0
- data/lib/simctl/command/delete.rb +12 -0
- data/lib/simctl/command/launch.rb +7 -2
- data/lib/simctl/device.rb +32 -7
- data/lib/simctl/device_path.rb +21 -0
- data/lib/simctl/device_type.rb +2 -0
- data/lib/simctl/executor.rb +4 -8
- data/lib/simctl/runtime.rb +2 -0
- data/lib/simctl/version.rb +1 -1
- data/test/simctl/command/crud_test.rb +65 -53
- data/test/simctl/command/list_test.rb +12 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dfe7554bf2998c41f884105ec70bc6a4dee155a
|
4
|
+
data.tar.gz: b96a52ae6049709614ded55bc6038afc9ed23ed5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8864a6e8fc2d0d5106bd9c1baad25225a8f6ce3bd9141ab2226d0b809d2ba5648c155da99681d4de21fcfa01c851710d72118715534198125d861a635fa810cb
|
7
|
+
data.tar.gz: b4541558026993c78934f76ae571648a21f210c7537595070fb5bec80f3961e99d68095e37c7b66ff49e131868e5e5505d3e601e46759b49a08f60cb47bc12f4
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -14,6 +14,8 @@ module SimCtl
|
|
14
14
|
def create_device(name, devicetype, runtime)
|
15
15
|
runtime = runtime(name: runtime) unless runtime.is_a?(Runtime)
|
16
16
|
devicetype = devicetype(name: devicetype) unless devicetype.is_a?(DeviceType)
|
17
|
+
raise "Invalid runtime: #{runtime}" unless runtime.is_a?(Runtime)
|
18
|
+
raise "Invalid devicetype: #{devicetype}" unless devicetype.is_a?(DeviceType)
|
17
19
|
Executor.execute([COMMAND, Shellwords.shellescape(name), devicetype.identifier, runtime.identifier]) do |identifier|
|
18
20
|
device(udid: identifier)
|
19
21
|
end
|
@@ -10,6 +10,18 @@ module SimCtl
|
|
10
10
|
def delete_device(device)
|
11
11
|
Executor.execute([COMMAND, device.udid])
|
12
12
|
end
|
13
|
+
|
14
|
+
# Delete all devices
|
15
|
+
#
|
16
|
+
# @return [SimCtl::List] a list of all deleted SimCtl::Device objects
|
17
|
+
def delete_all_devices
|
18
|
+
list_devices.each do |device|
|
19
|
+
device.kill!
|
20
|
+
device.shutdown! if device.state != :shutdown
|
21
|
+
device.wait! {|d| d.state == :shutdown}
|
22
|
+
device.delete!
|
23
|
+
end
|
24
|
+
end
|
13
25
|
end
|
14
26
|
end
|
15
27
|
end
|
@@ -8,12 +8,17 @@ module SimCtl
|
|
8
8
|
#
|
9
9
|
# @param device [SimCtl::Device] the device to launch
|
10
10
|
# @return [void]
|
11
|
-
def launch_device(device, scale=1.0)
|
11
|
+
def launch_device(device, scale=1.0, opts={})
|
12
12
|
raise "unsupported scale '#{scale}' (supported: #{SUPPORTED_SCALE.join(', ')})" unless SUPPORTED_SCALE.include?(scale)
|
13
13
|
# Launching the same device twice does not work.
|
14
14
|
# Simulator.app would just hang. Solution: Kill first.
|
15
15
|
kill_device(device)
|
16
|
-
|
16
|
+
args = {
|
17
|
+
'-ConnectHardwareKeyboard' => 1,
|
18
|
+
'-CurrentDeviceUDID' => device.udid,
|
19
|
+
"-SimulatorWindowLastScale-#{device.devicetype.identifier}" => scale,
|
20
|
+
}.merge(opts).zip.flatten.join(' ')
|
21
|
+
command = "open -Fgn #{XCODE_HOME}/Applications/Simulator.app --args #{args}"
|
17
22
|
system command
|
18
23
|
end
|
19
24
|
end
|
data/lib/simctl/device.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'cfpropertylist'
|
2
2
|
require 'ostruct'
|
3
|
+
require 'simctl/device_path'
|
3
4
|
require 'simctl/object'
|
4
5
|
require 'timeout'
|
5
6
|
|
@@ -19,6 +20,24 @@ module SimCtl
|
|
19
20
|
@devicetype ||= SimCtl.devicetype(identifier: plist.deviceType)
|
20
21
|
end
|
21
22
|
|
23
|
+
def disable_keyboard_helpers!
|
24
|
+
path.edit path.preferences_plist do |plist|
|
25
|
+
%w(
|
26
|
+
KeyboardPeriodShortcut
|
27
|
+
KeyboardAutocapitalization
|
28
|
+
KeyboardCheckSpelling
|
29
|
+
KeyboardAssistant
|
30
|
+
KeyboardAutocorrection
|
31
|
+
KeyboardPrediction
|
32
|
+
KeyboardShowPredictionBar
|
33
|
+
KeyboardCapsLock
|
34
|
+
).each do |key|
|
35
|
+
plist[key] = false
|
36
|
+
end
|
37
|
+
plist
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
22
41
|
def erase!
|
23
42
|
SimCtl.erase_device(self)
|
24
43
|
end
|
@@ -27,14 +46,22 @@ module SimCtl
|
|
27
46
|
SimCtl.kill_device(self)
|
28
47
|
end
|
29
48
|
|
30
|
-
def launch!(scale=1.0)
|
31
|
-
SimCtl.launch_device(self, scale)
|
49
|
+
def launch!(scale=1.0, opts={})
|
50
|
+
SimCtl.launch_device(self, scale, opts)
|
51
|
+
end
|
52
|
+
|
53
|
+
def path
|
54
|
+
@path ||= DevicePath.new(udid)
|
32
55
|
end
|
33
56
|
|
34
57
|
def rename!(name)
|
35
58
|
SimCtl.rename_device(self, name)
|
36
59
|
end
|
37
60
|
|
61
|
+
def reset!
|
62
|
+
SimCtl.reset_device name, devicetype, runtime
|
63
|
+
end
|
64
|
+
|
38
65
|
def runtime
|
39
66
|
@runtime ||= SimCtl.runtime(identifier: plist.runtime)
|
40
67
|
end
|
@@ -56,17 +83,15 @@ module SimCtl
|
|
56
83
|
end
|
57
84
|
|
58
85
|
def ==(other)
|
86
|
+
return false if other.nil?
|
87
|
+
return false unless other.kind_of? Device
|
59
88
|
other.udid == udid
|
60
89
|
end
|
61
90
|
|
62
91
|
private
|
63
92
|
|
64
93
|
def plist
|
65
|
-
@plist ||= OpenStruct.new(CFPropertyList.native_types(CFPropertyList::List.new(file:
|
66
|
-
end
|
67
|
-
|
68
|
-
def plist_path
|
69
|
-
File.join(ENV['HOME'], 'Library/Developer/CoreSimulator/Devices', udid, 'device.plist')
|
94
|
+
@plist ||= OpenStruct.new(CFPropertyList.native_types(CFPropertyList::List.new(file: path.device_plist).value))
|
70
95
|
end
|
71
96
|
|
72
97
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'simctl/object'
|
2
|
+
|
3
|
+
module SimCtl
|
4
|
+
class DevicePath
|
5
|
+
attr_reader :device_plist, :home, :preferences_plist
|
6
|
+
|
7
|
+
def initialize(udid)
|
8
|
+
@home = File.join(ENV['HOME'], 'Library/Developer/CoreSimulator/Devices', udid)
|
9
|
+
@device_plist = File.join(@home, 'device.plist')
|
10
|
+
@preferences_plist = File.join(@home, 'data/Library/Preferences/com.apple.Preferences.plist')
|
11
|
+
end
|
12
|
+
|
13
|
+
def edit(path, &block)
|
14
|
+
plist = File.exists?(path) ? CFPropertyList::List.new(file: path) : CFPropertyList::List.new
|
15
|
+
content = CFPropertyList.native_types(plist.value) || {}
|
16
|
+
plist.value = CFPropertyList.guess(yield content)
|
17
|
+
plist.save(path, CFPropertyList::List::FORMAT_BINARY)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/simctl/device_type.rb
CHANGED
data/lib/simctl/executor.rb
CHANGED
@@ -10,14 +10,10 @@ module SimCtl
|
|
10
10
|
output = stdout.read
|
11
11
|
raise StandardError.new(output) if result.value.to_i > 0
|
12
12
|
return unless block_given?
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
yield output.chomp
|
18
|
-
end
|
19
|
-
rescue StandardError => e
|
20
|
-
raise StandardError.new("Failed to execute '#{command}' (output: '#{output.chomp}'): #{e}")
|
13
|
+
if looks_like_json?(output)
|
14
|
+
yield JSON.parse(output)
|
15
|
+
else
|
16
|
+
yield output.chomp
|
21
17
|
end
|
22
18
|
end
|
23
19
|
end
|
data/lib/simctl/runtime.rb
CHANGED
data/lib/simctl/version.rb
CHANGED
@@ -2,83 +2,95 @@ require 'securerandom'
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
4
|
class SimCtl::Command::CRUDTest < Minitest::Test
|
5
|
-
|
6
|
-
@devicetype = SimCtl.list_devicetypes.select {|devicetype| devicetype.name =~ %r[iPhone]}.first
|
7
|
-
@runtime = SimCtl.list_runtimes.select {|runtime| runtime.name =~ %r[iOS.*9]}.first
|
8
|
-
@device = SimCtl.create_device SecureRandom.hex, @devicetype, @runtime
|
9
|
-
@device.wait! {|d| d.state != :creating}
|
10
|
-
end
|
5
|
+
order_dependent!
|
11
6
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
device.delete!
|
7
|
+
udid = nil
|
8
|
+
name = SecureRandom.hex
|
9
|
+
devicetype = 'iPhone 5'
|
10
|
+
|
11
|
+
should 'raise exception if devicetype lookup failed' do
|
12
|
+
assert_raises { SimCtl.create_device SecureRandom.hex, 'invalid devicetype', SimCtl::Runtime.latest(:ios) }
|
19
13
|
end
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
# assert device.devicetype == @devicetype
|
25
|
-
# assert device.runtime == @runtime
|
26
|
-
#end
|
15
|
+
should 'raise exception if runtime lookup failed' do
|
16
|
+
assert_raises { SimCtl.create_device name, SimCtl::DeviceType.find(name: devicetype), 'invalid runtime' }
|
17
|
+
end
|
27
18
|
|
28
|
-
should '
|
29
|
-
device = SimCtl.create_device
|
30
|
-
device.wait! {|d| d.state
|
31
|
-
device.
|
19
|
+
should '01. create a new device' do
|
20
|
+
device = SimCtl.create_device name, devicetype, SimCtl::Runtime.latest(:ios)
|
21
|
+
device.wait! {|d| d.state == :shutdown}
|
22
|
+
udid = device.udid
|
32
23
|
end
|
33
24
|
|
34
|
-
should 'find the device
|
35
|
-
device = SimCtl.device(udid:
|
25
|
+
should '02. find the device by udid' do
|
26
|
+
device = SimCtl.device(udid: udid)
|
36
27
|
assert_kind_of SimCtl::Device, device
|
37
28
|
assert device.availability != nil
|
38
|
-
assert device.name
|
29
|
+
assert device.name == name
|
39
30
|
assert device.os != nil
|
40
31
|
assert device.state != nil
|
41
32
|
assert device.udid != nil
|
42
33
|
end
|
43
34
|
|
44
|
-
should '
|
45
|
-
|
46
|
-
|
35
|
+
should '03. find the device by name' do
|
36
|
+
assert SimCtl.device(name: name).udid == udid
|
37
|
+
end
|
38
|
+
|
39
|
+
should '04. have devicetype property' do
|
40
|
+
assert SimCtl.device(udid: udid).devicetype == SimCtl.devicetype(name: devicetype)
|
41
|
+
end
|
42
|
+
|
43
|
+
should '05. have runtime property' do
|
44
|
+
assert SimCtl.device(udid: udid).runtime == SimCtl::Runtime.latest(:ios)
|
45
|
+
end
|
46
|
+
|
47
|
+
should '06. rename the device' do
|
48
|
+
SimCtl.device(udid: udid).rename!('new name')
|
49
|
+
assert SimCtl.device(udid: udid).name == 'new name'
|
50
|
+
end
|
51
|
+
|
52
|
+
should '07. erase the device' do
|
53
|
+
SimCtl.device(udid: udid).erase!
|
54
|
+
end
|
55
|
+
|
56
|
+
should '08. launch the device' do
|
57
|
+
device = SimCtl.device(udid: udid)
|
58
|
+
device.launch!
|
47
59
|
device.wait!{|d| d.state == :booted}
|
48
|
-
assert device.kill!
|
49
|
-
device.wait!{|d| d.state == :shutdown}
|
50
60
|
end
|
51
61
|
|
52
|
-
should '
|
53
|
-
device = SimCtl.device(udid:
|
54
|
-
device.
|
62
|
+
should '09. kill the device' do
|
63
|
+
device = SimCtl.device(udid: udid)
|
64
|
+
assert device.kill!
|
65
|
+
device.wait!{|d| d.state == :shutdown}
|
55
66
|
end
|
56
67
|
|
57
|
-
should 'boot
|
58
|
-
device = SimCtl.device(udid:
|
68
|
+
should '10. boot the device' do
|
69
|
+
device = SimCtl.device(udid: udid)
|
59
70
|
device.boot!
|
60
|
-
device.wait!
|
61
|
-
device.shutdown!
|
62
|
-
device.wait! {|d| d.state == :shutdown}
|
71
|
+
device.wait!{|d| d.state == :booted}
|
63
72
|
end
|
64
73
|
|
65
|
-
should '
|
66
|
-
device = SimCtl.device(udid:
|
67
|
-
|
68
|
-
|
74
|
+
should '11. shutdown the device' do
|
75
|
+
device = SimCtl.device(udid: udid)
|
76
|
+
device.shutdown!
|
77
|
+
device.wait!{|d| d.state == :shutdown}
|
69
78
|
end
|
70
79
|
|
71
|
-
should '
|
72
|
-
|
73
|
-
|
74
|
-
|
80
|
+
should '12. reset the device' do
|
81
|
+
old_device = SimCtl.device(udid: udid)
|
82
|
+
new_device = SimCtl.reset_device old_device.name, old_device.devicetype, old_device.runtime
|
83
|
+
new_device.wait!{|d| d.state != :creating}
|
84
|
+
assert old_device.name == new_device.name
|
85
|
+
assert old_device.devicetype == new_device.devicetype
|
86
|
+
assert old_device.runtime == new_device.runtime
|
87
|
+
assert old_device.udid != new_device.udid
|
88
|
+
udid = new_device.udid
|
75
89
|
end
|
76
90
|
|
77
|
-
should '
|
78
|
-
device = SimCtl.
|
79
|
-
|
80
|
-
assert_nil SimCtl.device(udid:
|
81
|
-
@device = device # teardown cleanup
|
82
|
-
device.wait! {|d| d.state != :creating}
|
91
|
+
should '13. delete the device' do
|
92
|
+
device = SimCtl.device(udid: udid)
|
93
|
+
device.delete!
|
94
|
+
assert_nil SimCtl.device(udid: udid)
|
83
95
|
end
|
84
96
|
end
|
@@ -49,6 +49,18 @@ class SimCtl::Command::ListTest < Minitest::Test
|
|
49
49
|
should 'parse name property' do
|
50
50
|
assert SimCtl.list_runtimes.first.name != nil
|
51
51
|
end
|
52
|
+
|
53
|
+
should 'return latest ios runtime' do
|
54
|
+
assert_kind_of SimCtl::Runtime, SimCtl::Runtime.latest(:ios)
|
55
|
+
end
|
56
|
+
|
57
|
+
should 'return latest tvos runtime' do
|
58
|
+
assert_kind_of SimCtl::Runtime, SimCtl::Runtime.latest(:tvos)
|
59
|
+
end
|
60
|
+
|
61
|
+
should 'return latest watchos runtime' do
|
62
|
+
assert_kind_of SimCtl::Runtime, SimCtl::Runtime.latest(:watchos)
|
63
|
+
end
|
52
64
|
end
|
53
65
|
|
54
66
|
context 'runtime' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simctl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johannes Plunien
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- lib/simctl/command/reset.rb
|
109
109
|
- lib/simctl/command/shutdown.rb
|
110
110
|
- lib/simctl/device.rb
|
111
|
+
- lib/simctl/device_path.rb
|
111
112
|
- lib/simctl/device_type.rb
|
112
113
|
- lib/simctl/executor.rb
|
113
114
|
- lib/simctl/list.rb
|