diff --git a/lib/xcodebuild/plugin.rb b/lib/xcodebuild/plugin.rb index 1a36487..fac7ae2 100644 --- a/lib/xcodebuild/plugin.rb +++ b/lib/xcodebuild/plugin.rb @@ -14,35 +14,77 @@ module Danger # class DangerXcodebuild < Plugin - # Allows you to specify an xcodebuild JSON file location to parse. - attr_accessor :xcodebuild_json - def initialize(arg) super @warning_count = 0 @error_count = 0 @test_failures_count = 0 + @xcodebuild_json = nil + end + + # Allows you to specify an xcodebuild JSON file location to parse. + attr_reader :json_file + + # Allows you to specify an xcodebuild JSON file location to parse. + # @return [void] + # + def json_file=(value) + @json_file = value + @xcodebuild_json = JSON.parse(File.open(value, 'r').read) end # Parses and exposes eventual warnings. # @return [warning_count] # def parse_warnings - + @warning_count = @xcodebuild_json["warnings"].count + @warning_count = @warning_count + @xcodebuild_json["ld_warnings"].count + @warning_count = @warning_count + @xcodebuild_json["compile_warnings"].count + if @warning_count > 0 + warning_string = @warning_count == 1 ? "warning" : "warnings" + warn("Please fix **#{@warning_count}** #{warning_string} 😒") + end + return @warning_count end # Parses and expose eventual errors. # @return [error_count] # def parse_errors - + errors = @xcodebuild_json["errors"].map {|x| "`#{x}`"} + errors += @xcodebuild_json["compile_errors"].map {|x| "`[#{x["file_path"].split("/").last}] #{x["reason"]}`"} + errors += @xcodebuild_json["file_missing_errors"].map {|x| "`[#{x["file_path"].split("/").last}] #{x["reason"]}`"} + errors += @xcodebuild_json["undefined_symbols_errors"].map {|x| "`#{x["message"]}`"} + errors += @xcodebuild_json["duplicate_symbols_errors"].map {|x| "`#{x["message"]}`"} + if errors.count > 0 + error_string = errors.count == 1 ? "error" : "errors" + fail("Build failed with **#{errors.count}** #{error_string} 🚨") + errors.each do |error| + fail(error) + end + end + @error_count = errors.count + return @error_count end # Parses and exposes eventual test failures. # @return [test_failures] # def parse_tests + test_failures = Array.new + @xcodebuild_json["tests_failures"].each do |key, value| + test_failures += value.map {|x| "`[#{x["file_path"].split("/").last}] [#{x["test_case"]}] #{x["reason"]}`"} + end + if test_failures.count > 0 + test_string = test_failures.count == 1 ? "error" : "errors" + fail("Test execution failed with **#{test_failures.count}** #{test_string} 🚨") + test_failures.each do |test_failure| + fail(test_failure) + end + end + @test_failures_count = test_failures.count + return @test_failures_count end # Prints "Perfect build 👍🏻" if everything is ok after parsing. diff --git a/spec/xcodebuild_spec.rb b/spec/xcodebuild_spec.rb index ebdd145..7030e84 100644 --- a/spec/xcodebuild_spec.rb +++ b/spec/xcodebuild_spec.rb @@ -17,7 +17,99 @@ module Danger it "is a perfect build" do expect(@xcodebuild.perfect_build).to be true - expect(@dangerfile.status_report[:messages]).to eq(["Perfect build 👍🏻"]) + expect(@dangerfile.status_report[:messages].first).to eq("Perfect build 👍🏻") + expect(@dangerfile.status_report[:errors]).to be_empty + expect(@dangerfile.status_report[:warnings]).to be_empty + expect(@dangerfile.status_report[:markdowns]).to be_empty + end + + describe 'with warnings' do + + before do + data = { + :warnings => ['warning1', 'warning2'], + :ld_warnings => ['ld_warnings'], + :compile_warnings => ['compile_warnings'] + }.to_json + + filename = 'xcodebuild_warnings.json' + allow(File).to receive(:open).with(filename, 'r').and_return(StringIO.new(data)) + + @xcodebuild.json_file = filename + end + + it "has to report warnings" do + expect(@xcodebuild.parse_warnings).to eq(4) + expect(@xcodebuild.perfect_build).to be false + expect(@dangerfile.status_report[:warnings].first).to eq("Please fix **4** warnings 😒") + expect(@dangerfile.status_report[:errors]).to be_empty + expect(@dangerfile.status_report[:messages]).to be_empty + expect(@dangerfile.status_report[:markdowns]).to be_empty + end + + end + + describe 'with errors' do + + before do + data = { + :errors => ['error1', 'error2'], + :compile_errors => [ + { :file_path => '/tmp/file1.m', :reason => 'reason1' }, + { :file_path => '/tmp/file2.m', :reason => 'reason2' } + ], + :file_missing_errors => [ + { :file_path => '/tmp/missing_file1.m', :reason => 'reason1' }, + { :file_path => '/tmp/missing_file2.m', :reason => 'reason2' } + ], + :undefined_symbols_errors => [{ :message => 'undefined_symbols' }], + :duplicate_symbols_errors => [{ :message => 'duplicate_symbols' }] + }.to_json + + filename = 'xcodebuild_errors.json' + allow(File).to receive(:open).with(filename, 'r').and_return(StringIO.new(data)) + + @xcodebuild.json_file = filename + end + + it "has to report errors" do + expect(@xcodebuild.parse_errors).to eq(8) + expect(@xcodebuild.perfect_build).to be false + expect(@dangerfile.status_report[:errors].count).to eq(8+1) + expect(@dangerfile.status_report[:errors].first).to eq("Build failed with **8** errors 🚨") + expect(@dangerfile.status_report[:warnings]).to be_empty + expect(@dangerfile.status_report[:messages]).to be_empty + expect(@dangerfile.status_report[:markdowns]).to be_empty + end + + end + + describe 'with tests failures' do + + before do + data = { + :tests_failures => { + :suite1 => [{ :file_path => '/tmp/file1.m', :test_case => "testCase1", :reason => 'reason1' }], + :suite2 => [{ :file_path => '/tmp/file2.m', :test_case => "testCase2", :reason => 'reason2' }] + } + }.to_json + + filename = 'xcodebuild_tests.json' + allow(File).to receive(:open).with(filename, 'r').and_return(StringIO.new(data)) + + @xcodebuild.json_file = filename + end + + it "has to report tests failures" do + expect(@xcodebuild.parse_tests).to eq(2) + expect(@xcodebuild.perfect_build).to be false + expect(@dangerfile.status_report[:errors].count).to eq(2+1) + expect(@dangerfile.status_report[:errors].first).to eq("Test execution failed with **2** errors 🚨") + expect(@dangerfile.status_report[:warnings]).to be_empty + expect(@dangerfile.status_report[:messages]).to be_empty + expect(@dangerfile.status_report[:markdowns]).to be_empty + end + end end