bamboo-client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bamboo-client.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010-2011 Jari Bakken
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,4 @@
1
+ Ruby clients for Bamboo's REST APIs:
2
+
3
+ * http://confluence.atlassian.com/display/BAMBOO/Bamboo+Remote+API (deprecated)
4
+ * http://confluence.atlassian.com/display/BAMBOO/Bamboo+REST+APIs (new and shiny)
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec/core/rake_task"
5
+ RSpec::Core::RakeTask.new
6
+
7
+ require 'cucumber/rake/task'
8
+ Cucumber::Rake::Task.new do |t|
9
+ t.profile = 'default'
10
+ end
11
+
12
+ task :default => [:spec, :cucumber]
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "bamboo-client/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "bamboo-client"
7
+ s.version = Bamboo::Client::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jari Bakken"]
10
+ s.email = ["jari.bakken@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Ruby client for Atlassian Bamboo's REST APIs}
13
+ s.description = %q{Ruby client for Atlassian Bamboo's REST APIs}
14
+
15
+ s.rubyforge_project = "bamboo-client"
16
+
17
+ s.add_development_dependency "rspec"
18
+ s.add_development_dependency "cucumber"
19
+ s.add_development_dependency "simplecov"
20
+
21
+ s.add_dependency "rest-client"
22
+ s.add_dependency "json"
23
+ s.add_dependency "nokogiri"
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ["lib"]
29
+ end
data/cucumber.yml ADDED
@@ -0,0 +1,2 @@
1
+ autotest-all: --color --format pretty features
2
+ default: --color --format progress features
@@ -0,0 +1,17 @@
1
+ Feature: Bamboo Remote client
2
+ In order to know more about our build pipeline
3
+ As a Bamboo user
4
+ I want to use Bamboo's Remote API
5
+
6
+ Background:
7
+ Given I am using the Remote client
8
+ And I am logged in
9
+
10
+ Scenario: Fetch build names
11
+ When I fetch all build names
12
+ Then I should get a list of builds
13
+
14
+ Scenario: Fetch a build result
15
+ When I fetch a build result
16
+ Then the build result should have a key
17
+ And the build result should have a state
@@ -0,0 +1,33 @@
1
+ Given /^I am using the (Remote|REST) client$/ do |api|
2
+ use api.downcase
3
+ end
4
+
5
+ Given /^I am logged in$/ do
6
+ client.login user, password
7
+ end
8
+
9
+ When /^I fetch all build names$/ do
10
+ @builds = client.builds
11
+ end
12
+
13
+ Then /^I should get a list of builds$/ do
14
+ @builds.should_not be_empty
15
+ @builds.each { |e| e.should be_kind_of(Bamboo::Client::Remote::Build) }
16
+ end
17
+
18
+
19
+ When /^I fetch a build result$/ do
20
+ builds = client.builds
21
+ build_key = builds.first.key
22
+
23
+ @build_result = client.latest_build_results(build_key)
24
+ end
25
+
26
+ Then /^the build result should have a key$/ do
27
+ @build_result.key.should be_kind_of(String)
28
+ end
29
+
30
+ Then /^the build result should have a state$/ do
31
+ @build_result.state.should be_kind_of(Symbol)
32
+ end
33
+
@@ -0,0 +1,30 @@
1
+ $:.unshift File.expand_path("../../../lib", __FILE__)
2
+ require "bamboo-client"
3
+
4
+ module BambooClientHelper
5
+ attr_reader :client
6
+
7
+ def use(what)
8
+ @client = Bamboo::Client.for what, url
9
+ end
10
+
11
+ def url
12
+ fetch_env 'BAMBOO_URL'
13
+ end
14
+
15
+ def user
16
+ fetch_env 'BAMBOO_USER'
17
+ end
18
+
19
+ def password
20
+ fetch_env 'BAMBOO_PASSWORD'
21
+ end
22
+
23
+ private
24
+
25
+ def fetch_env(var)
26
+ ENV[var] or raise "#{var} must be set for cucumber tests"
27
+ end
28
+ end
29
+
30
+ World(BambooClientHelper)
@@ -0,0 +1,27 @@
1
+ require "uri"
2
+ require "restclient"
3
+
4
+ require "bamboo-client/version"
5
+ require "bamboo-client/http"
6
+ require "bamboo-client/abstract"
7
+ require "bamboo-client/rest"
8
+ require "bamboo-client/remote"
9
+
10
+
11
+ module Bamboo
12
+ module Client
13
+ class Error < StandardError; end
14
+
15
+ def self.for(sym, url)
16
+ case sym.to_sym
17
+ when :rest
18
+ Rest.new Http::Json.new(url)
19
+ when :remote, :legacy
20
+ Remote.new Http::Xml.new(url)
21
+ else
22
+ raise ArgumentError, "unknown client #{sym.inspect}"
23
+ end
24
+ end
25
+
26
+ end # Client
27
+ end # Bamboo
@@ -0,0 +1,11 @@
1
+ module Bamboo
2
+ module Client
3
+
4
+ class Abstract
5
+ def initialize(http)
6
+ @http = http
7
+ end
8
+
9
+ end # Abstract
10
+ end # Client
11
+ end # Bamboo
@@ -0,0 +1,11 @@
1
+ require 'restclient'
2
+ require "bamboo-client/http/abstract"
3
+
4
+ module Bamboo
5
+ module Client
6
+ module Http
7
+ autoload :Json, "bamboo-client/http/json"
8
+ autoload :Xml, "bamboo-client/http/xml"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Bamboo
2
+ module Client
3
+ module Http
4
+ class Abstract
5
+ attr_reader :uri
6
+
7
+ def initialize(url)
8
+ @uri = URI.parse url
9
+ end
10
+ end # Abstract
11
+ end # Http
12
+ end # Client
13
+ end # Bamboo
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+
3
+ module Bamboo
4
+ module Client
5
+ module Http
6
+ class Json < Abstract
7
+
8
+ end # Json
9
+ end # Http
10
+ end # Client
11
+ end # Bamboo
@@ -0,0 +1,48 @@
1
+ require 'nokogiri'
2
+
3
+ module Bamboo
4
+ module Client
5
+ module Http
6
+ class Xml < Abstract
7
+ class Doc
8
+ def self.from(str)
9
+ new(Nokogiri::XML(str))
10
+ end
11
+
12
+ def initialize(doc)
13
+ @doc = doc
14
+ puts doc.to_s if $DEBUG
15
+ end
16
+
17
+ def text_for(css)
18
+ @doc.css(css).text
19
+ end
20
+
21
+ def objects_for(selector, klass)
22
+ @doc.css(selector).map { |e| klass.new(e) }
23
+ end
24
+
25
+ def object_for(selector, klass)
26
+ node = @doc.css(selector).first
27
+ node or raise Error, "no node matches selector #{selector.inspect}"
28
+
29
+ klass.new node
30
+ end
31
+ end # Doc
32
+
33
+ def post(path, data = {})
34
+ Doc.from RestClient.post(uri_for(path), data)
35
+ end
36
+
37
+ private
38
+
39
+ def uri_for(path)
40
+ u = uri.dup
41
+ u.path = path
42
+
43
+ u.to_s
44
+ end
45
+ end # Xml
46
+ end # Http
47
+ end # Client
48
+ end # Bamboo
@@ -0,0 +1,197 @@
1
+ module Bamboo
2
+ module Client
3
+
4
+ #
5
+ # Client for the legacy Bamboo Remote API
6
+ #
7
+ # http://confluence.atlassian.com/display/BAMBOO/Bamboo+Remote+API
8
+ #
9
+
10
+ class Remote < Abstract
11
+ attr_reader :token
12
+
13
+ def initialize(http)
14
+ super
15
+ @service = "/api/rest"
16
+ end
17
+
18
+ def login(user, pass)
19
+ doc = post :login,
20
+ :username => user,
21
+ :password => pass
22
+
23
+ @token = doc.text_for("response auth")
24
+ end
25
+
26
+ def logout
27
+ post :logout, :token => token
28
+ @token = nil
29
+ end
30
+
31
+ def update_and_build(build_name)
32
+ doc = post :updateAndBuild, :buildName => build_name
33
+
34
+ doc.text_for "response success"
35
+ end
36
+
37
+ def execute_build(build_key)
38
+ doc = post :executeBuild,
39
+ :auth => token,
40
+ :buildKey => build_key
41
+
42
+ doc.text_for "response string"
43
+ end
44
+
45
+ def builds
46
+ doc = post :listBuildNames, :auth => token
47
+
48
+ doc.objects_for "build", Remote::Build
49
+ end
50
+
51
+ def latest_builds_for(user)
52
+ doc = post :getLatestUserBuilds,
53
+ :auth => token,
54
+ :user => user
55
+
56
+ doc.objects_for "build", Remote::Build
57
+ end
58
+
59
+ def latest_build_results(build_key)
60
+ doc = post :getLatestBuildResults,
61
+ :auth => token,
62
+ :buildKey => build_key
63
+
64
+ doc.object_for "response", Remote::BuildResult
65
+ end
66
+
67
+ def recently_completed_results_for_project(project_key)
68
+ doc = post :getRecentlyCompletedBuildResultsForProject,
69
+ :auth => token,
70
+ :projectKey => project_key
71
+
72
+ doc.objects_for "build", Remote::BuildResult
73
+ end
74
+
75
+ def recently_completed_results_for_build(build_key)
76
+ doc = post :getRecentlyCompletedBuildResultsForBuild,
77
+ :auth => token,
78
+ :buildKey => build_key
79
+
80
+ doc.objects_for "build", Remote::BuildResult
81
+ end
82
+
83
+ private
84
+
85
+ def post(action, data = {})
86
+ @http.post "#{@service}/#{action}.action", data
87
+ end
88
+
89
+ #
90
+ # types
91
+ #
92
+
93
+ class Build
94
+ def initialize(doc)
95
+ @doc = doc
96
+ end
97
+
98
+ def enabled?
99
+ @doc['enabled'] == 'true'
100
+ end
101
+
102
+ def name
103
+ @doc.css("name").text
104
+ end
105
+
106
+ def key
107
+ @doc.css("key").text
108
+ end
109
+ end
110
+
111
+ class BuildResult
112
+ def initialize(doc)
113
+ @doc = doc
114
+ end
115
+
116
+ def key
117
+ @doc.css("buildKey").text
118
+ end
119
+
120
+ def state
121
+ @doc.css("buildState").text.downcase.gsub(/ /, '_').to_sym
122
+ end
123
+
124
+ def successful?
125
+ state == :successful
126
+ end
127
+
128
+ def project_name
129
+ @doc.css("projectName").text
130
+ end
131
+
132
+ def name
133
+ @doc.css("buildName").text
134
+ end
135
+
136
+ def number
137
+ @doc.css("buildNumber").text.to_i
138
+ end
139
+
140
+ def failed_test_count
141
+ @doc.css("failedTestCount").text.to_i
142
+ end
143
+
144
+ def successful_test_count
145
+ @doc.css("successfulTestCount").text.to_i
146
+ end
147
+
148
+ def start_time
149
+ Time.parse @doc.css("buildTime").text
150
+ rescue ArgumentError
151
+ nil
152
+ end
153
+
154
+ def end_time
155
+ Time.parse @doc.css("buildCompletedDate").text
156
+ rescue ArgumentError
157
+ nil
158
+ end
159
+
160
+ def duration
161
+ @doc.css("buildDurationInSeconds").text.to_i
162
+ end
163
+
164
+ def duration_description
165
+ @doc.css("buildDurationDescription").text
166
+ end
167
+
168
+ def relative_date
169
+ @doc.css("buildRelativeBuildDate").text
170
+ end
171
+
172
+ def test_summary
173
+ @doc.css("buildTestSummary").text
174
+ end
175
+
176
+ def reason
177
+ @doc.css("buildReason").text
178
+ end
179
+
180
+ def commits
181
+ @doc.css('commits commit').map { |e| Commit.new(e) }
182
+ end
183
+
184
+ class Commit
185
+ def initialize(doc)
186
+ @doc = doc
187
+ end
188
+
189
+ def author
190
+ @doc['author']
191
+ end
192
+ end
193
+
194
+ end
195
+ end # Remote
196
+ end # Client
197
+ end # Bamboo
@@ -0,0 +1,14 @@
1
+ module Bamboo
2
+ module Client
3
+
4
+ #
5
+ # Client for the Bamboo REST API
6
+ #
7
+ # http://confluence.atlassian.com/display/BAMBOO/Bamboo+REST+APIs
8
+ #
9
+
10
+ class Rest < Abstract
11
+
12
+ end # Rest
13
+ end # Client
14
+ end # Bamboo
@@ -0,0 +1,5 @@
1
+ module Bamboo
2
+ module Client
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ module Bamboo
4
+ describe Client do
5
+ it "returns a client for the REST API" do
6
+ client = Client.for :rest, "http://bamboo.com"
7
+
8
+ client.should be_kind_of(Client::Rest)
9
+ end
10
+
11
+ it "returns a client for the Remote API" do
12
+ client = Client.for :remote, "http://bamboo.com"
13
+
14
+ client.should be_kind_of(Client::Remote)
15
+ end
16
+
17
+ it "raises ArgumentError if the client is unknown" do
18
+ lambda { Client.for :foo, "http://foo.com" }.should raise_error(ArgumentError)
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path("../../../spec_helper", __FILE__)
2
+
3
+ module Bamboo
4
+ module Client
5
+ module Http
6
+ describe Xml do
7
+ let(:url) { "http://example.com" }
8
+ let(:xml) { Xml.new(url) }
9
+
10
+
11
+ it "does a POST" do
12
+ RestClient.should_receive(:post).
13
+ with("#{url}/", :some => "data").
14
+ and_return("<foo><bar></bar></foo>")
15
+
16
+ doc = xml.post("/", :some => "data")
17
+ doc.should be_kind_of(Xml::Doc)
18
+ end
19
+ end
20
+
21
+ describe Xml::Doc do
22
+ let(:wrapped) { mock("nokogiri document") }
23
+ let(:doc) { Xml::Doc.new(wrapped)}
24
+
25
+ it "returns the text of the given CSS selector" do
26
+ wrapped.should_receive(:css).
27
+ with("some selector").
28
+ and_return(mock("node", :text => "bar"))
29
+
30
+ doc.text_for("some selector").should == "bar"
31
+ end
32
+
33
+ it "returns an instance of the given class for each node matching the selector" do
34
+ wrapped.should_receive(:css).with("selector").and_return(['node1', 'node2'])
35
+
36
+ objs = doc.objects_for("selector", SpecHelper::Wrapper)
37
+
38
+ objs.size.should == 2
39
+ objs.each { |e| e.should be_instance_of(SpecHelper::Wrapper) }
40
+ objs.map { |e| e.obj }.should == ['node1', 'node2']
41
+ end
42
+
43
+ it "returns an instance of the given class for the first node matching the selector" do
44
+ wrapped.should_receive(:css).with("selector").and_return(['node1', 'node2'])
45
+ obj = doc.object_for("selector", SpecHelper::Wrapper)
46
+ obj.should be_instance_of(SpecHelper::Wrapper)
47
+ obj.obj.should == "node1"
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,233 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ module Bamboo
4
+ module Client
5
+ describe Remote do
6
+ let(:url) { "http://bamboo.example.com" }
7
+ let(:http) { mock(Http::Xml) }
8
+ let(:client) { Remote.new(http) }
9
+ let(:document) { mock(Http::Xml::Doc) }
10
+
11
+ context "authorization" do
12
+ it "logs in" do
13
+ document.should_receive(:text_for).with("response auth").and_return "token"
14
+
15
+ http.should_receive(:post).with(
16
+ "/api/rest/login.action",
17
+ :username => "user",
18
+ :password => "pass"
19
+ ).and_return(document)
20
+
21
+ client.login "user", "pass"
22
+ client.token.should == "token"
23
+ end
24
+
25
+ it "raises an error if no token is set" do
26
+ lambda { client.builds }.should raise_error
27
+ end
28
+
29
+ it "logs out" do
30
+ http.should_receive(:post).with(
31
+ "/api/rest/logout.action",
32
+ :token => "foo"
33
+ )
34
+
35
+ client.instance_variable_set "@token", "foo"
36
+ client.logout
37
+ client.token.should be_nil
38
+ end
39
+ end
40
+
41
+ context "API calls" do
42
+ before { client.stub(:token => "fake-token") }
43
+
44
+ it "updates and builds" do
45
+ document.should_receive(:text_for).with("response success").and_return "true"
46
+
47
+ http.should_receive(:post).
48
+ with("/api/rest/updateAndBuild.action", :buildName => "fake-name").
49
+ and_return(document)
50
+
51
+ client.update_and_build("fake-name").should == "true"
52
+ end
53
+
54
+ it "executes a build" do
55
+ document.should_receive(:text_for).with("response string").and_return "true"
56
+
57
+ http.should_receive(:post).with(
58
+ "/api/rest/executeBuild.action",
59
+ :auth => "fake-token",
60
+ :buildKey => "fake-build-key"
61
+ ).and_return(document)
62
+
63
+ client.execute_build("fake-build-key").should == "true"
64
+ end
65
+
66
+ it "fetches a list of builds" do
67
+ document.should_receive(:objects_for).with("build", Remote::Build).
68
+ and_return(["some", "objects"])
69
+
70
+ http.should_receive(:post).with(
71
+ "/api/rest/listBuildNames.action",
72
+ :auth => "fake-token"
73
+ ).and_return(document)
74
+
75
+ client.builds.should == ["some", "objects"]
76
+ end
77
+
78
+ it "fetches a list of the latest builds for the given user" do
79
+ document.should_receive(:objects_for).with("build", Remote::Build).
80
+ and_return(["some", "objects"])
81
+
82
+ user = "fake-user"
83
+
84
+ http.should_receive(:post).with(
85
+ "/api/rest/getLatestUserBuilds.action",
86
+ :auth => "fake-token",
87
+ :user => user
88
+ ).and_return(document)
89
+
90
+ client.latest_builds_for(user).should == ["some", "objects"]
91
+ end
92
+
93
+ it "fetches the latest build results for a given key" do
94
+ document.should_receive(:object_for).with("response", Remote::BuildResult).
95
+ and_return(["some objects"])
96
+
97
+ http.should_receive(:post).with(
98
+ "/api/rest/getLatestBuildResults.action",
99
+ :auth => "fake-token",
100
+ :buildKey => "fake-key"
101
+ ).and_return(document)
102
+
103
+ client.latest_build_results("fake-key").should == ["some objects"]
104
+ end
105
+
106
+ it "fetches the recently completed build results for a given project" do
107
+ document.should_receive(:objects_for).with("build", Remote::BuildResult).
108
+ and_return(%w[some results])
109
+
110
+ http.should_receive(:post).with(
111
+ "/api/rest/getRecentlyCompletedBuildResultsForProject.action",
112
+ :auth => "fake-token",
113
+ :projectKey => "fake-project"
114
+ ).and_return(document)
115
+
116
+ client.recently_completed_results_for_project("fake-project").should == %w[some results]
117
+ end
118
+
119
+ it "fetches the recently completed build results for a given build key" do
120
+ document.should_receive(:objects_for).with("build", Remote::BuildResult).
121
+ and_return(%w[some results])
122
+
123
+ http.should_receive(:post).with(
124
+ "/api/rest/getRecentlyCompletedBuildResultsForBuild.action",
125
+ :auth => "fake-token",
126
+ :buildKey => "fake-key"
127
+ ).and_return(document)
128
+
129
+ client.recently_completed_results_for_build("fake-key").should == %w[some results]
130
+ end
131
+ end # API calls
132
+
133
+ describe Remote::Build do
134
+ let(:build) { Remote::Build.new(xml_fixture("build").css("build").first) }
135
+
136
+ it "should know if the build is enabled" do
137
+ build.should be_enabled
138
+ end
139
+
140
+ it "should know the name of the build" do
141
+ build.name.should == "Thrift - Default"
142
+ end
143
+
144
+ it "should know the key of the build" do
145
+ build.key.should == "THRIFT-DEFAULT"
146
+ end
147
+ end # Remote::Build
148
+
149
+ describe Remote::BuildResult do
150
+ let(:doc) { xml_fixture("build_result").css("response").first }
151
+ let(:result) { Remote::BuildResult.new(doc) }
152
+
153
+ it "should have a key" do
154
+ result.key.should == "ADS-DEFAULT"
155
+ end
156
+
157
+ it "should have a state" do
158
+ result.state.should == :successful
159
+ end
160
+
161
+ it "should know if the build was successful" do
162
+ result.should be_successful
163
+ end
164
+
165
+ it "should have a project name" do
166
+ result.project_name.should == "Advert Selection"
167
+ end
168
+
169
+ it "should have a build name" do
170
+ result.name.should == "DEFAULT"
171
+ end
172
+
173
+ it "should have a build number" do
174
+ result.number.should == 28
175
+ end
176
+
177
+ it "should have a failed test count" do
178
+ result.failed_test_count.should == 0
179
+ end
180
+
181
+ it "should have a successful test count" do
182
+ result.successful_test_count.should == 13
183
+ end
184
+
185
+ it "should have a start time" do
186
+ result.start_time.should == Time.parse("2011-01-18 09:55:54")
187
+ end
188
+
189
+ it "returns nil if start time can not be parsed" do
190
+ doc.stub(:css).and_return mock(:text => "foo")
191
+ result.start_time.should be_nil
192
+ end
193
+
194
+ it "returns nil if start time can not be parsed" do
195
+ doc.stub(:css).and_return mock(:text => "foo")
196
+ result.end_time.should be_nil
197
+ end
198
+
199
+ it "should have an end time" do
200
+ result.end_time.should == Time.parse("2011-01-18T09:56:40+0100")
201
+ end
202
+
203
+ it "should have duration" do
204
+ result.duration.should == 46
205
+ end
206
+
207
+ it "should have a duration description" do
208
+ result.duration_description.should == "46 seconds"
209
+ end
210
+
211
+ it "should have a relative date" do
212
+ result.relative_date.should == "1 day ago"
213
+ end
214
+
215
+ it "should have a test summary" do
216
+ result.test_summary.should == "13 passed"
217
+ end
218
+
219
+ it "should have a reason" do
220
+ result.reason.should == "Code has changed"
221
+ end
222
+
223
+ it "should have commits" do
224
+ commits = result.commits
225
+ commits.size.should == 2
226
+ commits.each { |c| c.should be_kind_of Remote::BuildResult::Commit }
227
+ commits.map { |c| c.author }.should == %w[foo bar]
228
+ end
229
+ end
230
+
231
+ end # describe Remote
232
+ end # Client
233
+ end # Bamboo
@@ -0,0 +1,11 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ module Bamboo
4
+ module Client
5
+ describe Rest do
6
+ let(:http) { mock(Http::Json) }
7
+ let(:client) { Rest.new(http) }
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ <build enabled="true">
2
+ <name>Thrift - Default</name>
3
+ <key>THRIFT-DEFAULT</key>
4
+ </build>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0"?>
2
+ <response>
3
+ <projectName>Advert Selection</projectName>
4
+ <buildName>DEFAULT</buildName>
5
+ <buildKey>ADS-DEFAULT</buildKey>
6
+ <buildState>Successful</buildState>
7
+ <buildNumber>28</buildNumber>
8
+ <failedTestCount>0</failedTestCount>
9
+ <successfulTestCount>13</successfulTestCount>
10
+ <buildTime>2011-01-18 09:55:54</buildTime>
11
+ <buildCompletedDate>2011-01-18T09:56:40+0100</buildCompletedDate>
12
+ <buildDurationInSeconds>46</buildDurationInSeconds>
13
+ <buildDurationDescription>46 seconds</buildDurationDescription>
14
+ <buildRelativeBuildDate>1 day ago</buildRelativeBuildDate>
15
+ <buildTestSummary>13 passed</buildTestSummary>
16
+ <buildReason>Code has changed</buildReason>
17
+ <commits>
18
+ <commit author="foo"/>
19
+ <commit author="bar"/>
20
+ </commits>
21
+ </response>
@@ -0,0 +1,36 @@
1
+ if ENV['COVERAGE']
2
+ raise "simplecov only works on 1.9" unless RUBY_PLATFORM >= "1.9"
3
+ require 'simplecov'
4
+ SimpleCov.start {
5
+ add_filter "spec/"
6
+ }
7
+ end
8
+
9
+ $:.unshift File.expand_path("../../lib", __FILE__)
10
+ require "bamboo-client"
11
+
12
+ module Bamboo::Client::SpecHelper
13
+ def xml_fixture(name)
14
+ path = File.join fixture_path("#{name}.xml")
15
+
16
+ Nokogiri.XML File.read(path)
17
+ end
18
+
19
+ def fixture_path(file)
20
+ dir = File.expand_path("../fixtures", __FILE__)
21
+
22
+ File.join dir, file
23
+ end
24
+
25
+ class Wrapper
26
+ attr_reader :obj
27
+
28
+ def initialize(obj)
29
+ @obj = obj
30
+ end
31
+ end
32
+ end
33
+
34
+ RSpec.configure do |c|
35
+ c.include Bamboo::Client::SpecHelper
36
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bamboo-client
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Jari Bakken
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-19 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: cucumber
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: simplecov
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: rest-client
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :runtime
71
+ version_requirements: *id004
72
+ - !ruby/object:Gem::Dependency
73
+ name: json
74
+ prerelease: false
75
+ requirement: &id005 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ type: :runtime
84
+ version_requirements: *id005
85
+ - !ruby/object:Gem::Dependency
86
+ name: nokogiri
87
+ prerelease: false
88
+ requirement: &id006 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :runtime
97
+ version_requirements: *id006
98
+ description: Ruby client for Atlassian Bamboo's REST APIs
99
+ email:
100
+ - jari.bakken@gmail.com
101
+ executables: []
102
+
103
+ extensions: []
104
+
105
+ extra_rdoc_files: []
106
+
107
+ files:
108
+ - .gitignore
109
+ - .rspec
110
+ - Gemfile
111
+ - LICENSE
112
+ - README
113
+ - Rakefile
114
+ - bamboo-client.gemspec
115
+ - cucumber.yml
116
+ - features/remote.feature
117
+ - features/step_definitions/remote_steps.rb
118
+ - features/support/env.rb
119
+ - lib/bamboo-client.rb
120
+ - lib/bamboo-client/abstract.rb
121
+ - lib/bamboo-client/http.rb
122
+ - lib/bamboo-client/http/abstract.rb
123
+ - lib/bamboo-client/http/json.rb
124
+ - lib/bamboo-client/http/xml.rb
125
+ - lib/bamboo-client/remote.rb
126
+ - lib/bamboo-client/rest.rb
127
+ - lib/bamboo-client/version.rb
128
+ - spec/bamboo-client/client_spec.rb
129
+ - spec/bamboo-client/http/xml_spec.rb
130
+ - spec/bamboo-client/remote_spec.rb
131
+ - spec/bamboo-client/rest_spec.rb
132
+ - spec/fixtures/build.xml
133
+ - spec/fixtures/build_result.xml
134
+ - spec/spec_helper.rb
135
+ has_rdoc: true
136
+ homepage: ""
137
+ licenses: []
138
+
139
+ post_install_message:
140
+ rdoc_options: []
141
+
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ segments:
150
+ - 0
151
+ version: "0"
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ requirements: []
161
+
162
+ rubyforge_project: bamboo-client
163
+ rubygems_version: 1.3.7
164
+ signing_key:
165
+ specification_version: 3
166
+ summary: Ruby client for Atlassian Bamboo's REST APIs
167
+ test_files:
168
+ - features/remote.feature
169
+ - features/step_definitions/remote_steps.rb
170
+ - features/support/env.rb
171
+ - spec/bamboo-client/client_spec.rb
172
+ - spec/bamboo-client/http/xml_spec.rb
173
+ - spec/bamboo-client/remote_spec.rb
174
+ - spec/bamboo-client/rest_spec.rb
175
+ - spec/fixtures/build.xml
176
+ - spec/fixtures/build_result.xml
177
+ - spec/spec_helper.rb