simctl 1.5.8 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 23e929d60bc574b9e16e479b4754d40fa393cda0
4
- data.tar.gz: 06d72f6aca738f535b9517bdaacb3606ab17548b
3
+ metadata.gz: befe14fafe0f39d0393b7780baa319a46c6bf13a
4
+ data.tar.gz: 88c089c6d7da469fbca2024f8892861181bb09a6
5
5
  SHA512:
6
- metadata.gz: 37521cf964d7b1cc61c591beb0a77d2b0f0a54973d5a89ab10694aa9b7cb45329704d89064451ce22e36871bfb4296ca33c92b6894cb588c6cbf67fad43048d5
7
- data.tar.gz: 83480c3189051338b6d75fd8601847111a4bf61b1e9d94d9421ab27e6e47d44aece6ea47ff8713a3c81a7ab8ef4a81d807bcc1f78a068c576c77a5a9bdbf24c3
6
+ metadata.gz: e077e932fa6bb00962c6533a3d3656ecfe7e5917266d86c3cb8800b24fb4e81cfcf6311969e66a3cc6906685285cb0e121d52fc605e05a1e287420ff4f25a013
7
+ data.tar.gz: d489f60b57eea0d3b3b106e607c5231e1f4cf527e4b4edbd65081df9da559adeacdf4c92b836394cf279ef5ce2f51a7b9cbb5f85a4d4fc5770ffbadfcf29d871
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 1.6.0
2
+
3
+ * Breaking change: All `!` have been removed from method names
4
+ * Support spawning processes
5
+ * Add `device.ready?` method
6
+
1
7
  # 1.5.8
2
8
 
3
9
  * Support taking screenshots
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simctl (1.5.8)
4
+ simctl (1.6.0)
5
5
  CFPropertyList
6
6
  naturally
7
7
 
data/README.md CHANGED
@@ -19,20 +19,20 @@ devicetype = SimCtl.devicetype(name: 'iPhone 5')
19
19
  device = SimCtl.create_device 'Unit Tests @ iPhone 5 9.3', devicetype, runtime
20
20
 
21
21
  # Launch a new Simulator.app instance
22
- device.launch!
22
+ device.launch
23
23
 
24
24
  # Wait for the device to be booted
25
- device.wait! {|d| d.state == :booted}
25
+ device.wait {|d| d.state == :booted}
26
26
 
27
27
  # Kill the Simulator.app instance again
28
- device.shutdown!
29
- device.kill!
28
+ device.shutdown
29
+ device.kill
30
30
 
31
31
  # Wait until it did shutdown
32
- device.wait! {|d| d.state == :shutdown}
32
+ device.wait {|d| d.state == :shutdown}
33
33
 
34
34
  # Delete the device
35
- device.delete!
35
+ device.delete
36
36
  ```
37
37
 
38
38
  ## License (MIT)
@@ -17,7 +17,7 @@ module SimCtl
17
17
  device = Executor.execute(command_for('create', Shellwords.shellescape(name), devicetype.identifier, runtime.identifier)) do |identifier|
18
18
  device(udid: identifier)
19
19
  end
20
- device.wait! {|d| d.state == :shutdown && File.exists?(d.path.device_plist)}
20
+ device.wait {|d| d.state == :shutdown && File.exists?(d.path.device_plist)}
21
21
  device
22
22
  end
23
23
  end
@@ -14,10 +14,10 @@ module SimCtl
14
14
  # @return [SimCtl::List] a list of all deleted SimCtl::Device objects
15
15
  def delete_all_devices
16
16
  list_devices.each do |device|
17
- device.kill!
18
- device.shutdown! if device.state != :shutdown
19
- device.wait! {|d| d.state == :shutdown}
20
- device.delete!
17
+ device.kill
18
+ device.shutdown if device.state != :shutdown
19
+ device.wait {|d| d.state == :shutdown}
20
+ device.delete
21
21
  end
22
22
  end
23
23
  end
@@ -12,7 +12,7 @@ module SimCtl
12
12
  # * display: Can be main or tv for iOS, tv for tvOS and main for watchOS
13
13
  # @return [void]
14
14
  def screenshot(device, file, opts={})
15
- unless XcodeVersion.gte? '8.2'
15
+ unless Xcode::Version.gte? '8.2'
16
16
  raise UnsupportedCommandError.new('Needs at least Xcode 8.2')
17
17
  end
18
18
  optional_args = opts.map {|k,v| "--#{k}=#{Shellwords.shellescape(v)}"}
@@ -3,9 +3,7 @@ require 'shellwords'
3
3
  module SimCtl
4
4
  class Command
5
5
  module Launch
6
- LAUNCH_APP_COMMAND = 'xcrun simctl launch'
7
6
  SUPPORTED_SCALE = [1.0, 0.75, 0.5, 0.25]
8
- XCODE_HOME = `xcode-select -p`.chomp
9
7
 
10
8
  # Launches a Simulator instance with the given device
11
9
  #
@@ -23,7 +21,7 @@ module SimCtl
23
21
  }
24
22
  args.merge!({ '-DeviceSetPath' => Shellwords.shellescape(SimCtl.device_set_path) }) unless SimCtl.device_set_path.nil?
25
23
  args = args.merge(opts).zip.flatten.join(' ')
26
- command = "open -Fgn #{XCODE_HOME}/Applications/Simulator.app --args #{args}"
24
+ command = "open -Fgn #{Xcode::Path.home}/Applications/Simulator.app --args #{args}"
27
25
  system command
28
26
  end
29
27
 
@@ -11,16 +11,16 @@ module SimCtl
11
11
  def reset_device(name, device_type, runtime)
12
12
  begin
13
13
  list_devices.where(name: name, os: runtime.name).each do |device|
14
- device.kill!
15
- device.shutdown! if device.state != :shutdown
16
- device.wait! {|d| d.state == :shutdown}
17
- device.delete!
14
+ device.kill
15
+ device.shutdown if device.state != :shutdown
16
+ device.wait {|d| d.state == :shutdown}
17
+ device.delete
18
18
  end
19
19
  rescue Exception => exception
20
20
  yield exception if block_given?
21
21
  end
22
22
  device = create_device name, device_type, runtime
23
- device.wait! {|d| d.state == :shutdown}
23
+ device.wait {|d| d.state == :shutdown}
24
24
  device
25
25
  end
26
26
  end
@@ -0,0 +1,19 @@
1
+ require 'shellwords'
2
+
3
+ module SimCtl
4
+ class Command
5
+ module Spawn
6
+ # Spawn a process on a device
7
+ #
8
+ # @param device [SimCtl::Device] the device to spawn a process on
9
+ # @param path [String] path to executable
10
+ # @param args [Array] arguments for the executable
11
+ # @return [String] standard output the spawned process generated
12
+ def spawn(device, path, args=[], opts={})
13
+ Executor.execute(command_for('spawn', device.udid, Shellwords.shellescape(path), *args.map{|a| Shellwords.shellwords(a)})) do |output|
14
+ output
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -11,6 +11,7 @@ require 'simctl/command/openurl'
11
11
  require 'simctl/command/rename'
12
12
  require 'simctl/command/reset'
13
13
  require 'simctl/command/shutdown'
14
+ require 'simctl/command/spawn'
14
15
  require 'simctl/command/uninstall'
15
16
  require 'simctl/executor'
16
17
  require 'shellwords'
@@ -32,6 +33,7 @@ module SimCtl
32
33
  include SimCtl::Command::Rename
33
34
  include SimCtl::Command::Reset
34
35
  include SimCtl::Command::Shutdown
36
+ include SimCtl::Command::Spawn
35
37
  include SimCtl::Command::Uninstall
36
38
 
37
39
  def device_set_path=(device_set_path)
data/lib/simctl/device.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'cfpropertylist'
2
2
  require 'ostruct'
3
+ require 'simctl/device_launchctl'
3
4
  require 'simctl/device_path'
4
5
  require 'simctl/device_settings'
5
6
  require 'simctl/object'
@@ -9,17 +10,24 @@ module SimCtl
9
10
  class Device < Object
10
11
  attr_reader :availability, :name, :os, :state, :udid
11
12
 
13
+ # Returns true/false if the device is available
14
+ #
15
+ # @return [Bool]
16
+ def available?
17
+ availability !~ /unavailable/i
18
+ end
19
+
12
20
  # Boots the device
13
21
  #
14
22
  # @return [void]
15
- def boot!
23
+ def boot
16
24
  SimCtl.boot_device(self)
17
25
  end
18
26
 
19
27
  # Deletes the device
20
28
  #
21
29
  # @return [void]
22
- def delete!
30
+ def delete
23
31
  SimCtl.delete_device(self)
24
32
  end
25
33
 
@@ -33,7 +41,7 @@ module SimCtl
33
41
  # Erases the device
34
42
  #
35
43
  # @return [void]
36
- def erase!
44
+ def erase
37
45
  SimCtl.erase_device(self)
38
46
  end
39
47
 
@@ -41,7 +49,7 @@ module SimCtl
41
49
  #
42
50
  # @param path Absolute path to the app that should be installed
43
51
  # @return [void]
44
- def install!(path)
52
+ def install(path)
45
53
  SimCtl.install_app(self, path)
46
54
  end
47
55
 
@@ -49,31 +57,38 @@ module SimCtl
49
57
  #
50
58
  # @param app_id App identifier of the app that should be uninstalled
51
59
  # @return [void]
52
- def uninstall!(app_id)
60
+ def uninstall(app_id)
53
61
  SimCtl.uninstall_app(self, app_id)
54
62
  end
55
63
 
56
64
  # Kills the device
57
65
  #
58
66
  # @return [void]
59
- def kill!
67
+ def kill
60
68
  SimCtl.kill_device(self)
61
69
  end
62
70
 
63
71
  # Launches the Simulator
64
72
  #
65
73
  # @return [void]
66
- def launch!(scale=1.0, opts={})
74
+ def launch(scale=1.0, opts={})
67
75
  SimCtl.launch_device(self, scale, opts)
68
76
  end
69
77
 
78
+ # Returns the launchctl object
79
+ #
80
+ # @ return [SimCtl::DeviceLaunchctl]
81
+ def launchctl
82
+ @launchctl ||= DeviceLaunchctl.new(self)
83
+ end
84
+
70
85
  # Launches an app in the given device
71
86
  #
72
87
  # @param opts [Hash] options hash - `{ wait_for_debugger: true/false }`
73
88
  # @param identifier [String] the app identifier
74
89
  # @param args [Array] optional launch arguments
75
90
  # @return [void]
76
- def launch_app!(identifier, args=[], opts={})
91
+ def launch_app(identifier, args=[], opts={})
77
92
  SimCtl.launch_app(self, identifier, args, opts)
78
93
  end
79
94
 
@@ -81,18 +96,31 @@ module SimCtl
81
96
  #
82
97
  # @param url [String] The url to be opened on the device
83
98
  # @return [void]
84
- def open_url!(url)
99
+ def open_url(url)
85
100
  SimCtl.open_url(self, url)
86
101
  end
87
102
 
88
103
  def path
89
- @path ||= DevicePath.new(udid)
104
+ @path ||= DevicePath.new(self)
105
+ end
106
+
107
+ # Returns true/false if the device is ready
108
+ # Uses [SimCtl::DeviceLaunchctl] to look for certain services being running.
109
+ #
110
+ # Unfortunately the 'booted' state does not mean the Simulator is ready for
111
+ # installing or launching applications.
112
+ #
113
+ # @return [Bool]
114
+ def ready?
115
+ # TODO: Should look for different services depending on device type (iphone/ipad, tv, watch)
116
+ running_services = launchctl.list.reject {|service| service.pid.to_i == 0 }.map {|service| service.name}
117
+ (required_services_for_ready - running_services).empty?
90
118
  end
91
119
 
92
120
  # Reloads the device information
93
121
  #
94
122
  # @return [void]
95
- def reload!
123
+ def reload
96
124
  device = SimCtl.device(udid: udid)
97
125
  device.instance_variables.each do |ivar|
98
126
  instance_variable_set(ivar, device.instance_variable_get(ivar))
@@ -102,7 +130,7 @@ module SimCtl
102
130
  # Renames the device
103
131
  #
104
132
  # @return [void]
105
- def rename!(name)
133
+ def rename(name)
106
134
  SimCtl.rename_device(self, name)
107
135
  @name = name
108
136
  end
@@ -110,7 +138,7 @@ module SimCtl
110
138
  # Resets the device
111
139
  #
112
140
  # @return [void]
113
- def reset!
141
+ def reset
114
142
  SimCtl.reset_device name, devicetype, runtime
115
143
  end
116
144
 
@@ -128,7 +156,7 @@ module SimCtl
128
156
  # * type: Can be png, tiff, bmp, gif, jpeg (default is png)
129
157
  # * display: Can be main or tv for iOS, tv for tvOS and main for watchOS
130
158
  # @return [void]
131
- def screenshot!(file, opts={})
159
+ def screenshot(file, opts={})
132
160
  SimCtl.screenshot(self, file, opts)
133
161
  end
134
162
 
@@ -142,10 +170,19 @@ module SimCtl
142
170
  # Shuts down the runtime
143
171
  #
144
172
  # @return [void]
145
- def shutdown!
173
+ def shutdown
146
174
  SimCtl.shutdown_device(self)
147
175
  end
148
176
 
177
+ # Spawn a process on a device
178
+ #
179
+ # @param path [String] path to executable
180
+ # @param args [Array] arguments for the executable
181
+ # @return [void]
182
+ def spawn(path, args=[], opts={})
183
+ SimCtl.spawn(self, path, args, opts)
184
+ end
185
+
149
186
  # Returns the state of the device
150
187
  #
151
188
  # @return [sym]
@@ -156,13 +193,13 @@ module SimCtl
156
193
  # Reloads the device until the given block returns true
157
194
  #
158
195
  # @return [void]
159
- def wait!(timeout=SimCtl.default_timeout)
196
+ def wait(timeout=SimCtl.default_timeout)
160
197
  Timeout::timeout(timeout) do
161
198
  loop do
162
199
  break if yield SimCtl.device(udid: udid)
163
200
  end
164
201
  end
165
- reload!
202
+ reload
166
203
  end
167
204
 
168
205
  def ==(other)
@@ -171,11 +208,56 @@ module SimCtl
171
208
  other.udid == udid
172
209
  end
173
210
 
211
+ def method_missing(method_name, *args, &block)
212
+ if method_name[-1] == '!'
213
+ new_method_name = method_name.to_s.chop.to_sym
214
+ if respond_to?(new_method_name)
215
+ warn "[#{Kernel.caller.first}] `#{method_name}` is deprecated. Please use `#{new_method_name}` instead."
216
+ return send(new_method_name, &block)
217
+ end
218
+ end
219
+ super
220
+ end
221
+
174
222
  private
175
223
 
176
224
  def plist
177
225
  @plist ||= OpenStruct.new(CFPropertyList.native_types(CFPropertyList::List.new(file: path.device_plist).value))
178
226
  end
179
227
 
228
+ def required_services_for_ready
229
+ case runtime.type
230
+ when :tvos, :watchos
231
+ if Xcode::Version.gte? '8.0'
232
+ [
233
+ 'com.apple.mobileassetd',
234
+ 'com.apple.nsurlsessiond',
235
+ ]
236
+ else
237
+ [
238
+ 'com.apple.mobileassetd',
239
+ 'com.apple.networkd',
240
+ ]
241
+ end
242
+ when :ios
243
+ if Xcode::Version.gte? '8.0'
244
+ [
245
+ 'com.apple.SimulatorBridge',
246
+ 'com.apple.SpringBoard',
247
+ 'com.apple.backboardd',
248
+ 'com.apple.medialibraryd',
249
+ 'com.apple.mobile.installd',
250
+ ]
251
+ else
252
+ [
253
+ 'com.apple.SimulatorBridge',
254
+ 'com.apple.SpringBoard',
255
+ 'com.apple.mobile.installd',
256
+ ]
257
+ end
258
+ else
259
+ []
260
+ end
261
+ end
180
262
  end
181
263
  end
@@ -0,0 +1,23 @@
1
+ require 'ostruct'
2
+
3
+ module SimCtl
4
+ class DeviceLaunchctl
5
+ def initialize(device)
6
+ @device = device
7
+ end
8
+
9
+ def list
10
+ fields = [:pid, :status, :name]
11
+ device
12
+ .spawn(device.path.launchctl, ['list'])
13
+ .split("\n")
14
+ .drop(1)
15
+ .map {|item| Hash[fields.zip(item.split("\t"))] }
16
+ .map {|item| OpenStruct.new(item) }
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :device
22
+ end
23
+ end
@@ -1,19 +1,47 @@
1
1
  module SimCtl
2
2
  class DevicePath
3
- attr_reader :device_plist, :global_preferences_plist, :home, :preferences_plist
3
+ def initialize(device)
4
+ @device = device
5
+ end
6
+
7
+ def device_plist
8
+ @device_plist ||= File.join(home, 'device.plist')
9
+ end
10
+
11
+ def global_preferences_plist
12
+ @global_preferences_plist ||= File.join(home, 'data/Library/Preferences/.GlobalPreferences.plist')
13
+ end
14
+
15
+ def home
16
+ @home ||= File.join(device_set_path, device.udid)
17
+ end
4
18
 
5
- def initialize(udid)
6
- @home = File.join(device_set_path, udid)
7
- @device_plist = File.join(@home, 'device.plist')
8
- @global_preferences_plist = File.join(@home, 'data/Library/Preferences/.GlobalPreferences.plist')
9
- @preferences_plist = File.join(@home, 'data/Library/Preferences/com.apple.Preferences.plist')
19
+ def launchctl
20
+ @launchctl ||= File.join(runtime_root, 'bin/launchctl')
21
+ end
22
+
23
+ def preferences_plist
24
+ @preferences_plist ||= File.join(home, 'data/Library/Preferences/com.apple.Preferences.plist')
10
25
  end
11
26
 
12
27
  private
13
28
 
29
+ attr_reader :device
30
+
14
31
  def device_set_path
15
32
  return SimCtl.device_set_path unless SimCtl.device_set_path.nil?
16
33
  File.join(ENV['HOME'], 'Library/Developer/CoreSimulator/Devices')
17
34
  end
35
+
36
+ def locate_runtime_root
37
+ "/Library/Developer/CoreSimulator/Profiles/Runtimes/#{device.runtime.name}.simruntime/Contents/Resources/RuntimeRoot".tap do |path|
38
+ return path if File.exists?(path)
39
+ end
40
+ Xcode::Path.sdk_root
41
+ end
42
+
43
+ def runtime_root
44
+ @runtime_root ||= locate_runtime_root
45
+ end
18
46
  end
19
47
  end
@@ -11,7 +11,7 @@ module SimCtl
11
11
  # Disables the keyboard helpers
12
12
  #
13
13
  # @return [void]
14
- def disable_keyboard_helpers!
14
+ def disable_keyboard_helpers
15
15
  edit_plist(path.preferences_plist) do |plist|
16
16
  %w(
17
17
  KeyboardAllowPaddle
@@ -33,7 +33,7 @@ module SimCtl
33
33
  #
34
34
  # @param enabled value to replace
35
35
  # @return [vod]
36
- def update_hardware_keyboard!(enabled)
36
+ def update_hardware_keyboard(enabled)
37
37
  edit_plist(path.preferences_plist) do |plist|
38
38
  plist['AutomaticMinimizationEnabled'] = enabled
39
39
  end
@@ -3,7 +3,11 @@ require 'simctl/object'
3
3
 
4
4
  module SimCtl
5
5
  class Runtime < Object
6
- attr_reader :availability, :buildversion, :identifier, :name, :version
6
+ attr_reader :availability, :buildversion, :identifier, :name, :type, :version
7
+
8
+ def type
9
+ @type ||= name.split("\s").first.downcase.to_sym
10
+ end
7
11
 
8
12
  def ==(other)
9
13
  return false if other.nil?
@@ -1,3 +1,3 @@
1
1
  module SimCtl
2
- VERSION = '1.5.8'
2
+ VERSION = '1.6.0'
3
3
  end
@@ -0,0 +1,17 @@
1
+ module SimCtl
2
+ module Xcode
3
+ class Path
4
+ HOME=`xcode-select -p`.chomp
5
+
6
+ class << self
7
+ def home
8
+ HOME
9
+ end
10
+
11
+ def sdk_root
12
+ File.join(HOME, 'Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk')
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module SimCtl
2
+ module Xcode
3
+ class Version
4
+ VERSION = Gem::Version.new(`xcodebuild -version`.scan(/Xcode (\S+)/).flatten.first)
5
+
6
+ class << self
7
+ def gte?(version)
8
+ VERSION >= Gem::Version.new(version)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/simctl.rb CHANGED
@@ -3,7 +3,8 @@ require 'simctl/device'
3
3
  require 'simctl/device_type'
4
4
  require 'simctl/list'
5
5
  require 'simctl/runtime'
6
- require 'simctl/xcode_version'
6
+ require 'simctl/xcode/path'
7
+ require 'simctl/xcode/version'
7
8
 
8
9
  module SimCtl
9
10
  class UnsupportedCommandError < StandardError; end
@@ -7,13 +7,13 @@ RSpec.describe SimCtl, order: :defined do
7
7
  @devicetype = SimCtl.devicetype(name: 'iPhone 5')
8
8
  @runtime = SimCtl::Runtime.latest(:ios)
9
9
  @device = SimCtl.create_device @name, @devicetype, @runtime
10
- @device.wait! {|d| d.state == :shutdown}
10
+ @device.wait {|d| d.state == :shutdown}
11
11
  end
12
12
 
13
13
  after(:all) do
14
- with_rescue { @device.kill! }
15
- with_rescue { @device.wait! {|d| d.state == :shutdown} }
16
- with_rescue { @device.delete! }
14
+ with_rescue { @device.kill }
15
+ with_rescue { @device.wait {|d| d.state == :shutdown} }
16
+ with_rescue { @device.delete }
17
17
  end
18
18
 
19
19
  describe 'creating a device' do
@@ -54,13 +54,31 @@ RSpec.describe SimCtl, order: :defined do
54
54
  it 'state is shutdown' do
55
55
  expect(@device.state).to be == :shutdown
56
56
  end
57
+
58
+ describe '#path' do
59
+ it 'has a device plist' do
60
+ expect(File).to exist(@device.path.device_plist)
61
+ end
62
+
63
+ it 'has a global preferences plist' do
64
+ expect(File).to exist(@device.path.global_preferences_plist)
65
+ end
66
+
67
+ it 'has a home' do
68
+ expect(File).to exist(@device.path.home)
69
+ end
70
+
71
+ it 'has a launchctl' do
72
+ expect(File).to exist(@device.path.launchctl)
73
+ end
74
+ end
57
75
  end
58
76
 
59
77
  describe 'device settings' do
60
78
  describe 'update hardware keyboard' do
61
79
  it 'creates the preferences plist' do
62
80
  File.delete(@device.path.preferences_plist) if File.exists?(@device.path.preferences_plist)
63
- @device.settings.update_hardware_keyboard!(false)
81
+ @device.settings.update_hardware_keyboard(false)
64
82
  expect(File).to exist(@device.path.preferences_plist)
65
83
  end
66
84
  end
@@ -68,7 +86,7 @@ RSpec.describe SimCtl, order: :defined do
68
86
  describe 'disable keyboard helpers' do
69
87
  it 'creates the preferences plist' do
70
88
  File.delete(@device.path.preferences_plist) if File.exists?(@device.path.preferences_plist)
71
- @device.settings.disable_keyboard_helpers!
89
+ @device.settings.disable_keyboard_helpers
72
90
  expect(File).to exist(@device.path.preferences_plist)
73
91
  end
74
92
  end
@@ -106,7 +124,7 @@ RSpec.describe SimCtl, order: :defined do
106
124
 
107
125
  describe 'renaming the device' do
108
126
  it 'renames the device' do
109
- @device.rename!('new name')
127
+ @device.rename('new name')
110
128
  expect(@device.name).to be == 'new name'
111
129
  expect(SimCtl.device(udid: @device.udid).name).to be == 'new name'
112
130
  end
@@ -114,63 +132,75 @@ RSpec.describe SimCtl, order: :defined do
114
132
 
115
133
  describe 'erasing the device' do
116
134
  it 'erases the device' do
117
- @device.erase!
135
+ @device.erase
118
136
  end
119
137
  end
120
138
 
121
139
  describe 'launching the device' do
122
140
  it 'launches the device' do
123
- @device.launch!
124
- @device.wait!{|d| d.state == :booted}
141
+ @device.launch
142
+ @device.wait {|d| d.state == :booted}
125
143
  expect(@device.state).to be == :booted
126
144
  end
145
+
146
+ it 'is ready' do
147
+ @device.wait {|d| d.ready?}
148
+ expect(@device).to be_ready
149
+ end
127
150
  end
128
151
 
129
152
  describe 'launching a system app' do
130
153
  it 'launches Safari' do
131
- @device.launch_app!('com.apple.mobilesafari')
154
+ @device.launch_app('com.apple.mobilesafari')
132
155
  end
133
156
  end
134
157
 
135
158
  describe 'taking a screenshot' do
136
- if SimCtl::XcodeVersion.gte? '8.2'
159
+ if SimCtl::Xcode::Version.gte? '8.2'
137
160
  it 'takes a screenshot' do
138
161
  file = File.join(Dir.mktmpdir, 'screenshot.png')
139
- @device.screenshot!(file)
162
+ @device.screenshot(file)
140
163
  expect(File).to exist(file)
141
164
  end
142
165
  else
143
166
  it 'raises exception' do
144
- expect { @device.screenshot!('/tmp/foo.png') }.to raise_error SimCtl::UnsupportedCommandError
167
+ expect { @device.screenshot('/tmp/foo.png') }.to raise_error SimCtl::UnsupportedCommandError
145
168
  end
146
169
  end
147
170
  end
148
171
 
172
+ describe 'spawning a process' do
173
+ it 'spawns launchctl list' do
174
+ output = @device.spawn(@device.path.launchctl, ['list'])
175
+ expect(output.length).to be > 0
176
+ end
177
+ end
178
+
149
179
  describe 'installing an app' do
150
180
  before(:all) do
151
181
  system 'cd spec/SampleApp && xcodebuild -sdk iphonesimulator >/dev/null 2>&1'
152
182
  end
153
183
 
154
184
  it 'installs SampleApp' do
155
- @device.install!('spec/SampleApp/build/Release-iphonesimulator/SampleApp.app')
185
+ @device.install('spec/SampleApp/build/Release-iphonesimulator/SampleApp.app')
156
186
  end
157
187
  end
158
188
 
159
189
  describe 'launching an app' do
160
190
  it 'launches SampleApp' do
161
- @device.launch_app!('com.github.plu.simctl.SampleApp')
191
+ @device.launch_app('com.github.plu.simctl.SampleApp')
162
192
  end
163
193
  end
164
194
 
165
195
  describe 'uninstall an app' do
166
196
  it 'uninstalls SampleApp' do
167
- @device.uninstall!('com.github.plu.simctl.SampleApp')
197
+ @device.uninstall('com.github.plu.simctl.SampleApp')
168
198
  end
169
199
  end
170
200
 
171
201
  describe 'opening a url' do
172
202
  it 'opens some url' do
173
- @device.open_url!('https://www.github.com')
203
+ @device.open_url('https://www.github.com')
174
204
  end
175
205
  end
176
206
 
@@ -180,8 +210,8 @@ RSpec.describe SimCtl, order: :defined do
180
210
  end
181
211
 
182
212
  it 'kills the device' do
183
- @device.kill!
184
- @device.wait!{|d| d.state == :shutdown}
213
+ @device.kill
214
+ @device.wait {|d| d.state == :shutdown}
185
215
  end
186
216
 
187
217
  it 'state is shutdown' do
@@ -195,14 +225,19 @@ RSpec.describe SimCtl, order: :defined do
195
225
  end
196
226
 
197
227
  it 'boots the device' do
198
- @device.boot!
199
- @device.wait! {|d| d.state == :booted}
228
+ @device.boot
229
+ @device.wait {|d| d.state == :booted}
200
230
  expect(@device.state).to be == :booted
201
231
  end
202
232
 
203
233
  it 'state is booted' do
204
234
  expect(@device.state).to be == :booted
205
235
  end
236
+
237
+ it 'is ready' do
238
+ @device.wait {|d| d.ready?}
239
+ expect(@device).to be_ready
240
+ end
206
241
  end
207
242
 
208
243
  describe 'shutting down the device' do
@@ -211,8 +246,8 @@ RSpec.describe SimCtl, order: :defined do
211
246
  end
212
247
 
213
248
  it 'shuts down the device' do
214
- @device.shutdown!
215
- @device.wait!{|d| d.state == :shutdown}
249
+ @device.shutdown
250
+ @device.wait {|d| d.state == :shutdown}
216
251
  end
217
252
 
218
253
  it 'state is shutdown' do
@@ -222,7 +257,7 @@ RSpec.describe SimCtl, order: :defined do
222
257
 
223
258
  describe 'resetting the device' do
224
259
  it 'deletes the old device and creates a new one' do
225
- new_device = @device.reset!
260
+ new_device = @device.reset
226
261
  expect(new_device.name).to be == @device.name
227
262
  expect(new_device.devicetype).to be == @device.devicetype
228
263
  expect(new_device.runtime).to be == @device.runtime
@@ -235,7 +270,7 @@ RSpec.describe SimCtl, order: :defined do
235
270
  describe 'deleting the device' do
236
271
  it 'deletes the device' do
237
272
  device = SimCtl.create_device @name, @devicetype, @runtime
238
- device.delete!
273
+ device.delete
239
274
  expect(SimCtl.device(udid: @device.udid)).to be_nil
240
275
  end
241
276
  end
@@ -77,13 +77,13 @@ RSpec.describe SimCtl do
77
77
  end
78
78
 
79
79
  it 'finds the latest runtime' do
80
- if SimCtl::XcodeVersion.gte?('8.2')
80
+ if SimCtl::Xcode::Version.gte?('8.2')
81
81
  expect(SimCtl::Runtime.latest(:ios).version).to be == '10.2'
82
- elsif SimCtl::XcodeVersion.gte?('8.1')
82
+ elsif SimCtl::Xcode::Version.gte?('8.1')
83
83
  expect(SimCtl::Runtime.latest(:ios).version).to be == '10.1'
84
- elsif SimCtl::XcodeVersion.gte?('8.0')
84
+ elsif SimCtl::Xcode::Version.gte?('8.0')
85
85
  expect(SimCtl::Runtime.latest(:ios).version).to be == '10.0'
86
- elsif SimCtl::XcodeVersion.gte?('7.3')
86
+ elsif SimCtl::Xcode::Version.gte?('7.3')
87
87
  expect(SimCtl::Runtime.latest(:ios).version).to be == '9.3'
88
88
  end
89
89
  end
@@ -12,19 +12,19 @@ RSpec.describe SimCtl do
12
12
  device = SimCtl.create_device 'Unit Tests @ iPhone 5 9.3', devicetype, runtime
13
13
 
14
14
  # Launch a new Simulator.app instance
15
- device.launch!
15
+ device.launch
16
16
 
17
17
  # Wait for the device to be booted
18
- device.wait! {|d| d.state == :booted}
18
+ device.wait {|d| d.state == :booted}
19
19
 
20
20
  # Kill the Simulator.app instance again
21
- device.shutdown!
22
- device.kill!
21
+ device.shutdown
22
+ device.kill
23
23
 
24
24
  # Wait until it did shutdown
25
- device.wait! {|d| d.state == :shutdown}
25
+ device.wait {|d| d.state == :shutdown}
26
26
 
27
27
  # Delete the device
28
- device.delete!
28
+ device.delete
29
29
  end
30
30
  end
data/spec/spec_helper.rb CHANGED
@@ -10,6 +10,8 @@ require File.dirname(__FILE__) + '/../lib/simctl.rb'
10
10
 
11
11
  if ENV['TRAVIS']
12
12
  SimCtl.default_timeout = 300
13
+ else
14
+ SimCtl.default_timeout = 60
13
15
  end
14
16
 
15
17
  unless ENV['CUSTOM_DEVICE_SET_PATH'] == 'false'
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.5.8
4
+ version: 1.6.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-12-22 00:00:00.000000000 Z
11
+ date: 2016-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coveralls
@@ -111,8 +111,10 @@ files:
111
111
  - lib/simctl/command/rename.rb
112
112
  - lib/simctl/command/reset.rb
113
113
  - lib/simctl/command/shutdown.rb
114
+ - lib/simctl/command/spawn.rb
114
115
  - lib/simctl/command/uninstall.rb
115
116
  - lib/simctl/device.rb
117
+ - lib/simctl/device_launchctl.rb
116
118
  - lib/simctl/device_path.rb
117
119
  - lib/simctl/device_settings.rb
118
120
  - lib/simctl/device_type.rb
@@ -121,7 +123,8 @@ files:
121
123
  - lib/simctl/object.rb
122
124
  - lib/simctl/runtime.rb
123
125
  - lib/simctl/version.rb
124
- - lib/simctl/xcode_version.rb
126
+ - lib/simctl/xcode/path.rb
127
+ - lib/simctl/xcode/version.rb
125
128
  - simctl.gemspec
126
129
  - spec/SampleApp/.gitignore
127
130
  - spec/SampleApp/SampleApp.xcodeproj/project.pbxproj
@@ -1,11 +0,0 @@
1
- module SimCtl
2
- module XcodeVersion
3
- VERSION = Gem::Version.new(`xcodebuild -version`.scan(/Xcode (\S+)/).flatten.first)
4
-
5
- class << self
6
- def gte?(version)
7
- return VERSION >= Gem::Version.new(version)
8
- end
9
- end
10
- end
11
- end