luffa 1.0.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.
@@ -0,0 +1,36 @@
1
+ require 'singleton'
2
+
3
+ module Luffa
4
+ class Simulator
5
+ def core_simulator_home_dir
6
+ @core_simulator_home_dir ||= File.expand_path('~/Library/Developer/CoreSimulator')
7
+ end
8
+
9
+ def core_simulator_device_dir(sim_udid=nil)
10
+ if sim_udid.nil?
11
+ @core_simulator_device_dir ||= File.expand_path(File.join(core_simulator_home_dir, 'Devices'))
12
+ else
13
+ File.expand_path(File.join(core_simulator_device_dir, sim_udid))
14
+ end
15
+ end
16
+
17
+ def core_simulator_device_containers_dir(sim_udid)
18
+ File.expand_path(File.join(core_simulator_device_dir(sim_udid), 'Containers'))
19
+ end
20
+
21
+ def core_simulator_for_xcode_version(idiom, form_factor, xcode_version)
22
+ if xcode_version < Luffa::Version.new('6.1')
23
+ ios_version = '8.0'
24
+ elsif xcode_version < Luffa::Version.new('6.2')
25
+ ios_version = '8.1'
26
+ elsif xcode_version < Luffa::Version.new('6.3')
27
+ ios_version = '8.2'
28
+ elsif xcode_version >= Luffa::Version.new('6.3')
29
+ ios_version = '8.3'
30
+ else
31
+ raise "Unsupported Xcode version: #{xcode_version}"
32
+ end
33
+ "#{idiom} #{form_factor} (#{ios_version} Simulator)"
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,93 @@
1
+ module Luffa
2
+ class XcodeInstall
3
+ attr :version
4
+ attr :path
5
+
6
+ def initialize(path)
7
+ Luffa::Xcode.with_developer_dir(path) do
8
+ @version = lambda {
9
+ xcode_build_output = `xcrun xcodebuild -version`.split(/\s/)[1]
10
+ Luffa::Version.new(xcode_build_output)
11
+ }.call
12
+
13
+ @path = path
14
+ end
15
+ end
16
+
17
+ def version_string
18
+ version.to_s
19
+ end
20
+
21
+ def == (other)
22
+ other.path == path && other.version == version
23
+ end
24
+ end
25
+
26
+ class Xcode
27
+
28
+ def self.with_developer_dir(developer_dir, &block)
29
+ original_developer_dir = Luffa::Environment.developer_dir
30
+ stripped = developer_dir.strip
31
+ begin
32
+ ENV['DEVELOPER_DIR'] = stripped
33
+ block.call
34
+ ensure
35
+ ENV['DEVELOPER_DIR'] = original_developer_dir
36
+ end
37
+ end
38
+
39
+ def self.with_xcode_install(xcode_install, &block)
40
+ self.with_developer_dir(xcode_install.path, &block)
41
+ end
42
+
43
+ def self.ios_version_incompatible_with_xcode_version?(ios_version, xcode_version)
44
+ [(ios_version >= Luffa::Version.new('8.0') && xcode_version < Luffa::Version.new('6.0')),
45
+ (ios_version >= Luffa::Version.new('8.1') && xcode_version < Luffa::Version.new('6.1')),
46
+ (ios_version >= Luffa::Version.new('8.2') && xcode_version < Luffa::Version.new('6.2')),
47
+ (ios_version >= Luffa::Version.new('8.3') && xcode_version < Luffa::Version.new('6.3'))].any?
48
+ end
49
+
50
+ def xcode_installs
51
+ @xcode_installs ||= lambda do
52
+ min_xcode_version = Luffa::Version.new('5.1.1')
53
+ active_xcode = Luffa::Xcode.new.active_xcode
54
+ xcodes = [active_xcode]
55
+ Dir.glob('/Xcode/*/*.app/Contents/Developer').each do |path|
56
+ xcode_version = path[/(\d\.\d(\.\d)?)/, 0]
57
+ if Luffa::Version.new(xcode_version) >= min_xcode_version
58
+ install = Luffa::XcodeInstall.new(path)
59
+ unless install == active_xcode
60
+ xcodes << install
61
+ end
62
+ end
63
+ end
64
+ xcodes
65
+ end.call
66
+ end
67
+
68
+ # The developer dir at the time the tests start.
69
+ #
70
+ # To change the active Xcode:
71
+ #
72
+ # $ DEVELOPER_DIR=/path/to/Xcode.app/Contents/Developer be rake spec
73
+ def active_xcode_dir
74
+ @active_xcode_dir ||= lambda {
75
+ env = Luffa::Environment.developer_dir
76
+ if env
77
+ env
78
+ else
79
+ # fall back to xcode-select
80
+ xcode_select_path
81
+ end
82
+ }.call
83
+ end
84
+
85
+ def xcode_select_path
86
+ @xcode_select_dir ||= `xcode-select --print-path`.strip
87
+ end
88
+
89
+ def active_xcode
90
+ @active_xcode ||= Luffa::XcodeInstall.new(active_xcode_dir)
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,21 @@
1
+ module Luffa
2
+ def self.log_unix_cmd(msg)
3
+ puts "\033[36mEXEC: #{msg}\033[0m" if msg
4
+ end
5
+
6
+ def self.log_pass(msg)
7
+ puts "\033[32mPASS: #{msg}\033[0m" if msg
8
+ end
9
+
10
+ def self.log_warn(msg)
11
+ puts "\033[34mWARN: #{msg}\033[0m"
12
+ end
13
+
14
+ def self.log_fail(msg)
15
+ puts "\033[31mFAIL: #{msg}\033[0m" if msg
16
+ end
17
+
18
+ def self.log_info(msg)
19
+ puts "\033[46mINFO: #{msg}\033[0m" if msg
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ require 'awesome_print'
2
+
3
+ # monkey patch for AwesomePrint + objects that implement '=='
4
+ module AwesomePrint
5
+ class Formatter
6
+ def awesome_self(object, type)
7
+ if @options[:raw] && object.instance_variables.any?
8
+ awesome_object(object)
9
+ elsif object.respond_to?(:to_hash)
10
+ awesome_hash(object.to_hash)
11
+ else
12
+ colorize(object.inspect.to_s, type)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module Kernel
2
+ def capture_stdout
3
+ out = StringIO.new
4
+ $stdout = out
5
+ yield
6
+ return out
7
+ ensure
8
+ $stdout = STDOUT
9
+ end
10
+
11
+ def capture_stderr
12
+ out = StringIO.new
13
+ $stderr = out
14
+ yield
15
+ return out
16
+ ensure
17
+ $stderr = STDERR
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require 'singleton'
2
+
3
+ module Luffa
4
+ class Retry
5
+ include Singleton
6
+
7
+ def launch_retries
8
+ @launch_retries ||= lambda {
9
+ Luffa::Environment.travis_ci? ? 8 : 2
10
+ }.call
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ module Luffa
2
+ def self.unix_command(cmd, opts={})
3
+ default_opts = {:pass_msg => nil,
4
+ :fail_msg => nil,
5
+ :exit_on_nonzero_status => true,
6
+ :env_vars => {},
7
+ :log_cmd => true,
8
+ :obscure_fields => []}
9
+ merged_opts = default_opts.merge(opts)
10
+
11
+ obscure_fields = merged_opts[:obscure_fields]
12
+
13
+ if not obscure_fields.empty? and merged_opts[:log_cmd]
14
+ obscured = cmd.split(' ').map do |token|
15
+ if obscure_fields.include? token
16
+ "#{token[0,1]}***#{token[token.length-1,1]}"
17
+ else
18
+ token
19
+ end
20
+ end
21
+ Luffa.log_unix_cmd obscured.join(' ')
22
+ elsif merged_opts[:log_cmd]
23
+ Luffa.log_unix_cmd cmd
24
+ end
25
+
26
+ exit_on_err = merged_opts[:exit_on_nonzero_status]
27
+ unless exit_on_err
28
+ system 'set +e'
29
+ end
30
+
31
+ env_vars = merged_opts[:env_vars]
32
+ res = system(env_vars, cmd)
33
+ exit_code = $?.exitstatus
34
+ if res
35
+ Luffa.log_pass merged_opts[:pass_msg]
36
+ else
37
+ Luffa.log_fail merged_opts[:fail_msg]
38
+ exit exit_code if exit_on_err
39
+ end
40
+ system 'set -e'
41
+ exit_code
42
+ end
43
+ end
@@ -0,0 +1,166 @@
1
+ module Luffa
2
+ VERSION = '1.0.0'
3
+
4
+ # A model of a software release version that can be used to compare two versions.
5
+ #
6
+ # Calabash and RunLoop try very hard to comply with Semantic Versioning rules.
7
+ # However, the semantic versioning spec is incompatible with RubyGem's patterns
8
+ # for pre-release gems.
9
+ #
10
+ # > "But returning to the practical: No release version of SemVer is compatible with Rubygems." - _David Kellum_
11
+ #
12
+ # Calabash and RunLoop version numbers will be in the form `<major>.<minor>.<patch>[.pre<N>]`.
13
+ #
14
+ # @see http://semver.org/
15
+ # @see http://gravitext.com/2012/07/22/versioning.html
16
+ class Version
17
+
18
+ # @!attribute [rw] major
19
+ # @return [Integer] the major version
20
+ attr_accessor :major
21
+
22
+ # @!attribute [rw] minor
23
+ # @return [Integer] the minor version
24
+ attr_accessor :minor
25
+
26
+ # @!attribute [rw] patch
27
+ # @return [Integer] the patch version
28
+ attr_accessor :patch
29
+
30
+ # @!attribute [rw] pre
31
+ # @return [Boolean] true if this is a pre-release version
32
+ attr_accessor :pre
33
+
34
+ # @!attribute [rw] pre_version
35
+ # @return [Integer] if this is a pre-release version, returns the
36
+ # pre-release version; otherwise this is nil
37
+ attr_accessor :pre_version
38
+
39
+ # Creates a new Version instance with all the attributes set.
40
+ #
41
+ # @example
42
+ # version = Version.new(0.10.1)
43
+ # version.major => 0
44
+ # version.minor => 10
45
+ # version.patch => 1
46
+ # version.pre => false
47
+ # version.pre_release => nil
48
+ #
49
+ # @example
50
+ # version = Version.new(1.6.3.pre5)
51
+ # version.major => 1
52
+ # version.minor => 6
53
+ # version.patch => 3
54
+ # version.pre => true
55
+ # version.pre_release => 5
56
+ #
57
+ # @param [String] version the version string to parse.
58
+ # @raise [ArgumentError] if version is not in the form 5, 6.1, 7.1.2, 8.2.3.pre1
59
+ def initialize(version)
60
+ tokens = version.strip.split('.')
61
+ count = tokens.count
62
+ if tokens.empty?
63
+ raise ArgumentError, "expected '#{version}' to be like 5, 6.1, 7.1.2, 8.2.3.pre1"
64
+ end
65
+
66
+ if count < 4 and tokens.any? { |elm| elm =~ /\D/ }
67
+ raise ArgumentError, "expected '#{version}' to be like 5, 6.1, 7.1.2, 8.2.3.pre1"
68
+ end
69
+
70
+ if count == 4
71
+ @pre = tokens[3]
72
+ pre_tokens = @pre.scan(/\D+|\d+/)
73
+ @pre_version = pre_tokens[1].to_i if pre_tokens.count == 2
74
+ end
75
+
76
+ @major, @minor, @patch = version.split('.').map(&:to_i)
77
+ end
78
+
79
+ # Returns an string representation of this version.
80
+ # @return [String] a string in the form `<major>.<minor>.<patch>[.pre<N>]`
81
+ def to_s
82
+ str = [major, minor, patch].compact.join('.')
83
+ str = "#{str}.#{pre}" if pre
84
+ str
85
+ end
86
+
87
+ # Compare this version to another for equality.
88
+ # @param [Version] other the version to compare against
89
+ # @return [Boolean] true if this Version is the same as `other`
90
+ def == (other)
91
+ Version.compare(self, other) == 0
92
+ end
93
+
94
+ # Compare this version to another for inequality.
95
+ # @param [Version] other the version to compare against
96
+ # @return [Boolean] true if this Version is not the same as `other`
97
+ def != (other)
98
+ Version.compare(self, other) != 0
99
+ end
100
+
101
+ # Is this version less-than another version?
102
+ # @param [Version] other the version to compare against
103
+ # @return [Boolean] true if this Version is less-than `other`
104
+ def < (other)
105
+ Version.compare(self, other) < 0
106
+ end
107
+
108
+ # Is this version greater-than another version?
109
+ # @param [Version] other the version to compare against
110
+ # @return [Boolean] true if this Version is greater-than `other`
111
+ def > (other)
112
+ Version.compare(self, other) > 0
113
+ end
114
+
115
+ # Is this version less-than or equal to another version?
116
+ # @param [Version] other the version to compare against
117
+ # @return [Boolean] true if this Version is less-than or equal `other`
118
+ def <= (other)
119
+ Version.compare(self, other) <= 0
120
+ end
121
+
122
+ # Is this version greater-than or equal to another version?
123
+ # @param [Version] other the version to compare against
124
+ # @return [Boolean] true if this Version is greater-than or equal `other`
125
+ def >= (other)
126
+ Version.compare(self, other) >= 0
127
+ end
128
+
129
+ # Compare version `a` to version `b`.
130
+ #
131
+ # @example
132
+ # compare Version.new(0.10.0), Version.new(0.9.0) => 1
133
+ # compare Version.new(0.9.0), Version.new(0.10.0) => -1
134
+ # compare Version.new(0.9.0), Version.new(0.9.0) => 0
135
+ #
136
+ # @return [Integer] an integer `(-1, 1)`
137
+ def self.compare(a, b)
138
+
139
+ if a.major != b.major
140
+ return a.major > b.major ? 1 : -1
141
+ end
142
+
143
+ if a.minor != b.minor
144
+ return a.minor.to_i > b.minor.to_i ? 1 : -1
145
+ end
146
+
147
+ if a.patch != b.patch
148
+ return a.patch.to_i > b.patch.to_i ? 1 : -1
149
+ end
150
+
151
+ return -1 if a.pre and (not a.pre_version) and b.pre_version
152
+ return 1 if a.pre_version and b.pre and (not b.pre_version)
153
+
154
+ return -1 if a.pre and (not b.pre)
155
+ return 1 if (not a.pre) and b.pre
156
+
157
+ return -1 if a.pre_version and (not b.pre_version)
158
+ return 1 if (not a.pre_version) and b.pre_version
159
+
160
+ if a.pre_version != b.pre_version
161
+ return a.pre_version.to_i > b.pre_version.to_i ? 1 : -1
162
+ end
163
+ 0
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,13 @@
1
+ module Luffa
2
+ module Debug
3
+ def self.with_debugging(&block)
4
+ original_value = ENV['DEBUG']
5
+ ENV['DEBUG'] = '1'
6
+ begin
7
+ block.call
8
+ ensure
9
+ ENV['DEBUG'] = original_value
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>allow-root</key>
6
+ <true/>
7
+ <key>authenticate-user</key>
8
+ <true/>
9
+ <key>class</key>
10
+ <string>user</string>
11
+ <key>comment</key>
12
+ <string>Rights for Instruments</string>
13
+ <key>created</key>
14
+ <real>409022991.255041</real>
15
+ <key>group</key>
16
+ <string>admin</string>
17
+ <key>identifier</key>
18
+ <string>com.apple.dt.instruments.dtsecurity.xpc</string>
19
+ <key>modified</key>
20
+ <real>409022991.255041</real>
21
+ <key>requirement</key>
22
+ <string>identifier "com.apple.dt.instruments.dtsecurity.xpc" and anchor apple</string>
23
+ <key>session-owner</key>
24
+ <false/>
25
+ <key>shared</key>
26
+ <true/>
27
+ <key>timeout</key>
28
+ <integer>36000</integer>
29
+ <key>tries</key>
30
+ <integer>10000</integer>
31
+ <key>version</key>
32
+ <integer>0</integer>
33
+ </dict>
34
+ </plist>