rally_rest_api 0.7.10 → 0.8.0

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.
@@ -16,10 +16,18 @@ lib/rally_rest_api/timeout_catching_rest_builder.rb
16
16
  lib/rally_rest_api/typedef.rb
17
17
  lib/rally_rest_api/version.rb
18
18
  setup.rb
19
+ spec/rally_rest_api/attribute_definition_spec.rb
20
+ spec/rally_rest_api/custom_http_header_spec.rb
21
+ spec/rally_rest_api/query_result_spec.rb
22
+ spec/rally_rest_api/rest_builder_spec.rb
23
+ spec/rally_rest_api/rest_object_spec.rb
24
+ spec/rally_rest_api/tc_query_result.rb
25
+ spec/rally_rest_api/tc_rest_api.rb
26
+ spec/rally_rest_api/tc_rest_query.rb
27
+ spec/rally_rest_api/typedef_spec.rb
28
+ spec/test_helper.rb
19
29
  tasks/ann.rake
20
- tasks/annotations.rake
21
30
  tasks/bones.rake
22
- tasks/doc.rake
23
31
  tasks/gem.rake
24
32
  tasks/manifest.rake
25
33
  tasks/post_load.rake
@@ -28,13 +36,3 @@ tasks/setup.rb
28
36
  tasks/spec.rake
29
37
  tasks/svn.rake
30
38
  tasks/test.rake
31
- test/attribute_definition_spec.rb
32
- test/custom_http_header_spec.rb
33
- test/query_result_spec.rb
34
- test/rest_builder_spec.rb
35
- test/rest_object_spec.rb
36
- test/spec_typedef.rb
37
- test/tc_query_result.rb
38
- test/tc_rest_api.rb
39
- test/tc_rest_query.rb
40
- test/test_helper.rb
data/Rakefile CHANGED
@@ -2,6 +2,7 @@
2
2
  # configured in this Rakefile. The .rake files in the tasks directory
3
3
  # are where the options are used.
4
4
 
5
+
5
6
  load 'tasks/setup.rb'
6
7
 
7
8
  ensure_in_path 'lib'
@@ -13,14 +14,14 @@ PROJ.name = 'rally_rest_api'
13
14
  PROJ.authors = 'Bob Cotton'
14
15
  PROJ.email = 'bob.cotton@rallydev.com'
15
16
  PROJ.url = 'http://rally-rest-api.rubyforge.org/rally_rest_api'
16
- PROJ.rubyforge_name = 'rally-rest-api'
17
+ PROJ.rubyforge.name = 'rally-rest-api'
17
18
  PROJ.summary = "A Ruby interface to the Rally REST API"
18
19
  PROJ.version = RallyRestVersion::LIBRARY_VERSION::STRING
19
20
 
20
21
  PROJ.exclude = ['.git/*', 'pkg/*']
21
22
 
22
- PROJ.rdoc_dir = 'doc/output/rally_rest_api'
23
+ PROJ.rdoc.dir = 'doc/output/rally_rest_api'
23
24
 
24
- PROJ.spec_opts << '--color'
25
+ PROJ.spec.opts << '--color'
25
26
 
26
27
  # EOF
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/rest_object'
3
3
  class AttributeDefinition < RestObject # :nodoc:
4
4
 
5
5
  def initialize(rally_rest, values)
6
- @rally_rest = rally_rest
6
+ super(rally_rest)
7
7
  @elements = values
8
8
  end
9
9
 
@@ -32,6 +32,7 @@ class RallyRestAPI
32
32
  #
33
33
  def initialize(options = {})
34
34
  parse_options(options)
35
+ user
35
36
  end
36
37
 
37
38
  def parse_options(options)
@@ -1,6 +1,7 @@
1
1
  require 'logger'
2
2
  require File.dirname(__FILE__) + '/rest_builder'
3
3
  require 'builder/blankslate'
4
+ require 'forwardable'
4
5
 
5
6
  # == An interface to a Rally resource
6
7
  # RestObject is an adapter that is initialized with a resource ref (URL) that represents a Rally object. The adapter
@@ -26,14 +27,17 @@ class FancyHash < Hash # :nodoc: all
26
27
  end
27
28
 
28
29
  class RestObject
30
+ extend Forwardable
29
31
 
30
- attr_reader :username, :password, :rally_rest
32
+ attr_accessor :rally_rest
33
+ def_delegator(:rally_rest, :username)
34
+ def_delegator(:rally_rest, :password)
31
35
 
32
- def initialize(rally_rest, document_content)
36
+ def initialize(rally_rest = nil, document_content = nil)
37
+ @changed_values = {}
33
38
  @rally_rest = rally_rest
34
39
  @document_content = document_content
35
- @username, @password = @rally_rest.username, @rally_rest.password
36
- parse_document
40
+ parse_document if document_content
37
41
  end
38
42
 
39
43
  def parse_document
@@ -46,14 +50,14 @@ class RestObject
46
50
  end
47
51
 
48
52
  def marshal_dump
49
- [@rally_rest, @document_content, @username, @password]
53
+ [@rally_rest, @document_content, @changed_values]
50
54
  end
51
55
 
52
56
  def marshal_load(stuff)
53
- @rally_rest, @document_content, @username, @password = *stuff
57
+ @rally_rest, @document_content, @changed_values = *stuff
54
58
  parse_document
55
59
  end
56
-
60
+
57
61
  private
58
62
  def terminal?(node)
59
63
  !node.has_elements?
@@ -156,14 +160,19 @@ class RestObject
156
160
 
157
161
  # The name of the object, without having to read the entire body
158
162
  def name
159
- @document.root.attributes["refObjectName"]
163
+ @changed_values[:name] || @document.root.attributes["refObjectName"]
160
164
  end
161
165
  alias :to_s :name
162
166
 
163
167
  # The type of the underlying resource
164
168
  def type
165
- @document.root.attributes["type"] || @document.root.name
169
+ @type || @document.root.attributes["type"] || @document.root.name
170
+ end
171
+
172
+ def type=(type)
173
+ @type = type
166
174
  end
175
+ alias :artifact_type= :type=
167
176
 
168
177
  # the type as symbol
169
178
  def type_as_symbol
@@ -191,7 +200,7 @@ class RestObject
191
200
 
192
201
  def elements(read = @elements.nil?) #:nodoc:
193
202
  if read
194
- @document_content = builder.read_rest(self.ref, @username, @password)
203
+ @document_content = builder.read_rest(self.ref, username, password)
195
204
  @document = REXML::Document.new @document_content
196
205
  @elements = parse(@document.root)
197
206
  end
@@ -217,20 +226,33 @@ class RestObject
217
226
  end
218
227
 
219
228
  public
229
+
230
+ def save!
231
+ raise 'missing RallyRestAPI instance' unless rally_rest
232
+ raise 'missing object type' unless @type
233
+ @document_content = builder.create_rest(type, @changed_values, username, password)
234
+ parse_document
235
+ end
220
236
 
221
237
  # update the resource. This will re-read the resource after the update
222
238
  def update(args)
223
- builder.update_rest(self.type, self.ref, args, @username, @password)
239
+ builder.update_rest(type, ref, args, username, password)
224
240
  self.elements(true)
225
241
  end
226
242
 
227
243
  # delete the resource
228
244
  def delete
229
- builder.delete_rest(self.ref, @username, @password)
245
+ builder.delete_rest(ref, username, password)
230
246
  end
231
247
 
232
248
  def method_missing(sym, *args) # :nodoc:
233
- self.elements[sym]
249
+ method = sym
250
+ if sym.to_s.match(/(.*)=$/)
251
+ method = $1.intern
252
+ return @changed_values[method] = args.first
253
+ end
254
+
255
+ @changed_values[method] || self.elements[method]
234
256
  # Sometimes the xml returned has no element for things that are simply null. Without
235
257
  # asking the typedef, I have no way to know if the element exists, or has been ommited.
236
258
  # It would not be hard to ask the typedef, but they are expensive to load. It should be an option
@@ -1,8 +1,8 @@
1
1
  module RallyRestVersion #:nodoc:
2
2
  module LIBRARY_VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 7
5
- TINY = 10
4
+ MINOR = 8
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -1,9 +1,7 @@
1
- require 'rubygems'
2
- require 'spec'
3
- require 'builder'
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
4
3
  require 'ostruct'
5
4
  require 'logger'
6
- require 'rally_rest_api'
7
5
 
8
6
 
9
7
  describe "An attribute definition for a custom dropdown" do
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  describe "A CustomHttpHeader" do
4
4
 
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  describe "A QueryResult" do
4
4
 
@@ -125,7 +125,7 @@ describe "A QueryResult with full objects" do
125
125
  rest_builder.
126
126
  should_receive(:read_rest).
127
127
  twice.
128
- with(:any_args).
128
+ with(any_args(), nil, nil).
129
129
  and_return( xml do |b|
130
130
  b.iteration {
131
131
  b.Name("name1")
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  describe "a RestBuilder " do
4
4
 
@@ -20,7 +20,7 @@ describe "a RestBuilder " do
20
20
  b.Name "foo"
21
21
  }
22
22
  end
23
- @builder.should_receive(:post_xml).with(:anything, expected_xml, @username, @password)
23
+ @builder.should_receive(:post_xml).with(anything(), expected_xml, @username, @password)
24
24
  @builder.update_rest(:defect, "url", {:name => "foo"}, @username, @password)
25
25
  end
26
26
 
@@ -35,7 +35,7 @@ describe "a RestBuilder " do
35
35
  }
36
36
  end
37
37
 
38
- @builder.should_receive(:post_xml).with(:anything, expected_xml, @username, @password)
38
+ @builder.should_receive(:post_xml).with(anything(), expected_xml, @username, @password)
39
39
  @builder.update_rest(:defect, "url",
40
40
  {
41
41
  :name => "foo",
@@ -1,5 +1,4 @@
1
-
2
- require 'test_helper'
1
+ require File.dirname(__FILE__) + '/../test_helper'
3
2
 
4
3
  describe RestObject do
5
4
 
@@ -95,7 +94,7 @@ describe RestObject do
95
94
  rest_builder = mock("RestBuilder")
96
95
  rest_builder.
97
96
  should_receive(:read_rest).
98
- with(:any_args).
97
+ with(any_args()).
99
98
  and_return( xml do |b|
100
99
  b.TestCase {
101
100
  b.Name("name1")
@@ -115,7 +114,7 @@ describe RestObject do
115
114
  rest_builder = mock("RestBuilder")
116
115
  rest_builder.
117
116
  should_receive(:read_rest).
118
- with(:any_args).
117
+ with(any_args()).
119
118
  and_return( xml do |b|
120
119
  b.TestCase {
121
120
  b.Name("name1")
@@ -140,7 +139,7 @@ describe RestObject do
140
139
  rest_builder.
141
140
  should_receive(:read_rest).
142
141
  once.
143
- with(:any_args).
142
+ with(any_args()).
144
143
  and_return( xml do |b|
145
144
  b.TestCase {
146
145
  b.Name("name1")
@@ -164,7 +163,7 @@ describe RestObject do
164
163
  rest_builder.
165
164
  should_receive(:read_rest).
166
165
  once.
167
- with(:any_args).
166
+ with(any_args()).
168
167
  and_return( xml do |b|
169
168
  b.iteration {
170
169
  b.Name("name1")
@@ -299,7 +298,7 @@ describe RestObject do
299
298
  rest_builder.
300
299
  should_receive(:read_rest).
301
300
  twice.
302
- with(:any_args).
301
+ with(any_args()).
303
302
  and_return( xml do |b|
304
303
  b.Task {
305
304
  b.Name("name1")
@@ -323,5 +322,63 @@ describe RestObject do
323
322
  object.tasks.first.description.should == "Description"
324
323
  object.tasks.last.description.should == "Description"
325
324
  end
325
+
326
+ it "should allow getting and setting rally_rest" do
327
+ rally_rest = RallyRestAPI.new
328
+ rest_object = RestObject.new
329
+ rest_object.rally_rest = rally_rest
330
+ rest_object.rally_rest.should equal(rally_rest)
331
+ end
326
332
 
333
+ it "should allow the type to be set" do
334
+ rest_object = RestObject.new
335
+ rest_object.type = :defect
336
+ rest_object.type.should == :defect
337
+ end
338
+
339
+ it "should allow the name to be set" do
340
+ rest_object = RestObject.new
341
+ rest_object.name = "name"
342
+ rest_object.name.should == "name"
343
+ end
344
+
345
+ it "should allow the setting and getting of any value" do
346
+ rest_object = RestObject.new
347
+ rest_object.description = "description"
348
+ rest_object.description.should == "description"
349
+ end
350
+
351
+ it "should pass the type and set value to create on rally_rest" do
352
+ builder = mock("builder")
353
+ rally_rest = RallyRestAPI.new(:builder => builder)
354
+ args = {:name => "name", :description => "description"}
355
+ xml = %Q(<Object ref="bla" refObjectName="name">
356
+ <Name>name</Name>
357
+ <Description>description</Description>
358
+ </Object>)
359
+
360
+ builder.should_receive(:create_rest).with(:defect, args, nil, nil).and_return(xml)
361
+
362
+ rest_object = RestObject.new
363
+ rest_object.rally_rest = rally_rest
364
+ rest_object.type = :defect
365
+ rest_object.name = "name"
366
+ rest_object.description = "description"
367
+ rest_object.save!
368
+
369
+ rest_object.ref.should == "bla"
370
+ rest_object.name.should == "name"
371
+ rest_object.description.should == "description"
372
+ end
373
+
374
+ it "should not try to save if there is no rally_rest" do
375
+ rest_object = RestObject.new
376
+ lambda { rest_object.save! }.should raise_error(StandardError, /missing RallyRestAPI instance/)
377
+ end
378
+
379
+ it "should not try to save if there is no type" do
380
+ rally_rest = stub!("RallyRest")
381
+ rest_object = RestObject.new(rally_rest)
382
+ lambda { rest_object.save! }.should raise_error(StandardError, /missing object type/)
383
+ end
327
384
  end
@@ -1,8 +1,7 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
1
2
  require 'test/unit'
2
3
  require 'test/unit/testcase'
3
4
 
4
- require 'rubygems'
5
- require 'rally_rest_api'
6
5
 
7
6
  class QueryResultTestCase < Test::Unit::TestCase
8
7
 
@@ -1,9 +1,4 @@
1
- require 'test/unit'
2
- require 'test/unit/testcase'
3
-
4
- require 'rubygems'
5
- require 'rally_rest_api'
6
-
1
+ require File.dirname(__FILE__) + '/../test_helper'
7
2
  class RestApiTestCase < Test::Unit::TestCase
8
3
 
9
4
  # We need to override post_xml from RestBuilder, So redefine it here
@@ -1,8 +1,4 @@
1
-
2
- require "test/unit"
3
-
4
- require 'rubygems'
5
- require 'rally_rest_api'
1
+ require File.dirname(__FILE__) + '/../test_helper'
6
2
 
7
3
  class TestRestQuery < Test::Unit::TestCase
8
4
  # RestQuery.find(:feature).where { # default is and
@@ -1,7 +1,5 @@
1
- require 'spec'
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
2
  require 'ostruct'
3
- require 'logger'
4
- require 'rally_rest_api'
5
3
 
6
4
 
7
5
  describe "A Test Case type definition with 2 collection attribues, 1 object attributes, and 1 string attribute" do
@@ -15,11 +13,11 @@ describe "A Test Case type definition with 2 collection attribues, 1 object attr
15
13
  :type => "TypeDefinition") {
16
14
  @b.ElementName("TestCase")
17
15
  @b.Attributes {
18
- {"Notes" => {:type => "TEXT", :element_name => "Notes", :constrained => "false", :custom => "false"},
19
- "Test Case Result" => {:type => "COLLECTION", :element_name => "TestCaseResult", :constrained => "false", :custom => "false"},
16
+ {"Notes" => {:type => "TEXT", :element_name => "Notes", :constrained => "false", :custom => "false"},
17
+ "Test Case Result" => {:type => "COLLECTION", :element_name => "TestCaseResult", :constrained => "false", :custom => "false"},
20
18
  "Foo Bar" => {:type => "COLLECTION", :element_name => "FooBar", :constrained => "false", :custom => "false"},
21
19
  "Requirement" => {:type => "OBJECT", :element_name => "Requirement", :constrained => "false", :custom => "false"},
22
- "Constrained" => {:type => "STRING", :element_name => "Constrained", :constrained => "true", :custom => "false"},
20
+ "Constrained" => {:type => "STRING", :element_name => "Constrained", :constrained => "true", :custom => "false"},
23
21
  "Custom" => {:type => "STRING", :element_name => "Custom", :constrained => "false", :custom => "true"},
24
22
  "ConstainedCustom" => {:type => "STRING", :element_name => "ConstrainedCustom", :constrained => "true", :custom => "true"}
25
23
  }.each do |name, type|
@@ -0,0 +1,13 @@
1
+ dir = File.dirname(__FILE__)
2
+ app_path = File.expand_path("#{dir}/../lib")
3
+ $LOAD_PATH.unshift app_path unless $LOAD_PATH.include?(app_path)
4
+ require 'test/unit'
5
+ require 'rubygems'
6
+ require 'spec'
7
+ require 'net/http'
8
+ require 'rally_rest_api'
9
+
10
+ class RallyRestAPI
11
+ def user; end
12
+ end
13
+