Skip to content

Instantly share code, notes, and snippets.

@agross agross/teamcity.rb
Last active Dec 19, 2015

Embed
What would you like to do?
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
You can’t perform that action at this time.