Skip to content

Instantly share code, notes, and snippets.

@agross
Last active December 19, 2015 15:58
Show Gist options
  • Save agross/5979972 to your computer and use it in GitHub Desktop.
Save agross/5979972 to your computer and use it in GitHub Desktop.
class TeamCity
def self.running?
ENV.include? 'TEAMCITY_PROJECT_NAME'
end
def self.method_missing(method, *args, &block)
return unless running?
message_name = camel_case method.to_s
publish message_name, args[0]
end
private
def self.camel_case(string)
string
.split('_')
.inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }
.join
end
def self.publish(message_name, args)
args = [] << message_name << escaped_array_of(args)
args = args.flatten.reject(&:nil?)
puts "##teamcity[#{args.join(' ')}]"
end
def self.escape(string)
string
.gsub(/\|/, "||")
.gsub(/'/, "|'")
.gsub(/\r/, "|r")
.gsub(/\n/, "|n")
.gsub(/\u0085/, "|x")
.gsub(/\u2028/, "|l")
.gsub(/\u2029/, "|p")
.gsub(/\[/, "|[")
.gsub(/\]/, "|]")
end
def self.escaped_array_of(args)
return [] if args.nil?
if args.is_a? Hash
args.map {
|key, value| "#{key.to_s}='#{escape value.to_s}'"
}
else
"'#{escape args}'"
end
end
end
require 'tasks/teamcity'
describe "TeamCity service messages" do
context "when running outside TeamCity" do
before(:all) do
@original_project = ENV['TEAMCITY_PROJECT_NAME']
ENV.delete 'TEAMCITY_PROJECT_NAME'
end
after(:all) do
ENV['TEAMCITY_PROJECT_NAME'] = @original_project
end
it "should not publish messages" do
TeamCity.running?.should == false
end
end
context "when running inside TeamCity" do
before(:all) do
@original_project = ENV['TEAMCITY_PROJECT_NAME']
ENV['TEAMCITY_PROJECT_NAME'] = "foo"
end
after(:all) do
ENV['TEAMCITY_PROJECT_NAME'] = @original_project
end
it "should publish messages" do
TeamCity.running?.should == true
end
describe "service messages" do
describe "escaping" do
context "when publishing messages with special characters" do
it "should escape apostrophes" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|'']")
TeamCity.progress_start "'"
end
it "should escape line feeds" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|n']")
TeamCity.progress_start "\n"
end
it "should escape carriage returns" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|r']")
TeamCity.progress_start "\r"
end
it "should escape next lines" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|x']")
TeamCity.progress_start "\u0085"
end
it "should escape line separators" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|l']")
TeamCity.progress_start "\u2028"
end
it "should escape paragraph separators" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|p']")
TeamCity.progress_start "\u2029"
end
it "should escape vertical bars" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '||']")
TeamCity.progress_start '|'
end
it "should escape opening brackets" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|[']")
TeamCity.progress_start '['
end
it "should escape closing brackets" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|]']")
TeamCity.progress_start ']'
end
it "should escape all special characters" do
$stdout.should_receive(:puts).with("##teamcity[progressStart '|[|r|||n|]']")
TeamCity.progress_start "[\r|\n]"
end
end
end
describe "messages" do
context "when reporting a message without parameters" do
it "should print the service message" do
$stdout.should_receive(:puts).with("##teamcity[enableServiceMessages]")
TeamCity.enable_service_messages
end
end
context "when reporting a message with an unnamed parameter" do
it "should print the service message" do
$stdout.should_receive(:puts).with("##teamcity[progressMessage 'the message']")
TeamCity.progress_message "the message"
end
end
context "when reporting a message with a named parameter" do
it "should print the service message" do
$stdout.should_receive(:puts).with("##teamcity[blockOpened name='block name']")
TeamCity.block_opened({ :name => "block name" })
end
end
context "when reporting a message with multiple named parameters" do
it "should print the service message" do
$stdout.should_receive(:puts).with("##teamcity[testStarted name='test name' captureStandardOutput='true']")
TeamCity.test_started ({ :name => "test name", :captureStandardOutput => true})
end
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment