xcodebuild-rb 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.
@@ -0,0 +1 @@
1
+ require_relative 'xcode_build'
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+ require 'xcode_build/tasks/build_task'
3
+
4
+ describe XcodeBuild::Tasks::BuildTask do
5
+ before { Rake::Task.clear }
6
+
7
+ it "defines an build task in the default namespace (xcode)" do
8
+ XcodeBuild::Tasks::BuildTask.new
9
+ Rake::Task["xcode:build"].should be_instance_of(Rake::Task)
10
+ end
11
+
12
+ it "defines an build task in a custom namespace" do
13
+ XcodeBuild::Tasks::BuildTask.new(:test)
14
+ Rake::Task["test:build"].should be_instance_of(Rake::Task)
15
+ end
16
+
17
+ it "defines a clean task" do
18
+ XcodeBuild::Tasks::BuildTask.new
19
+ Rake::Task["xcode:clean"].should be_instance_of(Rake::Task)
20
+ end
21
+
22
+ it "defines a cleanbuild" do
23
+ XcodeBuild::Tasks::BuildTask.new
24
+ Rake::Task["xcode:cleanbuild"].should be_instance_of(Rake::Task)
25
+ end
26
+
27
+ context "#build_opts" do
28
+ let(:task) { XcodeBuild::Tasks::BuildTask.new }
29
+
30
+ it "includes the project" do
31
+ task.project_name = "TestProject.xcproject"
32
+ task.build_opts.should include("-project TestProject.xcproject")
33
+ end
34
+
35
+ it "includes the target" do
36
+ task.target = "TestTarget"
37
+ task.build_opts.should include("-target TestTarget")
38
+ end
39
+
40
+ it "includes the workspace" do
41
+ task.workspace = "SomeWorkspace.xcworkspace"
42
+ task.build_opts.should include("-workspace SomeWorkspace.xcworkspace")
43
+ end
44
+
45
+ it "includes the scheme" do
46
+ task.scheme = "TestScheme"
47
+ task.build_opts.should include("-scheme TestScheme")
48
+ end
49
+
50
+ it "includes the configuration" do
51
+ task.configuration = "TestConfiguration"
52
+ task.build_opts.should include("-configuration TestConfiguration")
53
+ end
54
+
55
+ it "includes the arch" do
56
+ task.arch = "i386"
57
+ task.build_opts.should include("-arch i386")
58
+ end
59
+
60
+ it "includes the sdk" do
61
+ task.sdk = "iphonesimulator5.0"
62
+ task.build_opts.should include("-sdk iphonesimulator5.0")
63
+ end
64
+
65
+ it "includes the xcconfig path" do
66
+ task.xcconfig = "path/to/config.xcconfig"
67
+ task.build_opts.should include("-xcconfig path/to/config.xcconfig")
68
+ end
69
+ end
70
+
71
+ context "build task" do
72
+ it "runs xcodebuild with the configured build_opts" do
73
+ task = XcodeBuild::Tasks::BuildTask.new do |task|
74
+ task.project_name = "TestProject.xcproject"
75
+ task.configuration = "Debug"
76
+ end
77
+
78
+ XcodeBuild.should_receive(:run).with(task.build_opts.join(" "), anything())
79
+ task.run(:build)
80
+ end
81
+
82
+ it "defaults to outputting the raw output to STDOUT" do
83
+ task = XcodeBuild::Tasks::BuildTask.new
84
+ XcodeBuild.should_receive(:run).with(anything(), STDOUT)
85
+ task.run(:build)
86
+ end
87
+
88
+ it "uses a custom output buffer if specified" do
89
+ buffer = stub('output buffer')
90
+ task = XcodeBuild::Tasks::BuildTask.new do |t|
91
+ t.output_to = buffer
92
+ end
93
+ XcodeBuild.should_receive(:run).with(anything(), buffer)
94
+ task.run(:build)
95
+ end
96
+
97
+ it "outputs the translator delegating to the reporter if formatter is set" do
98
+ formatter = stub('formatter')
99
+ task = XcodeBuild::Tasks::BuildTask.new do |t|
100
+ t.formatter = formatter
101
+ end
102
+ XcodeBuild.should_receive(:run).with(anything(),
103
+ output_translator_delegating_to(instance_of(XcodeBuild::Reporter)))
104
+ task.run(:build)
105
+ end
106
+
107
+ it "changes directory if invoke_from_within is set" do
108
+ task = XcodeBuild::Tasks::BuildTask.new do |task|
109
+ task.invoke_from_within = "foo/bar"
110
+ end
111
+
112
+ Dir.should_receive(:chdir).with("foo/bar").and_yield
113
+ XcodeBuild.should_receive(:run)
114
+ task.run(:build)
115
+ end
116
+ end
117
+
118
+ context "clean task" do
119
+ it "runs xcodebuild with the 'clean' action" do
120
+ task = XcodeBuild::Tasks::BuildTask.new
121
+ XcodeBuild.should_receive(:run).with("clean", anything())
122
+ task.run(:clean)
123
+ end
124
+ end
125
+
126
+ context "cleanbuild task" do
127
+ it "runs the clean task and then the build task" do
128
+ task = XcodeBuild::Tasks::BuildTask.new
129
+ XcodeBuild.should_receive(:run).with("clean", anything()) do
130
+ XcodeBuild.should_receive(:run).with("", anything())
131
+ end
132
+ task.run(:cleanbuild)
133
+ end
134
+ end
135
+
136
+ RSpec::Matchers.define :output_translator_delegating_to do |expected|
137
+ match do |actual|
138
+ actual.should be_instance_of(XcodeBuild::OutputTranslator)
139
+ expected.should == actual.delegate
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe XcodeBuild::OutputTranslator do
4
+ let(:delegate) { mock('delegate') }
5
+ let(:translator) { XcodeBuild::OutputTranslator.new(delegate, ignore_global_translations: true) }
6
+
7
+ it "notifies the delegate of each line received (to assist additional processing elsewhere)" do
8
+ delegate.should_receive(:beginning_translation_of_line).with("the line")
9
+ translator << "the line"
10
+ end
11
+
12
+ it "treats :beginning_translation_of_line as an optional delegate message" do
13
+ delegate_should_not_respond_to(:beginning_translation_of_line)
14
+ delegate.should_not_receive(:beginning_translation_of_line)
15
+ translator << "anything"
16
+ end
17
+
18
+ it "asks each translation to attempt to translate a line" do
19
+ translator.use_translation(FakeTranslation.dup)
20
+ translator.use_translation(FakeTranslation.dup)
21
+
22
+ translator << "a line"
23
+
24
+ translator.translations.each do |translation|
25
+ translation.should have_attempted_to_translate("a line")
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ module FakeTranslation
32
+ def attempt_to_translate(line)
33
+ @attempted_to_translate = line
34
+ end
35
+
36
+ def has_attempted_to_translate?(line)
37
+ line == @attempted_to_translate
38
+ end
39
+ end
40
+
41
+ def delegate_should_respond_to(method)
42
+ mock_should_respond?(delegate, method, true)
43
+ end
44
+
45
+ def delegate_should_not_respond_to(method)
46
+ mock_should_respond?(delegate, method, false)
47
+ end
48
+
49
+ def mock_should_respond?(mock, method, should_respond)
50
+ mock.stub(:respond_to?).with(method).and_return(should_respond)
51
+ end
52
+ end
@@ -0,0 +1,305 @@
1
+ require 'spec_helper'
2
+
3
+ describe XcodeBuild::Reporting::BuildReporting do
4
+ let(:reporter) { XcodeBuild::Reporter.new }
5
+
6
+ shared_examples_for "any build" do
7
+ it "reports the build target" do
8
+ reporter.build.target.should == "ExampleProject"
9
+ end
10
+
11
+ it "reports the project name" do
12
+ reporter.build.project_name.should == "ExampleProject"
13
+ end
14
+
15
+ it "reports the build configuration" do
16
+ reporter.build.configuration.should == "Release"
17
+ end
18
+
19
+ it "reports if the build configuration was the default" do
20
+ reporter.build.should be_default_configuration
21
+ end
22
+ end
23
+
24
+ context "when receiving events" do
25
+ let(:delegate) { mock('reporter delegate').as_null_object }
26
+
27
+ before do
28
+ reporter.delegate = delegate
29
+
30
+ # let's assume it responds to all delegate methods
31
+ delegate.stub(:respond_to?).with(anything).and_return(true)
32
+ end
33
+
34
+ it "notifies it's delegate that a build has started" do
35
+ delegate.should_receive(:build_started).with instance_of(XcodeBuild::Reporting::BuildReporting::Build)
36
+
37
+ event({:build_started=>
38
+ {:target=>"ExampleProject",
39
+ :project=>"ExampleProject",
40
+ :configuration=>"Release",
41
+ :default=>true}})
42
+ end
43
+
44
+ it "notifies it's delegate when a build step begins" do
45
+ assume_build_started
46
+
47
+ delegate.should_receive(:build_step_started).with instance_of(XcodeBuild::BuildStep)
48
+
49
+ event({:build_step=>
50
+ {:type=>"CpResource",
51
+ :arguments=>
52
+ ["/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/ResourceRules.plist",
53
+ "build/Release-iphoneos/ExampleProject.app/ResourceRules.plist"]}})
54
+ end
55
+
56
+ it "notifies it's delegate when a previous build step finishes" do
57
+ assume_build_started
58
+
59
+ event({:build_step=>
60
+ {:type=>"CpResource",
61
+ :arguments=>
62
+ ["/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/ResourceRules.plist",
63
+ "build/Release-iphoneos/ExampleProject.app/ResourceRules.plist"]}})
64
+
65
+ delegate.should_receive(:build_step_finished).with reporter.build.last_step
66
+
67
+ event({:build_step=>
68
+ {:type=>"CpResource",
69
+ :arguments=>
70
+ ["/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/ResourceRules.plist",
71
+ "build/Release-iphoneos/ExampleProject.app/ResourceRules.plist"]}})
72
+ end
73
+
74
+ it "notifies it's delegate when the last build step finishes and the build is successful" do
75
+ assume_build_started
76
+
77
+ event({:build_step=>
78
+ {:type=>"CpResource",
79
+ :arguments=>
80
+ ["/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/ResourceRules.plist",
81
+ "build/Release-iphoneos/ExampleProject.app/ResourceRules.plist"]}})
82
+
83
+ delegate.should_receive(:build_step_finished).with reporter.build.last_step
84
+
85
+ event({:build_succeeded=>{}})
86
+ end
87
+
88
+ it "notifies it's delegate when the last build step finishes and the build fails" do
89
+ assume_build_started
90
+
91
+ event({:build_step=>
92
+ {:type=>"CpResource",
93
+ :arguments=>
94
+ ["/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/ResourceRules.plist",
95
+ "build/Release-iphoneos/ExampleProject.app/ResourceRules.plist"]}})
96
+
97
+ delegate.should_receive(:build_step_finished).with reporter.build.last_step
98
+
99
+ event({:build_succeeded=>{}})
100
+ end
101
+
102
+ it "notifies it's delegate that the build has finished when it is successful" do
103
+ assume_build_started
104
+ delegate.should_receive(:build_finished).with(reporter.build)
105
+ event({:build_succeeded=>{}})
106
+ end
107
+
108
+ it "notifies it's delegate that the build has finished when it fails" do
109
+ assume_build_started
110
+ delegate.should_receive(:build_finished).with(reporter.build)
111
+ event({:build_failed=>{}})
112
+ end
113
+
114
+ it "tracks the time a build takes" do
115
+ Timecop.travel(Chronic.parse("10 seconds ago")) do
116
+ event({:build_started=>
117
+ {:target=>"ExampleProject",
118
+ :project=>"ExampleProject",
119
+ :configuration=>"Release",
120
+ :default=>true}})
121
+
122
+ Timecop.travel(Chronic.parse("5 seconds from now")) do
123
+ event({:build_succeeded=>{}})
124
+ end
125
+ end
126
+
127
+ reporter.build.duration.should be_within(0.01).of(5)
128
+ end
129
+ end
130
+
131
+ context "once a build has started" do
132
+ before do
133
+ event({:build_started=>
134
+ {:target=>"ExampleProject",
135
+ :project=>"ExampleProject",
136
+ :configuration=>"Release",
137
+ :default=>true}})
138
+ end
139
+
140
+ it "reports that the build is running" do
141
+ reporter.build.should be_running
142
+ end
143
+
144
+ it "reports that the build is not finished" do
145
+ reporter.build.should_not be_finished
146
+ end
147
+ end
148
+
149
+ context "once a simple, successful build has finished" do
150
+ before do
151
+ event({:build_started=>
152
+ {:target=>"ExampleProject",
153
+ :project=>"ExampleProject",
154
+ :configuration=>"Release",
155
+ :default=>true}})
156
+
157
+ event({:build_step=>
158
+ {:type=>"CpResource",
159
+ :arguments=>
160
+ ["/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/ResourceRules.plist",
161
+ "build/Release-iphoneos/ExampleProject.app/ResourceRules.plist"]}})
162
+
163
+ event({:build_step=>
164
+ {:type=>"ProcessInfoPlistFile",
165
+ :arguments=>
166
+ ["build/Release-iphoneos/ExampleProject.app/Info.plist",
167
+ "ExampleProject/ExampleProject-Info.plist"]}})
168
+
169
+ event({:build_step=>
170
+ {:type=>"CompileC",
171
+ :arguments=>
172
+ ["build/ExampleProject.build/Release-iphoneos/ExampleProject.build/Objects-normal/armv7/AppDelegate.o",
173
+ "ExampleProject/AppDelegate.m",
174
+ "normal",
175
+ "armv7",
176
+ "objective-c",
177
+ "com.apple.compilers.llvm.clang.1_0.compiler"]}})
178
+
179
+ event({:build_succeeded=>{}})
180
+ end
181
+
182
+ it_behaves_like "any build"
183
+
184
+ it "reports that the build was successful" do
185
+ reporter.build.should be_successful
186
+ end
187
+
188
+ it "reports the total number of completed build steps" do
189
+ reporter.build.should have(3).steps_completed
190
+ end
191
+
192
+ it "reports that the build is not running" do
193
+ reporter.build.should_not be_running
194
+ end
195
+
196
+ it "reports that the build is finished" do
197
+ reporter.build.should be_finished
198
+ end
199
+ end
200
+
201
+ context "once a simple, failed build has finished" do
202
+ before do
203
+ event({:build_started=>
204
+ {:target=>"ExampleProject",
205
+ :project=>"ExampleProject",
206
+ :configuration=>"Release",
207
+ :default=>true}})
208
+
209
+ event({:build_step=>
210
+ {:type=>"CompileC",
211
+ :arguments=>
212
+ ["build/ExampleProject.build/Release-iphoneos/ExampleProject.build/Objects-normal/armv7/AppDelegate.o",
213
+ "ExampleProject/AppDelegate.m",
214
+ "normal",
215
+ "armv7",
216
+ "objective-c",
217
+ "com.apple.compilers.llvm.clang.1_0.compiler"]}})
218
+
219
+ event({:build_error_detected=>
220
+ {:file=>
221
+ "/Users/luke/Code/mine/xcodebuild/resources/ExampleProject/ExampleProject/main.m",
222
+ :line=>16,
223
+ :char=>42,
224
+ :message=>"expected ';' after expression [1]"}})
225
+
226
+ event({:build_step=>
227
+ {:type=>"CompileC",
228
+ :arguments=>
229
+ ["build/ExampleProject.build/Release-iphoneos/ExampleProject.build/Objects-normal/armv7/AppDelegate.o",
230
+ "ExampleProject/AppDelegate.m",
231
+ "normal",
232
+ "armv7",
233
+ "objective-c",
234
+ "com.apple.compilers.llvm.clang.1_0.compiler"]}})
235
+
236
+ event({:build_failed=>{}})
237
+
238
+ event({:build_step_failed=>
239
+ {:type=>"CompileC",
240
+ :arguments=>
241
+ ["build/ExampleProject.build/Release-iphoneos/ExampleProject.build/Objects-normal/armv7/AppDelegate.o",
242
+ "ExampleProject/AppDelegate.m",
243
+ "normal",
244
+ "armv7",
245
+ "objective-c",
246
+ "com.apple.compilers.llvm.clang.1_0.compiler"]}})
247
+ end
248
+
249
+ it_behaves_like "any build"
250
+
251
+ it "reports that the build was a failure" do
252
+ reporter.build.should be_failed
253
+ end
254
+
255
+ it "reports the total number of completed build steps" do
256
+ reporter.build.should have(2).steps_completed
257
+ end
258
+
259
+ it "reports the total number of failed build steps" do
260
+ reporter.build.should have(1).failed_steps
261
+ reporter.build.failed_steps.first.tap do |step|
262
+ step.type.should == "CompileC"
263
+ end
264
+ end
265
+
266
+ it "reports the errors for each failed build step" do
267
+ reporter.build.failed_steps.first.should have(1).errors
268
+ reporter.build.failed_steps.first.errors.first.tap do |error|
269
+ error.file.should == "/Users/luke/Code/mine/xcodebuild/resources/ExampleProject/ExampleProject/main.m"
270
+ error.line.should == 16
271
+ error.char.should == 42
272
+ error.message.should == "expected ';' after expression [1]"
273
+ end
274
+ end
275
+
276
+ it "reports that the build is not running" do
277
+ reporter.build.should_not be_running
278
+ end
279
+
280
+ it "reports that the build is finished" do
281
+ reporter.build.should be_finished
282
+ end
283
+ end
284
+
285
+ private
286
+
287
+ def event(event_data)
288
+ message = event_data.keys.first
289
+ params = event_data.values.first
290
+
291
+ if params.any?
292
+ reporter.send(message, params)
293
+ else
294
+ reporter.send(message)
295
+ end
296
+ end
297
+
298
+ def assume_build_started
299
+ event({:build_started=>
300
+ {:target=>"ExampleProject",
301
+ :project=>"ExampleProject",
302
+ :configuration=>"Release",
303
+ :default=>true}})
304
+ end
305
+ end