run_loop 2.4.1 → 2.5.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: 5fa8d6acd657ee7230c4095b970215199e1e9d03
4
- data.tar.gz: b06b85cde2448ca8f5a97f79a834c237f920d008
3
+ metadata.gz: 47c4ac8c0ca04201b1f2a083ef93cb906835c4ab
4
+ data.tar.gz: 9665bb55f30876e01542533f5312604879f2c3da
5
5
  SHA512:
6
- metadata.gz: ccd75f46828607b5e5d40df9acfa688f15ff5b812f9366657b9638cb93cd316080b02652f97f8bdcc0299ffeb167461925a85b26c2177313b9f52960126f70c9
7
- data.tar.gz: c87f40e81cad88dcd0f5d29b9d49a76920f3b06f263d2ad8fab45fd84eff07c509ea43f7a6af64ee1e7c8ac05172952b0878920edf18182a5ed139628993d0c0
6
+ metadata.gz: 26077ed5f0322bf945f258cecf869dd378d3b1e12c4897cf3a9add7cfe22644e133c53b241c986298248d4dd6d038c7bda697f691e8a61148c363c9b4df0f8c1
7
+ data.tar.gz: 90607898903b3236f2af292918413fb3ff9e7d1c2d09e1d66e159d37d0f6a681bcfc9dedc5e4dc4fb2743954400d4a468bee01606136db5f609c6b2d0762c0c4
@@ -1,11 +1,13 @@
1
- require 'thor'
2
- require 'run_loop'
3
- require 'run_loop/cli/errors'
4
1
 
5
2
  module RunLoop
6
3
  module CLI
4
+
5
+ require 'thor'
7
6
  class Simctl < Thor
8
7
 
8
+ require 'run_loop'
9
+ require 'run_loop/cli/errors'
10
+
9
11
  attr_reader :simctl
10
12
 
11
13
  desc 'tail', 'Tail the log file of the booted simulator'
@@ -187,6 +189,60 @@ module RunLoop
187
189
  end
188
190
  end
189
191
 
192
+ desc "erase <simulator>", "Erases the simulator"
193
+
194
+ method_option 'debug',
195
+ :desc => 'Enable debug logging.',
196
+ :aliases => '-v',
197
+ :required => false,
198
+ :default => false,
199
+ :type => :boolean
200
+
201
+ def erase(simulator=nil)
202
+
203
+ debug = options[:debug]
204
+
205
+ RunLoop::Environment.with_debugging(debug) do
206
+ if !simulator
207
+ identifier = RunLoop::Core.default_simulator(xcode)
208
+ else
209
+ identifier = simulator
210
+ end
211
+
212
+ options = {simctl: simctl, xcode: xcode}
213
+ device = RunLoop::Device.device_with_identifier(identifier, options)
214
+
215
+ RunLoop::CoreSimulator.erase(device, options)
216
+ end
217
+ end
218
+
219
+ desc "launch <simulator>", "Launches the simulator"
220
+
221
+ method_option 'debug',
222
+ :desc => 'Enable debug logging.',
223
+ :aliases => '-v',
224
+ :required => false,
225
+ :default => false,
226
+ :type => :boolean
227
+
228
+ def launch(simulator=nil)
229
+ debug = options[:debug]
230
+
231
+ RunLoop::Environment.with_debugging(debug) do
232
+ if !simulator
233
+ identifier = RunLoop::Core.default_simulator(xcode)
234
+ else
235
+ identifier = simulator
236
+ end
237
+
238
+ options = {simctl: simctl, xcode: xcode}
239
+ device = RunLoop::Device.device_with_identifier(identifier, options)
240
+
241
+ core_sim = RunLoop::CoreSimulator.new(device, nil)
242
+ core_sim.launch_simulator
243
+ end
244
+ end
245
+
190
246
  no_commands do
191
247
  def expect_device(options)
192
248
  device_from_options = options[:device]
data/lib/run_loop/core.rb CHANGED
@@ -320,7 +320,9 @@ Logfile: #{log_file}
320
320
  # version.
321
321
  def self.default_simulator(xcode=RunLoop::Xcode.new)
322
322
 
323
- if xcode.version_gte_83?
323
+ if xcode.version_gte_90?
324
+ "iPhone 7 (11.0)"
325
+ elsif xcode.version_gte_83?
324
326
  "iPhone 7 (10.3)"
325
327
  elsif xcode.version_gte_82?
326
328
  "iPhone 7 (10.2)"
@@ -157,6 +157,8 @@ class RunLoop::CoreSimulator
157
157
  # @!visibility private
158
158
  # Quit any Simulator.app or iOS Simulator.app
159
159
  def self.quit_simulator
160
+ RunLoop::DeviceAgent::Xcodebuild.terminate_simulator_tests
161
+
160
162
  SIMULATOR_QUIT_PROCESSES.each do |process_details|
161
163
  process_name = process_details[0]
162
164
  send_term_first = process_details[1]
@@ -375,6 +377,11 @@ class RunLoop::CoreSimulator
375
377
  options = { :timeout => 5, :raise_on_timeout => true }
376
378
  RunLoop::ProcessWaiter.new(sim_name, options).wait_for_any
377
379
 
380
+ # open -g no longer launches application in the background. We want the
381
+ # Simulator to open in the background because when it is opened in the
382
+ # foreground, it steals (key application) focus which is disruptive.
383
+ send_simulator_to_background
384
+
378
385
  if merged_options[:wait_for_stable]
379
386
  device.simulator_wait_for_stable_state
380
387
  end
@@ -599,6 +606,23 @@ Command had no output.
599
606
  hash
600
607
  end
601
608
 
609
+ # @!visibility private
610
+ def send_simulator_to_background
611
+ script = "tell application \"System Events\" to tell process \"#{sim_name}\" to set visible to false"
612
+ begin
613
+ system("osascript", "-e", script)
614
+ rescue => _
615
+ RunLoop.log_debug("Could not put simulator into the background")
616
+ end
617
+
618
+ script = "tell application \"System Events\" to tell process \"#{sim_name}\" to set visible to true"
619
+ begin
620
+ system("osascript", "-e", script)
621
+ rescue => _
622
+ RunLoop.log_debug("Could not put simulator into the foreground")
623
+ end
624
+ end
625
+
602
626
  # @!visibility private
603
627
  def uninstall_app_with_simctl
604
628
  launch_simulator
@@ -737,6 +761,14 @@ Command had no output.
737
761
  end
738
762
  end
739
763
 
764
+ # @!visibility private
765
+ def device_agent_launched_by_xcode?(running_apps)
766
+ process_info = running_apps["XCTRunner"] || running_apps["DeviceAgent-Runner"]
767
+ return false if !process_info
768
+
769
+ process_info[:args][/CBX_LAUNCHED_BY_XCODE/]
770
+ end
771
+
740
772
  # @!visibility private
741
773
  def running_apps_require_relaunch?
742
774
  running_apps = device.simulator_running_app_details
@@ -747,11 +779,9 @@ Command had no output.
747
779
  end
748
780
 
749
781
  # DeviceAgent is running, but it was launched by Xcode.
750
- if running_apps["XCTRunner"]
751
- if running_apps["XCTRunner"][:args][/CBX_LAUNCHED_BY_XCODE/]
752
- RunLoop.log_debug("Simulator relaunch required: XCTRunner is controlled by Xcode")
753
- return true
754
- end
782
+ if device_agent_launched_by_xcode?(running_apps)
783
+ RunLoop.log_debug("Simulator relaunch required: XCTRunner is controlled by Xcode")
784
+ return true
755
785
  end
756
786
 
757
787
  # No app was passed to initializer.
@@ -314,11 +314,29 @@ version: #{version}
314
314
  end
315
315
 
316
316
  # @!visibility private
317
- def simulator_global_preferences_path
318
- @simulator_global_preferences_path ||= lambda do
319
- return nil if physical_device?
320
- File.join(simulator_root_dir, "data/Library/Preferences/.GlobalPreferences.plist")
321
- end.call
317
+ def simulator_global_preferences_path(timeout=10)
318
+ return nil if physical_device?
319
+
320
+ path = File.join(simulator_root_dir,
321
+ "data/Library/Preferences/.GlobalPreferences.plist")
322
+
323
+ return path if File.exist?(path)
324
+
325
+ start = Time.now
326
+ while !File.exist?(path) && (start + timeout) < Time.now
327
+ sleep(1.0)
328
+ end
329
+
330
+ return path if File.exist?(path)
331
+
332
+ raise(RuntimeError, %Q[
333
+ Timed out waiting for .GlobalPreferences.plist after #{Time.now - start} seconds.
334
+
335
+ File does not exist at path:
336
+
337
+ #{path}
338
+
339
+ ])
322
340
  end
323
341
 
324
342
  # @!visibility private
@@ -39,10 +39,20 @@ module RunLoop
39
39
  # Ignored in the XTC.
40
40
  # This key is subject to removal or changes
41
41
  :device_agent_install_timeout => RunLoop::Environment.ci? ? 240 : 120,
42
+
42
43
  # This value must always be false on the XTC.
43
44
  # This is should only be used by gem maintainers or very advanced users.
44
45
  :shutdown_device_agent_before_launch => false,
45
46
 
47
+ # This value controls whether or not DeviceAgent should terminate the
48
+ # the Application Under Test (AUT) when a new testing session is
49
+ # started. The default behavior is to _not_ terminate the AUT if it
50
+ # is already running. If you want your next test to start with your
51
+ # application in a freshly launched state, set this option to true.
52
+ #
53
+ # If the AUT is not running, DeviceAgent performs no action.
54
+ :terminate_aut_before_test => false,
55
+
46
56
  # This value was derived empirically by typing hundreds of strings
47
57
  # using XCUIElement#typeText. It corresponds to the DeviceAgent
48
58
  # constant CBX_DEFAULT_SEND_STRING_FREQUENCY which is 60. _Decrease_
@@ -122,10 +132,18 @@ module RunLoop
122
132
  code_sign_identity = RunLoop::Environment::code_sign_identity
123
133
  end
124
134
 
135
+ provisioning_profile = options[:provisioning_profile]
136
+ if !provisioning_profile
137
+ provisioning_profile = RunLoop::Environment::provisioning_profile
138
+ end
139
+
125
140
  install_timeout = options.fetch(:device_agent_install_timeout,
126
141
  DEFAULTS[:device_agent_install_timeout])
127
- shutdown_before_launch = options.fetch(:shutdown_device_agent_before_launch,
128
- DEFAULTS[:shutdown_device_agent_before_launch])
142
+ shutdown_device_agent_before_launch = options.fetch(:shutdown_device_agent_before_launch,
143
+ DEFAULTS[:shutdown_device_agent_before_launch])
144
+ terminate_aut_before_test = options.fetch(:terminate_aut_before_test,
145
+ DEFAULTS[:terminate_aut_before_test])
146
+
129
147
  aut_args = options.fetch(:args, [])
130
148
  aut_env = options.fetch(:env, {})
131
149
 
@@ -135,8 +153,10 @@ module RunLoop
135
153
 
136
154
  launcher_options = {
137
155
  code_sign_identity: code_sign_identity,
156
+ provisioning_profile: provisioning_profile,
138
157
  device_agent_install_timeout: install_timeout,
139
- shutdown_device_agent_before_launch: shutdown_before_launch,
158
+ shutdown_device_agent_before_launch: shutdown_device_agent_before_launch,
159
+ terminate_aut_before_test: terminate_aut_before_test,
140
160
  dylib_injection_details: dylib_injection_details,
141
161
  aut_args: aut_args,
142
162
  aut_env: aut_env
@@ -152,6 +172,7 @@ module RunLoop
152
172
  :app => bundle_id,
153
173
  :automator => :device_agent,
154
174
  :code_sign_identity => code_sign_identity,
175
+ :provisioning_profile => provisioning_profile,
155
176
  :launcher => cbx_launcher.name,
156
177
  :launcher_pid => xcuitest.launcher_pid,
157
178
  :launcher_options => xcuitest.launcher_options
@@ -674,14 +695,21 @@ Could not dismiss SpringBoard alert by touching button with title '#{button_titl
674
695
  def rotate_home_button_to(position, sleep_for=1.0)
675
696
  orientation = normalize_orientation_position(position)
676
697
  parameters = {
677
- :orientation => orientation
698
+ :orientation => orientation,
699
+ :seconds_to_sleep_after => sleep_for
678
700
  }
679
701
  request = request("rotate_home_button_to", parameters)
680
702
  client = http_client(http_options)
681
703
  response = client.post(request)
682
- json = expect_300_response(response)
683
- sleep(sleep_for)
684
- json
704
+ expect_300_response(response)
705
+ end
706
+
707
+ # @!visibility private
708
+ def orientations
709
+ request = request("orientations")
710
+ client = http_client(http_options)
711
+ response = client.get(request)
712
+ expect_300_response(response)
685
713
  end
686
714
 
687
715
  # @!visibility private
@@ -1287,10 +1315,6 @@ PRIVATE
1287
1315
  kill = RunLoop::ProcessTerminator.new(pid, "KILL", process_name, kill_options)
1288
1316
  kill.kill_process
1289
1317
  end
1290
-
1291
- if process_name == :xcodebuild
1292
- sleep(10)
1293
- end
1294
1318
  end
1295
1319
  end
1296
1320
  hash
@@ -1420,13 +1444,16 @@ Please install it.
1420
1444
  # internal callers to do not.
1421
1445
  aut_args = launcher_options.fetch(:aut_args, [])
1422
1446
  aut_env = launcher_options.fetch(:aut_env, {})
1447
+ terminate_aut = launcher_options.fetch(:terminate_aut_before_test, false)
1448
+
1423
1449
  begin
1424
1450
  client = http_client(http_options)
1425
1451
  request = request("session",
1426
1452
  {
1427
1453
  :bundle_id => bundle_id,
1428
1454
  :launchArgs => aut_args,
1429
- :environment => aut_env
1455
+ :environment => aut_env,
1456
+ :terminate_aut_if_running => terminate_aut
1430
1457
  })
1431
1458
  response = client.post(request)
1432
1459
  RunLoop.log_debug("Launched #{bundle_id} on #{device}")
@@ -7,6 +7,8 @@ module RunLoop
7
7
  # A wrapper around the test-control binary.
8
8
  class IOSDeviceManager < RunLoop::DeviceAgent::LauncherStrategy
9
9
 
10
+ require "run_loop/regex"
11
+
10
12
  EXIT_CODES = {
11
13
  "0" => :success,
12
14
  "2" => :false
@@ -98,6 +100,7 @@ but binary does not exist at that path.
98
100
  # @!visibility private
99
101
  def launch(options)
100
102
  code_sign_identity = options[:code_sign_identity]
103
+ provisioning_profile = options[:provisioning_profile]
101
104
  install_timeout = options[:device_agent_install_timeout]
102
105
 
103
106
  RunLoop::DeviceAgent::Frameworks.instance.install
@@ -105,12 +108,15 @@ but binary does not exist at that path.
105
108
 
106
109
  start = Time.now
107
110
  if device.simulator?
108
- cbxapp = RunLoop::App.new(runner.runner)
111
+ RunLoop::DeviceAgent::Xcodebuild.terminate_simulator_tests
109
112
 
113
+ cbxapp = RunLoop::App.new(runner.runner)
110
114
  sim = CoreSimulator.new(device, cbxapp)
115
+
111
116
  sim.install
112
117
  sim.launch_simulator
113
118
  else
119
+ RunLoop::DeviceAgent::Xcodebuild.terminate_device_test(device.udid)
114
120
 
115
121
  if !install_timeout
116
122
  raise ArgumentError, %Q[
@@ -125,16 +131,17 @@ Expected :device_agent_install_timeout key in options:
125
131
  shell_options = {:log_cmd => true, :timeout => install_timeout}
126
132
 
127
133
  args = [
128
- cmd, "install",
129
- "--device-id", device.udid,
130
- # -a <== --app-bundle (1.0.4) and --app-path (> 1.0.4)
131
- "-a", runner.runner
134
+ cmd, "install", runner.runner, "--device-id", device.udid
132
135
  ]
133
136
 
134
137
  if code_sign_identity
135
138
  args = args + ["--codesign-identity", code_sign_identity]
136
139
  end
137
140
 
141
+ if provisioning_profile
142
+ args = args + ["--provisioning-profile", provisioning_profile]
143
+ end
144
+
138
145
  start = Time.now
139
146
  hash = run_shell_command(args, shell_options)
140
147
 
@@ -149,10 +156,11 @@ Could not install #{runner.runner}. iOSDeviceManager says:
149
156
  end
150
157
  end
151
158
 
152
- RunLoop::log_debug("Took #{Time.now - start} seconds to install DeviceAgent");
159
+ RunLoop::log_debug("Took #{Time.now - start} seconds to install DeviceAgent")
153
160
 
154
161
  cmd = "xcrun"
155
- args = ["xcodebuild", "test-without-building",
162
+ args = ["xcodebuild",
163
+ "test-without-building",
156
164
  "-xctestrun", path_to_xctestrun,
157
165
  "-destination", "id=#{device.udid}",
158
166
  "-derivedDataPath", Xcodebuild.derived_data_directory]
@@ -162,6 +170,7 @@ Could not install #{runner.runner}. iOSDeviceManager says:
162
170
  FileUtils.touch(log_file)
163
171
 
164
172
  env = {
173
+ # zsh support
165
174
  "CLOBBER" => "1"
166
175
  }
167
176
 
@@ -180,9 +189,7 @@ Could not install #{runner.runner}. iOSDeviceManager says:
180
189
  cmd = RunLoop::DeviceAgent::IOSDeviceManager.ios_device_manager
181
190
 
182
191
  args = [
183
- cmd, "is_installed",
184
- "--device-id", device.udid,
185
- "--bundle-identifier", bundle_identifier
192
+ cmd, "is-installed", bundle_identifier, "--device-id", device.udid
186
193
  ]
187
194
 
188
195
  start = Time.now
@@ -116,7 +116,69 @@ Use the CBXWS environment variable to override the default.
116
116
  relative = File.expand_path(File.join(this_dir, "..", "..", "..", ".."))
117
117
  File.join(relative, "DeviceAgent.iOS/DeviceAgent.xcworkspace")
118
118
  end
119
+
120
+ # @visibility private
121
+ def self.terminate_simulator_tests
122
+ should_term_test = lambda do |process_description|
123
+ xcodebuild_destination_is_simulator?(process_description)
124
+ end
125
+
126
+ self.terminate_xcodebuild_test_processes(should_term_test)
127
+ end
128
+
129
+ # @visibility private
130
+ def self.terminate_device_test(udid)
131
+ should_term_test = lambda do |process_description|
132
+ process_description[/id=#{udid}/]
133
+ end
134
+ self.terminate_xcodebuild_test_processes(should_term_test)
135
+ end
136
+
137
+ # @visibility private
138
+ def self.terminate_xcodebuild_test_processes(should_term_test)
139
+ options = { :timeout => 0.5, :raise_on_timeout => false }
140
+ pids = RunLoop::ProcessWaiter.new("xcodebuild", options).pids
141
+ pids.each do |pid|
142
+ if should_term_test.call(process_env(pid))
143
+ RunLoop.log_debug("Will terminate xcodebuild process: #{pid}")
144
+ terminate_xcodebuild_test_process(pid)
145
+ end
146
+ end
147
+ end
148
+
149
+ # @visibility private
150
+ def self.terminate_xcodebuild_test_process(pid)
151
+ term_options = { :timeout => 1.5 }
152
+ kill_options = { :timeout => 1.0 }
153
+
154
+ process_name = "xcodebuild test-without-building"
155
+
156
+ term = RunLoop::ProcessTerminator.new(pid.to_i,
157
+ "TERM",
158
+ process_name,
159
+ term_options)
160
+ if !term.kill_process
161
+ kill = RunLoop::ProcessTerminator.new(pid.to_i,
162
+ "KILL",
163
+ process_name,
164
+ kill_options)
165
+ kill.kill_process
166
+ end
167
+ sleep(1.0)
168
+ end
169
+
170
+ # @visibility private
171
+ def self.xcodebuild_destination_is_simulator?(process_description)
172
+ process_description[/-destination id=#{RunLoop::Regex::CORE_SIMULATOR_UDID_REGEX}/]
173
+ end
174
+
175
+ # @visibility private
176
+ def self.process_env(pid)
177
+ options = {:log_cmd => true}
178
+ args = ["ps", "-p", pid.to_s, "-wwwE"]
179
+ hash = RunLoop::Shell.run_shell_command(args, options)
180
+ hash[:out]
181
+ end
119
182
  end
120
183
  end
121
184
  end
122
-
@@ -162,7 +162,7 @@ module RunLoop
162
162
  end
163
163
  end
164
164
 
165
- # Returns the value of CODESIGN_IDENTITY
165
+ # Returns the value of CODE_SIGN_IDENTITY
166
166
  def self.code_sign_identity
167
167
  value = ENV["CODE_SIGN_IDENTITY"]
168
168
  if !value || value == ""
@@ -172,6 +172,16 @@ module RunLoop
172
172
  end
173
173
  end
174
174
 
175
+ # Returns the value of PROVISIONING_PROFILE
176
+ def self.provisioning_profile
177
+ value = ENV["PROVISIONING_PROFILE"]
178
+ if !value || value == ""
179
+ nil
180
+ else
181
+ value
182
+ end
183
+ end
184
+
175
185
  # Returns the value of KEYCHAIN
176
186
  #
177
187
  # Use this to specify a non-default KEYCHAIN for code signing.
data/lib/run_loop/l10n.rb CHANGED
@@ -18,6 +18,7 @@ module RunLoop
18
18
  end
19
19
 
20
20
  UIKIT_AXBUNDLE_PATH_CORE_SIM = 'Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/AccessibilityBundles/UIKit.axbundle/'
21
+ UIKIT_AXBUNDLE_PATH_CORE_SIM_XCODE_9 = "Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/AccessibilityBundles/UIKit.axbundle"
21
22
 
22
23
  LANG_CODE_TO_LANG_NAME_MAP = {
23
24
  'en' => 'English',
@@ -70,7 +71,11 @@ module RunLoop
70
71
  end
71
72
 
72
73
  def uikit_bundle_l10n_path
73
- File.join(xcode.developer_dir, UIKIT_AXBUNDLE_PATH_CORE_SIM)
74
+ if xcode.version_gte_90?
75
+ File.join(xcode.developer_dir, UIKIT_AXBUNDLE_PATH_CORE_SIM_XCODE_9)
76
+ else
77
+ File.join(xcode.developer_dir, UIKIT_AXBUNDLE_PATH_CORE_SIM)
78
+ end
74
79
  end
75
80
 
76
81
  def is_full_name?(two_letter_country_code)
@@ -1,5 +1,5 @@
1
1
  module RunLoop
2
- VERSION = "2.4.1"
2
+ VERSION = "2.5.0"
3
3
 
4
4
  # A model of a software release version that can be used to compare two versions.
5
5
  #
@@ -102,7 +102,15 @@ module RunLoop
102
102
 
103
103
  # The hash method for this instance.
104
104
  def hash
105
- to_s.hash
105
+ str = [major, minor, patch].map do |str|
106
+ str ? str : "0"
107
+ end.join(".")
108
+
109
+ if pre
110
+ str = "#{str}.#{pre}"
111
+ end
112
+
113
+ str.hash
106
114
  end
107
115
 
108
116
  # Compare this version to another for equality.
@@ -158,25 +166,29 @@ module RunLoop
158
166
  def self.compare(a, b)
159
167
 
160
168
  if a.major != b.major
161
- return a.major > b.major ? 1 : -1
169
+ return a.major.to_i > b.major.to_i ? 1 : -1
162
170
  end
163
171
 
164
- if a.minor != b.minor
165
- return a.minor.to_i > b.minor.to_i ? 1 : -1
172
+ a_minor = a.minor ? a.minor.to_i : 0
173
+ b_minor = b.minor ? b.minor.to_i : 0
174
+ if a_minor != b_minor
175
+ return a_minor > b_minor.to_i ? 1 : -1
166
176
  end
167
177
 
168
- if a.patch != b.patch
169
- return a.patch.to_i > b.patch.to_i ? 1 : -1
178
+ a_patch = a.patch ? a.patch.to_i : 0
179
+ b_patch = b.patch ? b.patch.to_i : 0
180
+ if a_patch != b_patch
181
+ return a_patch.to_i > b_patch.to_i ? 1 : -1
170
182
  end
171
183
 
172
- return -1 if a.pre and (not a.pre_version) and b.pre_version
173
- return 1 if a.pre_version and b.pre and (not b.pre_version)
184
+ return -1 if a.pre && (!a.pre_version) && b.pre_version
185
+ return 1 if a.pre_version && b.pre && (!b.pre_version)
174
186
 
175
- return -1 if a.pre and (not b.pre)
176
- return 1 if (not a.pre) and b.pre
187
+ return -1 if a.pre && (!b.pre)
188
+ return 1 if (!a.pre) && b.pre
177
189
 
178
- return -1 if a.pre_version and (not b.pre_version)
179
- return 1 if (not a.pre_version) and b.pre_version
190
+ return -1 if a.pre_version && (!b.pre_version)
191
+ return 1 if (!a.pre_version) && b.pre_version
180
192
 
181
193
  if a.pre_version != b.pre_version
182
194
  return a.pre_version.to_i > b.pre_version.to_i ? 1 : -1
@@ -26,7 +26,15 @@ module RunLoop
26
26
  to_s
27
27
  end
28
28
 
29
- # Returns a version instance for Xcode 8.3 ; used to check for the
29
+ # Returns a version instance for Xcode 9.0; used to check for the
30
+ # availability of features and paths to various items on the filesystem
31
+ #
32
+ # @return [RunLoop::Version] 9.0
33
+ def v90
34
+ fetch_version(:v90)
35
+ end
36
+
37
+ # Returns a version instance for Xcode 8.3; used to check for the
30
38
  # availability of features and paths to various items on the filesystem
31
39
  #
32
40
  # @return [RunLoop::Version] 8.3
@@ -34,7 +42,7 @@ module RunLoop
34
42
  fetch_version(:v83)
35
43
  end
36
44
 
37
- # Returns a version instance for Xcode 8.2 ; used to check for the
45
+ # Returns a version instance for Xcode 8.2; used to check for the
38
46
  # availability of features and paths to various items on the filesystem
39
47
  #
40
48
  # @return [RunLoop::Version] 8.2
@@ -146,6 +154,13 @@ module RunLoop
146
154
  fetch_version(:v50)
147
155
  end
148
156
 
157
+ # Is the active Xcode version 9.0 or above?
158
+ #
159
+ # @return [Boolean] `true` if the current Xcode version is >= 9.0
160
+ def version_gte_90?
161
+ version >= v90
162
+ end
163
+
149
164
  # Is the active Xcode version 8.3 or above?
150
165
  #
151
166
  # @return [Boolean] `true` if the current Xcode version is >= 8.3
@@ -198,7 +198,8 @@ function portugueseBrazilLocalizations() {
198
198
  ["OK", /Deseja Ter Acesso às Suas Atividades de Movimento e Preparo Físico/],
199
199
  ["OK", /Deseja Ter Acesso às Contas do Twitter/],
200
200
  ["OK", /data available to nearby bluetooth devices/],
201
- ["OK", /[Dd]eseja [Ee]nviar-lhe [Nn]otificações/]
201
+ ["OK", /[Dd]eseja [Ee]nviar-lhe [Nn]otificações/],
202
+ ["Permitir", /Deseja Enviar Notificações/]
202
203
  ];
203
204
  }
204
205
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: run_loop
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karl Krukow
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-04-11 00:00:00.000000000 Z
12
+ date: 2017-08-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -212,47 +212,47 @@ dependencies:
212
212
  - !ruby/object:Gem::Version
213
213
  version: '4.3'
214
214
  - !ruby/object:Gem::Dependency
215
- name: guard-bundler
215
+ name: terminal-notifier-guard
216
216
  requirement: !ruby/object:Gem::Requirement
217
217
  requirements:
218
218
  - - "~>"
219
219
  - !ruby/object:Gem::Version
220
- version: '2.0'
220
+ version: '1.7'
221
221
  type: :development
222
222
  prerelease: false
223
223
  version_requirements: !ruby/object:Gem::Requirement
224
224
  requirements:
225
225
  - - "~>"
226
226
  - !ruby/object:Gem::Version
227
- version: '2.0'
227
+ version: '1.7'
228
228
  - !ruby/object:Gem::Dependency
229
- name: listen
229
+ name: guard-bundler
230
230
  requirement: !ruby/object:Gem::Requirement
231
231
  requirements:
232
- - - '='
232
+ - - "~>"
233
233
  - !ruby/object:Gem::Version
234
- version: 3.0.6
234
+ version: '2.0'
235
235
  type: :development
236
236
  prerelease: false
237
237
  version_requirements: !ruby/object:Gem::Requirement
238
238
  requirements:
239
- - - '='
239
+ - - "~>"
240
240
  - !ruby/object:Gem::Version
241
- version: 3.0.6
241
+ version: '2.0'
242
242
  - !ruby/object:Gem::Dependency
243
- name: growl
243
+ name: listen
244
244
  requirement: !ruby/object:Gem::Requirement
245
245
  requirements:
246
- - - "~>"
246
+ - - '='
247
247
  - !ruby/object:Gem::Version
248
- version: '1.0'
248
+ version: 3.0.6
249
249
  type: :development
250
250
  prerelease: false
251
251
  version_requirements: !ruby/object:Gem::Requirement
252
252
  requirements:
253
- - - "~>"
253
+ - - '='
254
254
  - !ruby/object:Gem::Version
255
- version: '1.0'
255
+ version: 3.0.6
256
256
  - !ruby/object:Gem::Dependency
257
257
  name: stub_env
258
258
  requirement: !ruby/object:Gem::Requirement
@@ -415,7 +415,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
415
415
  version: '0'
416
416
  requirements: []
417
417
  rubyforge_project:
418
- rubygems_version: 2.5.1
418
+ rubygems_version: 2.6.12
419
419
  signing_key:
420
420
  specification_version: 4
421
421
  summary: The bridge between Calabash iOS and Xcode command-line tools like instruments