Class: Snapshot::TestCommandGenerator

Inherits:
TestCommandGeneratorBase show all
Defined in:
snapshot/lib/snapshot/test_command_generator.rb

Overview

Responsible for building the fully working xcodebuild command Xcode 9 introduced the ability to run tests in parallel on multiple simulators This TestCommandGenerator constructs the appropriate ‘xcodebuild` command to be used for executing simultaneous tests

Class Method Summary collapse

Methods inherited from TestCommandGeneratorBase

actions, build_settings, derived_data_path, device_udid, find_device, initialize, options, prefix, project_path_array, resolve_result_bundle_path, suffix, xcodebuild_log_path

Class Method Details

.destination(devices) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'snapshot/lib/snapshot/test_command_generator.rb', line 41

def destination(devices)
  unless verify_devices_share_os(devices)
    UI.user_error!('All devices provided to snapshot should run the same operating system')
  end
  # on Mac we will always run on host machine, so should specify only platform
  return ["-destination 'platform=macOS'"] if devices.first.to_s =~ /^Mac/

  os = devices.first.to_s =~ /^Apple TV/ ? "tvOS" : "iOS"

  os_version = Snapshot.config[:ios_version] || Snapshot::LatestOsVersion.version(os)

  destinations = devices.map do |d|
    device = find_device(d, os_version)
    if device.nil?
      UI.user_error!("No device found named '#{d}' for version '#{os_version}'") if device.nil?
    elsif device.os_version != os_version
      UI.important("Using device named '#{device.name}' with version '#{device.os_version}' because no match was found for version '#{os_version}'")
    end
    "-destination 'platform=#{os} Simulator,name=#{device.name},OS=#{device.os_version}'"
  end

  return [destinations.join(' ')]
end

.generate(devices: nil, language: nil, locale: nil, log_path: nil) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
# File 'snapshot/lib/snapshot/test_command_generator.rb', line 11

def generate(devices: nil, language: nil, locale: nil, log_path: nil)
  parts = prefix
  parts << "xcodebuild"
  parts += options(language, locale)
  parts += destination(devices)
  parts += build_settings
  parts += actions
  parts += suffix
  parts += pipe(log_path: log_path)

  return parts
end

.pipe(log_path: nil) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'snapshot/lib/snapshot/test_command_generator.rb', line 24

def pipe(log_path: nil)
  tee_command = ['tee']
  tee_command << '-a' if log_path && File.exist?(log_path)
  tee_command << log_path.shellescape if log_path

  pipe = ["| #{tee_command.join(' ')}"]
  if Snapshot.config[:disable_xcpretty]
    return pipe
  end

  xcpretty = "xcpretty #{Snapshot.config[:xcpretty_args]}"
  xcpretty << "--no-color" if Helper.colors_disabled?
  pipe << "| #{xcpretty}"
  pipe << "> /dev/null" if Snapshot.config[:suppress_xcode_output]
  return pipe
end

.verify_devices_share_os(device_names) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'snapshot/lib/snapshot/test_command_generator.rb', line 65

def verify_devices_share_os(device_names)
  # Get device types based off of device name
  devices = get_device_type_with_simctl(device_names)

  # Check each device to see if it is an iOS device
  all_ios = devices.map do |device|
    device = device.downcase
    device.include?('iphone') || device.include?('ipad')
  end
  # Return true if all devices are iOS devices
  return true unless all_ios.include?(false)

  all_tvos = devices.map do |device|
    device = device.downcase
    device.include?('apple tv')
  end
  # Return true if all devices are iOS devices
  return true unless all_tvos.include?(false)

  # There should only be more than 1 device type if
  # it is iOS or tvOS, therefore, if there is more than 1
  # device in the array, and they are not all iOS or tvOS
  # as checked above, that would imply that this is a mixed bag
  return devices.count == 1
end