From 196d7badfae5692bfe7dd79e4559f5b41eea5761 Mon Sep 17 00:00:00 2001
From: Markus Reiter <me@reitermark.us>
Date: Tue, 8 Sep 2020 19:23:32 +0200
Subject: [PATCH] Improve RSpec annotations.

---
 Library/Homebrew/test/spec_helper.rb          | 16 ++++++------
 .../Homebrew/test/support/github_formatter.rb | 25 +++++++++++++++++--
 Library/Homebrew/utils/github/actions.rb      |  8 +++---
 3 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb
index 17d5c8e2ba..0408ea72a4 100644
--- a/Library/Homebrew/test/spec_helper.rb
+++ b/Library/Homebrew/test/spec_helper.rb
@@ -95,15 +95,15 @@ RSpec.configure do |config|
   config.include(Test::Helper::OutputAsTTY)
 
   config.before(:each, :needs_compat) do
-    skip "Requires compatibility layer." if ENV["HOMEBREW_NO_COMPAT"]
+    skip "Requires the compatibility layer." if ENV["HOMEBREW_NO_COMPAT"]
   end
 
   config.before(:each, :needs_linux) do
-    skip "Not on Linux." unless OS.linux?
+    skip "Not running on Linux." unless OS.linux?
   end
 
   config.before(:each, :needs_macos) do
-    skip "Not on macOS." unless OS.mac?
+    skip "Not running on macOS." unless OS.mac?
   end
 
   config.before(:each, :needs_java) do
@@ -113,11 +113,11 @@ RSpec.configure do |config|
     else
       which("java")
     end
-    skip "Java not installed." unless java_installed
+    skip "Java is not installed." unless java_installed
   end
 
   config.before(:each, :needs_python) do
-    skip "Python not installed." unless which("python")
+    skip "Python is not installed." unless which("python")
   end
 
   config.before(:each, :needs_network) do
@@ -125,7 +125,7 @@ RSpec.configure do |config|
   end
 
   config.before(:each, :needs_svn) do
-    skip "subversion not installed." unless quiet_system "#{HOMEBREW_SHIMS_PATH}/scm/svn", "--version"
+    skip "Subversion is not installed." unless quiet_system "#{HOMEBREW_SHIMS_PATH}/scm/svn", "--version"
 
     svn_paths = PATH.new(ENV["PATH"])
     if OS.mac?
@@ -135,7 +135,7 @@ RSpec.configure do |config|
 
     svn = which("svn", svn_paths)
     svnadmin = which("svnadmin", svn_paths)
-    skip "subversion not installed." if !svn || !svnadmin
+    skip "Subversion is not installed." if !svn || !svnadmin
 
     ENV["PATH"] = PATH.new(ENV["PATH"])
                       .append(svn.dirname)
@@ -143,7 +143,7 @@ RSpec.configure do |config|
   end
 
   config.before(:each, :needs_unzip) do
-    skip "unzip not installed." unless which("unzip")
+    skip "UnZip is not installed." unless which("unzip")
   end
 
   config.around do |example|
diff --git a/Library/Homebrew/test/support/github_formatter.rb b/Library/Homebrew/test/support/github_formatter.rb
index 94b57dcece..4b4aac9045 100644
--- a/Library/Homebrew/test/support/github_formatter.rb
+++ b/Library/Homebrew/test/support/github_formatter.rb
@@ -9,6 +9,13 @@ module RSpec
     class Formatter < RSpec::Core::Formatters::BaseFormatter
       RSpec::Core::Formatters.register self, :example_failed, :example_pending
 
+      def self.escape(string)
+        # See https://github.community/t/set-output-truncates-multiline-strings/16852/3.
+        string.gsub("%", "%25")
+              .gsub("\n", "%0A")
+              .gsub("\r", "%0D")
+      end
+
       def self.relative_path(path)
         if (workspace = ENV["GITHUB_WORKSPACE"])
           workspace = "#{File.realpath(workspace)}#{File::SEPARATOR}"
@@ -23,13 +30,27 @@ module RSpec
       def example_failed(failure)
         file, line = failure.example.location.split(":")
         file = self.class.relative_path(file)
-        output.puts "\n::error file=#{file},line=#{line}::#{failure.message_lines.join("%0A")}"
+
+        description = failure.example.full_description
+        message = failure.message_lines.join("\n")
+        annotation = "#{description}:\n\n#{message}"
+
+        output.puts "\n::error file=#{file},line=#{line}::#{self.class.escape(annotation)}"
       end
 
       def example_pending(pending)
         file, line = pending.example.location.split(":")
         file = self.class.relative_path(file)
-        output.puts "\n::warning file=#{file},line=#{line}::#{pending.example.full_description}"
+
+        description = pending.example.full_description
+        message = if pending.example.skip
+          "Skipped: #{pending.example.execution_result.pending_message}"
+        else
+          "Pending: #{pending.example.execution_result.pending_message}"
+        end
+        annotation = "#{description}:\n\n#{message}"
+
+        output.puts "\n::warning file=#{file},line=#{line}::#{self.class.escape(annotation)}"
       end
     end
   end
diff --git a/Library/Homebrew/utils/github/actions.rb b/Library/Homebrew/utils/github/actions.rb
index 646945b428..e897ae5b54 100644
--- a/Library/Homebrew/utils/github/actions.rb
+++ b/Library/Homebrew/utils/github/actions.rb
@@ -6,10 +6,10 @@ module GitHub
   # @api private
   module Actions
     def self.escape(string)
-      string.gsub(/\r/, "%0D")
-            .gsub(/\n/, "%0A")
-            .gsub(/]/, "%5D")
-            .gsub(/;/, "%3B")
+      # See https://github.community/t/set-output-truncates-multiline-strings/16852/3.
+      string.gsub("%", "%25")
+            .gsub("\n", "%0A")
+            .gsub("\r", "%0D")
     end
 
     # Helper class for formatting annotations on GitHub Actions.
-- 
GitLab