bamboo-client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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