simctl 0.1.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 +7 -0
- data/.gitignore +2 -0
- data/.travis.yml +8 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +22 -0
- data/LICENSE +20 -0
- data/README.md +144 -0
- data/Rakefile +13 -0
- data/lib/simctl.rb +27 -0
- data/lib/simctl/command.rb +18 -0
- data/lib/simctl/command/boot.rb +14 -0
- data/lib/simctl/command/create.rb +18 -0
- data/lib/simctl/command/delete.rb +14 -0
- data/lib/simctl/command/erase.rb +16 -0
- data/lib/simctl/command/list.rb +59 -0
- data/lib/simctl/command/shutdown.rb +14 -0
- data/lib/simctl/device.rb +27 -0
- data/lib/simctl/device_type.rb +7 -0
- data/lib/simctl/executor.rb +28 -0
- data/lib/simctl/list.rb +20 -0
- data/lib/simctl/object.rb +9 -0
- data/lib/simctl/runtime.rb +7 -0
- data/lib/simctl/version.rb +3 -0
- data/simctl.gemspec +24 -0
- data/test/simctl/command/crud_test.rb +55 -0
- data/test/simctl/command/list_test.rb +47 -0
- data/test/test_helper.rb +5 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0bb277e12e4ce8fc175ae3aa9e2f6409df2f9452
|
4
|
+
data.tar.gz: 21f532425ac401ea95dde484af341f2f4d8231db
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8d0400e3c768b6f7dac83a7c4cc7195daa71eca447630410c753c4e19016f29878ef1e59de51dda28eb2e7e89ffa01bf4602167cbbd1ff2352326656e736b766
|
7
|
+
data.tar.gz: ac9fd2b3fed5f8652dc3fbf2d1cde044fb98f0e6cebe36a83e8f91847c1f8e17f5a6c98e9e04234243ffb1db158f9957831df4b57aaf5fb2efc64593e6ef041c
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
simctl (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
maxitest (1.5.4)
|
10
|
+
minitest (>= 5.0.0, < 5.9.0)
|
11
|
+
minitest (5.8.3)
|
12
|
+
rake (10.4.2)
|
13
|
+
shoulda-context (1.2.1)
|
14
|
+
|
15
|
+
PLATFORMS
|
16
|
+
ruby
|
17
|
+
|
18
|
+
DEPENDENCIES
|
19
|
+
maxitest
|
20
|
+
rake
|
21
|
+
shoulda-context
|
22
|
+
simctl!
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Johannes Plunien
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
# simctl
|
2
|
+
|
3
|
+
[](https://travis-ci.org/plu/simctl)
|
4
|
+
|
5
|
+
Ruby interface to xcrun simctl.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Via [bundler](http://getbundler.com)
|
10
|
+
|
11
|
+
```sh
|
12
|
+
# in your Gemfile
|
13
|
+
gem 'simctl'
|
14
|
+
```
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
### boot_device
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
device = SimCtl.device(name: 'my iphone 5', state: 'Shutdown')
|
22
|
+
SimCtl.boot_device(device)
|
23
|
+
|
24
|
+
# or:
|
25
|
+
|
26
|
+
SimCtl.device(name: 'my iphone 5', state: 'Shutdown').boot!
|
27
|
+
```
|
28
|
+
|
29
|
+
### create_device
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
SimCtl.create_device 'my iphone 5', SimCtl.devicetype(name: 'iPhone 5'), SimCtl.runtime(name: 'iOS 9.2')
|
33
|
+
|
34
|
+
#<SimCtl::Device:0x007fbce48afd88 @state="Creating", @availability="(available)", @name="my iphone 5", @udid="6F7269E0-6375-4B72-8451-F2728BF6DA82", @os="iOS 9.2">
|
35
|
+
```
|
36
|
+
|
37
|
+
### delete_device
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
device = SimCtl.device(name: 'my iphone 5', state: 'Booted')
|
41
|
+
SimCtl.delete_device(device)
|
42
|
+
|
43
|
+
# or:
|
44
|
+
|
45
|
+
SimCtl.device(name: 'my iphone 5', state: 'Booted').delete!
|
46
|
+
```
|
47
|
+
|
48
|
+
### devicetype
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
SimCtl.devicetype(name: 'iPhone 5')
|
52
|
+
|
53
|
+
#<SimCtl::DeviceType:0x007fd90dd9f2e0 @name="iPhone 5", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-5">
|
54
|
+
```
|
55
|
+
|
56
|
+
### device
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
SimCtl.device(name: 'my iphone 5', state: 'Booted')
|
60
|
+
|
61
|
+
#<SimCtl::Device:0x007fd90dcce910 @state="Booted", @availability="(available)", @name="my iphone 5", @udid="6F7269E0-6375-4B72-8451-F2728BF6DA82", @os="iOS 9.2">
|
62
|
+
```
|
63
|
+
|
64
|
+
### erase_device
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
device = SimCtl.device(name: 'my iphone 5', state: 'Booted')
|
68
|
+
SimCtl.erase_device(device)
|
69
|
+
|
70
|
+
# or:
|
71
|
+
|
72
|
+
SimCtl.device(name: 'my iphone 5', state: 'Booted').erase!
|
73
|
+
```
|
74
|
+
|
75
|
+
### list_devices
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
SimCtl.list_devices.each do |device|
|
79
|
+
puts device.inspect
|
80
|
+
end
|
81
|
+
|
82
|
+
#<SimCtl::Device:0x007fd90dd06f90 @state="Booted", @availability="(available)", @name="iPhone 5", @udid="25AC234A-EB91-46EF-9BCB-B7405813EF93", @os="iOS 9.2">
|
83
|
+
#<SimCtl::Device:0x007fd90dd06e00 @state="Shutdown", @availability="(available)", @name="iPhone 5", @udid="CEFEDED6-94C0-4B6B-8ABC-B855C49F06B0", @os="iOS 9.2">
|
84
|
+
```
|
85
|
+
|
86
|
+
### list_devicetypes
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
SimCtl.list_devicetypes.each do |devicetype|
|
90
|
+
puts devicetype.inspect
|
91
|
+
end
|
92
|
+
|
93
|
+
#<SimCtl::DeviceType:0x007fbce48f5270 @name="iPhone 4s", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-4s">
|
94
|
+
#<SimCtl::DeviceType:0x007fbce48f51f8 @name="iPhone 5", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-5">
|
95
|
+
#<SimCtl::DeviceType:0x007fbce48f5180 @name="iPhone 5s", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-5s">
|
96
|
+
#<SimCtl::DeviceType:0x007fbce48f5108 @name="iPhone 6", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-6">
|
97
|
+
#<SimCtl::DeviceType:0x007fbce48f5090 @name="iPhone 6 Plus", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus">
|
98
|
+
#<SimCtl::DeviceType:0x007fbce48f5018 @name="iPhone 6s", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-6s">
|
99
|
+
#<SimCtl::DeviceType:0x007fbce48f4fa0 @name="iPhone 6s Plus", @identifier="com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus">
|
100
|
+
#<SimCtl::DeviceType:0x007fbce48f4f28 @name="iPad 2", @identifier="com.apple.CoreSimulator.SimDeviceType.iPad-2">
|
101
|
+
#<SimCtl::DeviceType:0x007fbce48f4eb0 @name="iPad Retina", @identifier="com.apple.CoreSimulator.SimDeviceType.iPad-Retina">
|
102
|
+
#<SimCtl::DeviceType:0x007fbce48f4e38 @name="iPad Air", @identifier="com.apple.CoreSimulator.SimDeviceType.iPad-Air">
|
103
|
+
#<SimCtl::DeviceType:0x007fbce48f4dc0 @name="iPad Air 2", @identifier="com.apple.CoreSimulator.SimDeviceType.iPad-Air-2">
|
104
|
+
#<SimCtl::DeviceType:0x007fbce48f4d48 @name="iPad Pro", @identifier="com.apple.CoreSimulator.SimDeviceType.iPad-Pro">
|
105
|
+
#<SimCtl::DeviceType:0x007fbce48f4cd0 @name="Apple TV 1080p", @identifier="com.apple.CoreSimulator.SimDeviceType.Apple-TV-1080p">
|
106
|
+
#<SimCtl::DeviceType:0x007fbce48f4c58 @name="Apple Watch - 38mm", @identifier="com.apple.CoreSimulator.SimDeviceType.Apple-Watch-38mm">
|
107
|
+
#<SimCtl::DeviceType:0x007fbce48f4be0 @name="Apple Watch - 42mm", @identifier="com.apple.CoreSimulator.SimDeviceType.Apple-Watch-42mm">
|
108
|
+
```
|
109
|
+
|
110
|
+
### list_runtimes
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
SimCtl.list_runtimes.each do |runtime|
|
114
|
+
puts runtime.inspect
|
115
|
+
end
|
116
|
+
|
117
|
+
#<SimCtl::Runtime:0x007fbce48cd6d0 @buildversion="12B411", @availability="(available)", @name="iOS 8.1", @identifier="com.apple.CoreSimulator.SimRuntime.iOS-8-1", @version="8.1">
|
118
|
+
#<SimCtl::Runtime:0x007fbce48cd5e0 @buildversion="12D508", @availability="(available)", @name="iOS 8.2", @identifier="com.apple.CoreSimulator.SimRuntime.iOS-8-2", @version="8.2">
|
119
|
+
#<SimCtl::Runtime:0x007fbce48cd4f0 @buildversion="12F70", @availability="(available)", @name="iOS 8.3", @identifier="com.apple.CoreSimulator.SimRuntime.iOS-8-3", @version="8.3">
|
120
|
+
#<SimCtl::Runtime:0x007fbce48cd400 @buildversion="12H141", @availability="(available)", @name="iOS 8.4", @identifier="com.apple.CoreSimulator.SimRuntime.iOS-8-4", @version="8.4">
|
121
|
+
#<SimCtl::Runtime:0x007fbce48cd310 @buildversion="13A344", @availability="(available)", @name="iOS 9.0", @identifier="com.apple.CoreSimulator.SimRuntime.iOS-9-0", @version="9.0">
|
122
|
+
#<SimCtl::Runtime:0x007fbce48cd220 @buildversion="13C75", @availability="(available)", @name="iOS 9.2", @identifier="com.apple.CoreSimulator.SimRuntime.iOS-9-2", @version="9.2">
|
123
|
+
#<SimCtl::Runtime:0x007fbce48cd130 @buildversion="13U78", @availability="(available)", @name="tvOS 9.1", @identifier="com.apple.CoreSimulator.SimRuntime.tvOS-9-1", @version="9.1">
|
124
|
+
#<SimCtl::Runtime:0x007fbce48cd040 @buildversion="13S660", @availability="(available)", @name="watchOS 2.1", @identifier="com.apple.CoreSimulator.SimRuntime.watchOS-2-1", @version="2.1">
|
125
|
+
```
|
126
|
+
|
127
|
+
### runtime
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
SimCtl.runtime(name: 'iOS 9.2')
|
131
|
+
|
132
|
+
#<SimCtl::Runtime:0x007fd90dd2da28 @buildversion="13C75", @availability="(available)", @name="iOS 9.2", @identifier="com.apple.CoreSimulator.SimRuntime.iOS-9-2", @version="9.2">
|
133
|
+
```
|
134
|
+
|
135
|
+
### shutdown_device
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
device = SimCtl.device(name: 'my iphone 5', state: 'Booted')
|
139
|
+
SimCtl.shutdown_device(device)
|
140
|
+
|
141
|
+
# or:
|
142
|
+
|
143
|
+
SimCtl.device(name: 'my iphone 5', state: 'Booted').shutdown!
|
144
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
desc 'Execute simctl tests'
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << 'lib' << 'test'
|
8
|
+
t.pattern = 'test/**/*_test.rb'
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'Default: Execute simctl tests'
|
13
|
+
task default: :test
|
data/lib/simctl.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'simctl/command'
|
2
|
+
require 'simctl/device'
|
3
|
+
require 'simctl/device_type'
|
4
|
+
require 'simctl/list'
|
5
|
+
require 'simctl/runtime'
|
6
|
+
|
7
|
+
module SimCtl
|
8
|
+
class << self
|
9
|
+
def command
|
10
|
+
return @command if defined?(@command)
|
11
|
+
@command = SimCtl::Command.new
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def respond_to_missing?(method_name, include_private=false)
|
17
|
+
command.respond_to?(method_name, include_private)
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(method_name, *args, &block)
|
21
|
+
if command.respond_to?(method_name)
|
22
|
+
return command.send(method_name, *args, &block)
|
23
|
+
end
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'simctl/command/boot'
|
2
|
+
require 'simctl/command/create'
|
3
|
+
require 'simctl/command/delete'
|
4
|
+
require 'simctl/command/erase'
|
5
|
+
require 'simctl/command/list'
|
6
|
+
require 'simctl/command/shutdown'
|
7
|
+
require 'simctl/executor'
|
8
|
+
|
9
|
+
module SimCtl
|
10
|
+
class Command
|
11
|
+
include SimCtl::Command::Boot
|
12
|
+
include SimCtl::Command::Create
|
13
|
+
include SimCtl::Command::Delete
|
14
|
+
include SimCtl::Command::Erase
|
15
|
+
include SimCtl::Command::List
|
16
|
+
include SimCtl::Command::Shutdown
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SimCtl
|
2
|
+
class Command
|
3
|
+
module Boot
|
4
|
+
COMMAND = %w[xcrun simctl boot]
|
5
|
+
|
6
|
+
# Boots a device
|
7
|
+
#
|
8
|
+
# @param device [SimCtl::Device] the device to boot
|
9
|
+
def boot_device(device)
|
10
|
+
Executor.execute([COMMAND, device.udid])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SimCtl
|
2
|
+
class Command
|
3
|
+
module Create
|
4
|
+
COMMAND = %w[xcrun simctl create]
|
5
|
+
|
6
|
+
# Creates a device
|
7
|
+
#
|
8
|
+
# @param name [String] name of the new device
|
9
|
+
# @param device_type [SimCtl::DeviceTYpe] device type of the new device
|
10
|
+
# @param runtime [SimCtl::Runtime] runtime of the new device
|
11
|
+
def create_device(name, device_type, runtime)
|
12
|
+
Executor.execute([COMMAND, "'#{name}'", device_type.identifier, runtime.identifier]) do |identifier|
|
13
|
+
device(udid: identifier)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SimCtl
|
2
|
+
class Command
|
3
|
+
module Delete
|
4
|
+
COMMAND = %w[xcrun simctl delete]
|
5
|
+
|
6
|
+
# Delete a device
|
7
|
+
#
|
8
|
+
# @param device [SimCtl::Device] the device to delete
|
9
|
+
def delete_device(device)
|
10
|
+
Executor.execute([COMMAND, device.udid])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SimCtl
|
2
|
+
class Command
|
3
|
+
module Erase
|
4
|
+
COMMAND = %w[xcrun simctl erase]
|
5
|
+
|
6
|
+
# Erase a device
|
7
|
+
#
|
8
|
+
# @param device [SimCtl::Device] the device to erase
|
9
|
+
def erase_device(device)
|
10
|
+
Executor.execute([COMMAND, device.udid])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SimCtl
|
2
|
+
class Command
|
3
|
+
module List
|
4
|
+
COMMAND = %w[xcrun simctl list -j]
|
5
|
+
|
6
|
+
# Find a device
|
7
|
+
#
|
8
|
+
# @param filter [Hash] the filter
|
9
|
+
# @return [SimCtl::Device, nil] the device matching the given filter
|
10
|
+
def device(filter)
|
11
|
+
list_devices.where(filter).first
|
12
|
+
end
|
13
|
+
|
14
|
+
# Find a device type
|
15
|
+
#
|
16
|
+
# @param filter [Hash] the filter
|
17
|
+
# @return [SimCtl::DeviceType, nil] the device type matching the given filter
|
18
|
+
def devicetype(filter)
|
19
|
+
list_devicetypes.where(filter).first
|
20
|
+
end
|
21
|
+
|
22
|
+
# List all devices
|
23
|
+
#
|
24
|
+
# @return [SimCtl::List] a list of SimCtl::Device objects
|
25
|
+
def list_devices
|
26
|
+
Executor.execute([COMMAND, 'devices']) do |json|
|
27
|
+
SimCtl::List.new(json['devices'].map {|os, devices| devices.map {|device| Device.new(device.merge(os: os))}}.flatten)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# List all device types
|
32
|
+
#
|
33
|
+
# @return [SimCtl::List] a list of SimCtl::DeviceType objects
|
34
|
+
def list_devicetypes
|
35
|
+
Executor.execute([COMMAND, 'devicetypes']) do |json|
|
36
|
+
SimCtl::List.new(json['devicetypes'].map {|devicetype| DeviceType.new(devicetype)})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# List all runtimes
|
41
|
+
#
|
42
|
+
# @return [SimCtl::List] a list of SimCtl::Runtime objects
|
43
|
+
def list_runtimes
|
44
|
+
Executor.execute([COMMAND, 'runtimes']) do |json|
|
45
|
+
SimCtl::List.new(json['runtimes'].map {|runtime| Runtime.new(runtime)})
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Find a runtime
|
50
|
+
#
|
51
|
+
# @param filter [Hash] the filter
|
52
|
+
# @return [SimCtl::Runtime, nil] the runtime matching the given filter
|
53
|
+
def runtime(filter)
|
54
|
+
list_runtimes.where(filter).first
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SimCtl
|
2
|
+
class Command
|
3
|
+
module Shutdown
|
4
|
+
COMMAND = %w[xcrun simctl shutdown]
|
5
|
+
|
6
|
+
# Shutdown a device
|
7
|
+
#
|
8
|
+
# @param device [SimCtl::Device] the device to shutdown
|
9
|
+
def shutdown_device(device)
|
10
|
+
Executor.execute([COMMAND, device.udid])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'simctl/object'
|
2
|
+
|
3
|
+
module SimCtl
|
4
|
+
class Device < Object
|
5
|
+
attr_reader :availability, :name, :os, :state, :udid
|
6
|
+
|
7
|
+
# Boot the device
|
8
|
+
def boot!
|
9
|
+
SimCtl.boot_device(self)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Delete the device
|
13
|
+
def delete!
|
14
|
+
SimCtl.delete_device(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Erase the device
|
18
|
+
def erase!
|
19
|
+
SimCtl.erase_device(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Shutdown the device
|
23
|
+
def shutdown!
|
24
|
+
SimCtl.shutdown_device(self)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module SimCtl
|
5
|
+
class Executor
|
6
|
+
class << self
|
7
|
+
def execute(command)
|
8
|
+
command = command.flatten.join(' ')
|
9
|
+
Open3.popen2e(command) do |_, io, result|
|
10
|
+
output = io.read
|
11
|
+
raise StandardError.new(output) if result.value.to_i > 0
|
12
|
+
return unless block_given?
|
13
|
+
if looks_like_json?(output)
|
14
|
+
yield JSON.parse(output)
|
15
|
+
else
|
16
|
+
yield output.chomp
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def looks_like_json?(output)
|
24
|
+
output.start_with?('[') || output.start_with?('{')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/simctl/list.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module SimCtl
|
2
|
+
class List < Array
|
3
|
+
# Filters an array of objects by a given hash. The keys of
|
4
|
+
# the hash must be methods implemented by the objects. The
|
5
|
+
# values of the hash are compared to the values the object
|
6
|
+
# returns when calling the methods.
|
7
|
+
#
|
8
|
+
# @param filter [Hash] the filters that should be applied
|
9
|
+
# @return [Array] the filtered array.
|
10
|
+
def where(filter)
|
11
|
+
select do |item|
|
12
|
+
matches = true
|
13
|
+
filter.each do |key, value|
|
14
|
+
matches &= item.send(key) == value
|
15
|
+
end
|
16
|
+
matches
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/simctl.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
3
|
+
require 'simctl/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'simctl'
|
7
|
+
s.version = SimCtl::VERSION
|
8
|
+
s.summary = 'Ruby interface to xcrun simctl'
|
9
|
+
s.description = 'Ruby interface to xcrun simctl'
|
10
|
+
|
11
|
+
s.authors = ['Johannes Plunien']
|
12
|
+
s.email = %w(plu@pqpq.de)
|
13
|
+
s.homepage = 'https://github.com/plu/simctl'
|
14
|
+
s.licenses = ['MIT']
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_development_dependency 'rake'
|
22
|
+
s.add_development_dependency 'maxitest'
|
23
|
+
s.add_development_dependency 'shoulda-context'
|
24
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'test_helper'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
class SimCtl::Command::CRUDTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@devicetype = SimCtl.list_devicetypes.select {|devicetype| devicetype.name =~ %r[iPhone]}.first
|
8
|
+
@runtime = SimCtl.list_runtimes.select {|runtime| runtime.name =~ %r[iOS.*9]}.first
|
9
|
+
@device = SimCtl.create_device SecureRandom.hex, @devicetype, @runtime
|
10
|
+
wait_for {|device| device.state != 'Creating'}
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
device = SimCtl.device(udid: @device.udid)
|
15
|
+
SimCtl.delete_device device if device
|
16
|
+
end
|
17
|
+
|
18
|
+
def wait_for
|
19
|
+
Timeout::timeout(30) do
|
20
|
+
loop do
|
21
|
+
device = SimCtl.device(udid: @device.udid)
|
22
|
+
break if yield device
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'find the device created in setup' do
|
28
|
+
device = SimCtl.device(udid: @device.udid)
|
29
|
+
assert_kind_of SimCtl::Device, device
|
30
|
+
assert device.availability != nil
|
31
|
+
assert device.name != nil
|
32
|
+
assert device.os != nil
|
33
|
+
assert device.state != nil
|
34
|
+
assert device.udid != nil
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'erase the device created in setup' do
|
38
|
+
device = SimCtl.device(udid: @device.udid)
|
39
|
+
SimCtl.erase_device device
|
40
|
+
end
|
41
|
+
|
42
|
+
should 'boot/shutdown the device created in setup' do
|
43
|
+
device = SimCtl.device(udid: @device.udid)
|
44
|
+
SimCtl.boot_device device
|
45
|
+
wait_for {|device| device.state == 'Booted'}
|
46
|
+
SimCtl.shutdown_device device
|
47
|
+
wait_for {|device| device.state == 'Shutdown'}
|
48
|
+
end
|
49
|
+
|
50
|
+
should 'delete the device created in setup' do
|
51
|
+
device = SimCtl.device(udid: @device.udid)
|
52
|
+
SimCtl.delete_device device
|
53
|
+
assert_nil SimCtl.device(udid: @device.udid)
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SimCtl::Command::ListTest < Minitest::Test
|
4
|
+
context 'list_devicetypes' do
|
5
|
+
should 'contain some devicetypes' do
|
6
|
+
assert SimCtl.list_devicetypes.count > 0
|
7
|
+
end
|
8
|
+
|
9
|
+
should 'be a SimCtl::DeviceType object' do
|
10
|
+
assert_kind_of SimCtl::DeviceType, SimCtl.list_devicetypes.first
|
11
|
+
end
|
12
|
+
|
13
|
+
should 'parse identifier property' do
|
14
|
+
assert SimCtl.list_devicetypes.first.identifier != nil
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'parse name property' do
|
18
|
+
assert SimCtl.list_devicetypes.first.name != nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'list_runtimes' do
|
23
|
+
should 'contain some runtimes' do
|
24
|
+
assert SimCtl.list_runtimes.count > 0
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'be a SimCtl::Runtime object' do
|
28
|
+
assert_kind_of SimCtl::Runtime, SimCtl.list_runtimes.first
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'parse availability property' do
|
32
|
+
assert SimCtl.list_runtimes.first.availability != nil
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'parse buildversion property' do
|
36
|
+
assert SimCtl.list_runtimes.first.buildversion != nil
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'parse identifier property' do
|
40
|
+
assert SimCtl.list_runtimes.first.identifier != nil
|
41
|
+
end
|
42
|
+
|
43
|
+
should 'parse name property' do
|
44
|
+
assert SimCtl.list_runtimes.first.name != nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simctl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Johannes Plunien
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: maxitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: shoulda-context
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Ruby interface to xcrun simctl
|
56
|
+
email:
|
57
|
+
- plu@pqpq.de
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".travis.yml"
|
64
|
+
- Gemfile
|
65
|
+
- Gemfile.lock
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- lib/simctl.rb
|
70
|
+
- lib/simctl/command.rb
|
71
|
+
- lib/simctl/command/boot.rb
|
72
|
+
- lib/simctl/command/create.rb
|
73
|
+
- lib/simctl/command/delete.rb
|
74
|
+
- lib/simctl/command/erase.rb
|
75
|
+
- lib/simctl/command/list.rb
|
76
|
+
- lib/simctl/command/shutdown.rb
|
77
|
+
- lib/simctl/device.rb
|
78
|
+
- lib/simctl/device_type.rb
|
79
|
+
- lib/simctl/executor.rb
|
80
|
+
- lib/simctl/list.rb
|
81
|
+
- lib/simctl/object.rb
|
82
|
+
- lib/simctl/runtime.rb
|
83
|
+
- lib/simctl/version.rb
|
84
|
+
- simctl.gemspec
|
85
|
+
- test/simctl/command/crud_test.rb
|
86
|
+
- test/simctl/command/list_test.rb
|
87
|
+
- test/test_helper.rb
|
88
|
+
homepage: https://github.com/plu/simctl
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.4.6
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Ruby interface to xcrun simctl
|
112
|
+
test_files:
|
113
|
+
- test/simctl/command/crud_test.rb
|
114
|
+
- test/simctl/command/list_test.rb
|
115
|
+
- test/test_helper.rb
|
116
|
+
has_rdoc:
|