rally_rest_api 0.6.2 → 0.6.3
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/lib/rally_rest_api/query_result.rb +6 -0
- data/lib/rally_rest_api/rally_rest.rb +13 -1
- data/lib/rally_rest_api/rest_builder.rb +7 -7
- data/lib/rally_rest_api/rest_object.rb +29 -19
- data/lib/rally_rest_api/typedef.rb +6 -10
- data/lib/rally_rest_api/version.rb +1 -1
- data/test/attribute_definition_spec.rb +7 -1
- data/test/query_result_spec.rb +13 -0
- data/test/spec_typedef.rb +4 -4
- data/test/tc_rest_api.rb +6 -6
- data/test/tc_rest_object.rb +17 -18
- data/test/tc_rest_query.rb +4 -0
- metadata +2 -2
@@ -3,7 +3,6 @@ require 'uri'
|
|
3
3
|
require 'rexml/document'
|
4
4
|
require 'ostruct'
|
5
5
|
|
6
|
-
|
7
6
|
#
|
8
7
|
# RallyRestAPI - A Ruby-ized interface to Rally's REST webservice API
|
9
8
|
#
|
@@ -11,6 +10,7 @@ class RallyRestAPI
|
|
11
10
|
include RestBuilder
|
12
11
|
|
13
12
|
attr_reader :username, :password, :base_url, :raise_on_warning, :logger
|
13
|
+
attr_accessor :parse_collections_as_hash
|
14
14
|
|
15
15
|
ALLOWED_TYPES = %w[subscription workspace project iteration release defect defect_suite test_case
|
16
16
|
feature supplemental_requirement use_case story actor card
|
@@ -35,6 +35,7 @@ class RallyRestAPI
|
|
35
35
|
@base_url = options[:base_url]
|
36
36
|
@raise_on_warning = options[:raise_on_warning]
|
37
37
|
@logger = options[:logger]
|
38
|
+
@parse_collections_as_hash = options[:parse_collections_as_hash] || false
|
38
39
|
end
|
39
40
|
|
40
41
|
# return an instance of User, for the currently logged in user.
|
@@ -95,6 +96,17 @@ class RallyRestAPI
|
|
95
96
|
QueryResult.new(query, self, xml)
|
96
97
|
end
|
97
98
|
|
99
|
+
# Should rest_objects parse into hashes
|
100
|
+
def parse_collections_as_hash?
|
101
|
+
@parse_collections_as_hash
|
102
|
+
end
|
103
|
+
|
104
|
+
protected
|
105
|
+
def debug(message)
|
106
|
+
@logger.debug(message) if @logger
|
107
|
+
end
|
108
|
+
|
98
109
|
end
|
99
110
|
|
100
111
|
|
112
|
+
|
@@ -18,7 +18,7 @@ module RestBuilder # :nodoc:
|
|
18
18
|
# then call create on the REST api
|
19
19
|
def create_rest(artifact_type, args, username, password)
|
20
20
|
type = camel_case_word(artifact_type)
|
21
|
-
|
21
|
+
debug "RestBuilder#create_rest artifact_type = #{type}"
|
22
22
|
b = create_builder
|
23
23
|
xml = b.__send__(type, &builder_block(args))
|
24
24
|
|
@@ -37,7 +37,7 @@ module RestBuilder # :nodoc:
|
|
37
37
|
# }
|
38
38
|
# then call create on the REST api
|
39
39
|
def update_rest(artifact_type, url, args, username, password)
|
40
|
-
|
40
|
+
debug "RestBuilder#update_rest url = #{url}"
|
41
41
|
b = create_builder
|
42
42
|
# and pass that to the builder
|
43
43
|
xml = b.__send__(artifact_type, :ref => url, &builder_block(args))
|
@@ -45,21 +45,21 @@ module RestBuilder # :nodoc:
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def read_rest(ref_url, username, password)
|
48
|
-
|
48
|
+
debug "RestBuilder#read_rest ref_url = #{ref_url} username = #{ username } pass = #{ password }"
|
49
49
|
url = URI.parse(ref_url)
|
50
50
|
req = Net::HTTP::Get.new(url.path + (url.query ? "?" + url.query : ""))
|
51
51
|
send_request(url, req, username, password)
|
52
52
|
end
|
53
53
|
|
54
54
|
def delete_rest(ref_url, username, password)
|
55
|
-
|
55
|
+
debug "RestBuilder#delete_rest ref_url = #{ref_url} username = #{ username } pass = #{ password }"
|
56
56
|
url = URI.parse(ref_url)
|
57
57
|
req = Net::HTTP::Delete.new(url.path)
|
58
58
|
send_request(url, req, username, password)
|
59
59
|
end
|
60
60
|
|
61
61
|
def post_xml(url, xml, username, password)
|
62
|
-
|
62
|
+
debug "RestBuilder#post_xml xml = #{xml} as user #{ self.username } pass = #{ self.password }"
|
63
63
|
url = URI.parse(url)
|
64
64
|
req = Net::HTTP::Post.new(url.path)
|
65
65
|
req.body = xml
|
@@ -67,13 +67,13 @@ module RestBuilder # :nodoc:
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def send_request(url, req, username, password)
|
70
|
-
|
70
|
+
debug "RestBuilder#send_request req = #{req.inspect}"
|
71
71
|
req.basic_auth username, password
|
72
72
|
req.content_type = 'text/xml'
|
73
73
|
http = Net::HTTP.new(url.host, url.port)
|
74
74
|
http.use_ssl = true if url.scheme == "https"
|
75
75
|
body = http.start { |http| http.request(req) }.body
|
76
|
-
|
76
|
+
debug "RestBuilder#send_request result = #{body}"
|
77
77
|
check_for_errors(body)
|
78
78
|
body
|
79
79
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'logger'
|
1
2
|
require File.dirname(__FILE__) + '/rest_builder'
|
2
3
|
|
3
4
|
# == An interface to a Rally resource
|
@@ -19,8 +20,6 @@ require File.dirname(__FILE__) + '/rest_builder'
|
|
19
20
|
class RestObject
|
20
21
|
include RestBuilder
|
21
22
|
|
22
|
-
DEBUG = false
|
23
|
-
|
24
23
|
attr_reader :username, :password, :rally_rest
|
25
24
|
alias :builder :rally_rest
|
26
25
|
|
@@ -36,17 +35,16 @@ class RestObject
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
|
-
|
40
38
|
private
|
41
39
|
def parse(node)
|
42
|
-
|
40
|
+
debug "parse self = #{self.object_id} node = #{ node.to_s }"
|
43
41
|
|
44
42
|
if !node.has_elements?
|
45
43
|
if ref?(node)
|
46
|
-
|
44
|
+
debug "Returning RestObject for #{ node.to_s}"
|
47
45
|
return RestObject.new(@rally_rest, node.to_s)
|
48
46
|
else
|
49
|
-
|
47
|
+
debug "Returning text #{ node.text }"
|
50
48
|
return node.text
|
51
49
|
end
|
52
50
|
end
|
@@ -63,16 +61,16 @@ class RestObject
|
|
63
61
|
#Add all the element's children to the hash.
|
64
62
|
node.each_element do |e|
|
65
63
|
name = underscore(e.name).to_sym
|
66
|
-
|
64
|
+
debug "Looking at name = #{ name }"
|
67
65
|
case elements[name]
|
68
66
|
# We've not seen this element before
|
69
67
|
when NilClass
|
70
|
-
|
68
|
+
debug "NilClass name = #{ name }"
|
71
69
|
# if we have a collection of things with refObjectName attributes, collect them into a hash
|
72
|
-
# with the refObjectName as the key
|
73
|
-
if named_collection?(e)
|
74
|
-
|
75
|
-
elements[name] = {}
|
70
|
+
# with the refObjectName as the key, unless we're told not to make hashs out of collections.
|
71
|
+
if named_collection?(e) && parse_collections_as_hash?
|
72
|
+
debug "Named collection #{ name }"
|
73
|
+
elements[name] = {}
|
76
74
|
e.elements.each do |child|
|
77
75
|
ref_name = child.attributes["refObjectName"]
|
78
76
|
if elements[name][ref_name]
|
@@ -82,21 +80,21 @@ class RestObject
|
|
82
80
|
elements[name][ref_name] = parse(child)
|
83
81
|
end
|
84
82
|
end
|
85
|
-
elsif
|
86
|
-
|
83
|
+
elsif collection?(e)
|
84
|
+
debug "Collection #{ name }"
|
87
85
|
elements[name] = []
|
88
86
|
e.elements.each do |child|
|
89
87
|
elements[name] << parse(child)
|
90
88
|
end
|
91
89
|
else # a fully dressed object, without a name
|
92
|
-
|
90
|
+
debug "Fully Dressed object, without a name #{ name }"
|
93
91
|
elements[name] = parse(e)
|
94
92
|
end
|
95
93
|
|
96
94
|
#Non-unique child elements become arrays: We've already
|
97
95
|
#created the array: just add the element.
|
98
96
|
when Array
|
99
|
-
|
97
|
+
debug "Array name = #{ name }"
|
100
98
|
elements[name] << parse(e)
|
101
99
|
|
102
100
|
#We haven't created the array yet: do so,
|
@@ -105,7 +103,7 @@ class RestObject
|
|
105
103
|
# when Hash
|
106
104
|
# raise "Don't know how to deail with a named collection we've already seen! element = #{e}"
|
107
105
|
else
|
108
|
-
|
106
|
+
debug "creating and wrapping #{elements[name]}with an array name = #{ name }"
|
109
107
|
elements[name] = [elements[name]]
|
110
108
|
elements[name] << parse(e)
|
111
109
|
end
|
@@ -207,11 +205,15 @@ class RestObject
|
|
207
205
|
|
208
206
|
protected
|
209
207
|
def named_collection?(element) # :nodoc:
|
210
|
-
element.elements.find_all { |e| e.attributes['ref'] && e.attributes['refObjectName'] }.length > 0
|
208
|
+
collection?(element) && element.elements.find_all { |e| e.attributes['ref'] && e.attributes['refObjectName'] }.length > 0
|
211
209
|
end
|
212
210
|
|
213
211
|
def unnamed_collection?(element) # :nodoc:
|
214
|
-
element.elements.find_all { |e| e.attributes['ref'] && e.attributes['refObjectName'] == nil }.length > 0
|
212
|
+
collection?(element) && element.elements.find_all { |e| e.attributes['ref'] && e.attributes['refObjectName'] == nil }.length > 0
|
213
|
+
end
|
214
|
+
|
215
|
+
def collection?(element) # :nodoc:
|
216
|
+
!element.has_attributes? && element.has_elements? && element.elements.find_all { |e| e.attributes['ref'] }.length == element.elements.size
|
215
217
|
end
|
216
218
|
|
217
219
|
def ref?(element) # :nodoc:
|
@@ -220,4 +222,12 @@ class RestObject
|
|
220
222
|
!element.attributes["ref"].nil?
|
221
223
|
end
|
222
224
|
|
225
|
+
def parse_collections_as_hash? # :nodoc:
|
226
|
+
self.rally_rest.parse_collections_as_hash?
|
227
|
+
end
|
228
|
+
|
229
|
+
def debug(message)
|
230
|
+
# @rally_rest.logger.debug(message) if @rally_rest.logger
|
231
|
+
end
|
232
|
+
|
223
233
|
end
|
@@ -15,19 +15,10 @@ class TypeDefinition < RestObject # :nodoc:
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.get_type_definition(workspace, type)
|
18
|
-
|
19
|
-
typedef = workspace.type_definitions[type]
|
18
|
+
typedef = workspace.type_definitions.find { |td| td.element_name == type }
|
20
19
|
TypeDefinition.new(typedef.rally_rest, typedef.body)
|
21
20
|
end
|
22
21
|
|
23
|
-
# This is a hack
|
24
|
-
# Strip spaces from the name, and put the values back in to the hash
|
25
|
-
def self.mangle_type_definitions(type_definitions)
|
26
|
-
type_definitions.each do |key, value|
|
27
|
-
type_definitions[key.gsub(" ", "")] = value if key.include? " "
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
22
|
def self.make_key(workspace, type)
|
32
23
|
# Parent typedefs don't have a workspace, so key them appropriately
|
33
24
|
ref = workspace.ref rescue ""
|
@@ -101,5 +92,10 @@ class TypeDefinition < RestObject # :nodoc:
|
|
101
92
|
end
|
102
93
|
typedef
|
103
94
|
end
|
95
|
+
|
96
|
+
protected
|
97
|
+
def parse_collections_as_hash?
|
98
|
+
true
|
99
|
+
end
|
104
100
|
|
105
101
|
end
|
@@ -2,6 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'spec'
|
3
3
|
require 'builder'
|
4
4
|
require 'ostruct'
|
5
|
+
require 'logger'
|
5
6
|
require 'rally_rest_api'
|
6
7
|
|
7
8
|
|
@@ -28,7 +29,7 @@ context "An attribute definition for a custom dropdown" do
|
|
28
29
|
}
|
29
30
|
}
|
30
31
|
}
|
31
|
-
fake_rally_rest = OpenStruct.new(:username => "", :password => "")
|
32
|
+
fake_rally_rest = OpenStruct.new(:username => "", :password => "", :logger => nil)
|
32
33
|
@attrdef = AttributeDefinition.new(fake_rally_rest, RestObject.new(fake_rally_rest, xml).elements)
|
33
34
|
end
|
34
35
|
|
@@ -51,4 +52,9 @@ context "An attribute definition for a custom dropdown" do
|
|
51
52
|
specify "allowed_values should match" do
|
52
53
|
@attrdef.allowed_values.should == [nil, "Actor"]
|
53
54
|
end
|
55
|
+
|
56
|
+
specify "should have 'AttributeDefinition' as the type" do
|
57
|
+
@attrdef.type.should == "AttributeDefinition"
|
58
|
+
end
|
59
|
+
|
54
60
|
end
|
data/test/query_result_spec.rb
CHANGED
@@ -10,6 +10,8 @@ context "A QueryResult" do
|
|
10
10
|
@api = mock("RallyRestAPI")
|
11
11
|
@api.stub! :username
|
12
12
|
@api.stub! :password
|
13
|
+
@api.stub!(:logger).and_return(nil)
|
14
|
+
@api.stub!(:parse_collections_as_hash?).and_return true
|
13
15
|
end
|
14
16
|
|
15
17
|
def make_result(total, page_size, start_index)
|
@@ -66,6 +68,17 @@ context "A QueryResult" do
|
|
66
68
|
start.should_be 0
|
67
69
|
end
|
68
70
|
|
71
|
+
specify "a page of results should match the page size" do
|
72
|
+
make_result(20, 20, 1).results.length.should_be 20
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "results should be in the same order as returned" do
|
76
|
+
result = make_result(20, 20, 1)
|
77
|
+
result.results.length.should_be 20
|
78
|
+
result.results[0].name.should == "name0"
|
79
|
+
result.results[19].name.should == "name19"
|
80
|
+
end
|
81
|
+
|
69
82
|
end
|
70
83
|
|
71
84
|
context "A QueryResult with 2 pages" do
|
data/test/spec_typedef.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'spec'
|
3
2
|
require 'ostruct'
|
3
|
+
require 'logger'
|
4
4
|
require 'rally_rest_api'
|
5
5
|
|
6
6
|
|
@@ -33,7 +33,7 @@ context "A Test Case type definition with 2 collection attribues, 1 object attri
|
|
33
33
|
end
|
34
34
|
}
|
35
35
|
}
|
36
|
-
@typedef = TypeDefinition.new(OpenStruct.new(:username => "", :password => ""), xml)
|
36
|
+
@typedef = TypeDefinition.new(OpenStruct.new(:username => "", :password => "", :logger => nil), xml)
|
37
37
|
end
|
38
38
|
|
39
39
|
specify "all attribute keys are symbols" do
|
@@ -69,8 +69,8 @@ context "A Test Case type definition with 2 collection attribues, 1 object attri
|
|
69
69
|
end
|
70
70
|
|
71
71
|
specify "should have 1 custom_constrained_attributes" do
|
72
|
-
@typedef.custom_constrained_attributes.size.
|
73
|
-
@typedef.custom_dropdown_attributes.size.
|
72
|
+
@typedef.custom_constrained_attributes.size.should_be 1
|
73
|
+
@typedef.custom_dropdown_attributes.size.should_be 1
|
74
74
|
end
|
75
75
|
|
76
76
|
specify "#attributes should return instances of AttributeDefinitions" do
|
data/test/tc_rest_api.rb
CHANGED
@@ -48,20 +48,20 @@ class RestApiTestCase < Test::Unit::TestCase
|
|
48
48
|
# test that types and keys are camel cased (at least with one underscore)
|
49
49
|
def test_camel_case
|
50
50
|
xml = "#{preamble}<UseCase><NameName>name</NameName></UseCase>"
|
51
|
-
@api.
|
51
|
+
@api.create(:use_case, :name_name => "name")
|
52
52
|
assert_equal(xml, @xml)
|
53
53
|
end
|
54
54
|
|
55
55
|
def test_nil_value
|
56
56
|
xml = %Q(#{preamble}<UseCase><Name ref="null"/></UseCase>)
|
57
|
-
@api.
|
57
|
+
@api.create(:use_case, :name => nil)
|
58
58
|
assert_equal(xml, @xml)
|
59
59
|
end
|
60
60
|
|
61
61
|
def test_time_value
|
62
62
|
time = Time.now
|
63
63
|
xml = "#{preamble}<UseCase><Time>#{time.iso8601}</Time></UseCase>"
|
64
|
-
@api.
|
64
|
+
@api.create(:use_case, :time => time)
|
65
65
|
assert_equal(xml, @xml)
|
66
66
|
end
|
67
67
|
|
@@ -71,7 +71,7 @@ class RestApiTestCase < Test::Unit::TestCase
|
|
71
71
|
rest_object = RestObject.new(@api, rest_object_xml)
|
72
72
|
|
73
73
|
xml = %Q(#{preamble}<Feature><UseCase ref="url"/></Feature>)
|
74
|
-
@api.
|
74
|
+
@api.create(:feature, :use_case => rest_object)
|
75
75
|
assert_equal(xml, @xml)
|
76
76
|
end
|
77
77
|
|
@@ -81,7 +81,7 @@ class RestApiTestCase < Test::Unit::TestCase
|
|
81
81
|
uc1 = RestObject.new(@api, rest_object_xml)
|
82
82
|
|
83
83
|
xml = %Q(#{preamble}<Feature><Dependents><UseCase ref="url"/></Dependents></Feature>)
|
84
|
-
@api.
|
84
|
+
@api.create(:feature, :dependents => uc1)
|
85
85
|
assert_equal(xml, @xml)
|
86
86
|
end
|
87
87
|
|
@@ -92,7 +92,7 @@ class RestApiTestCase < Test::Unit::TestCase
|
|
92
92
|
uc2 = RestObject.new(@api, rest_object_xml)
|
93
93
|
|
94
94
|
xml = %Q(#{preamble}<Feature><Dependents><UseCase ref="url"/><UseCase ref="url"/></Dependents></Feature>)
|
95
|
-
@api.
|
95
|
+
@api.create(:feature, :dependents => [uc1, uc2])
|
96
96
|
assert_equal(xml, @xml)
|
97
97
|
end
|
98
98
|
|
data/test/tc_rest_object.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
require 'test/unit'
|
3
3
|
require 'test/unit/testcase'
|
4
|
+
require 'logger'
|
4
5
|
|
5
6
|
require 'rubygems'
|
6
7
|
require 'rally_rest_api'
|
@@ -68,13 +69,13 @@ class RestObjectTestCase < Test::Unit::TestCase
|
|
68
69
|
end
|
69
70
|
|
70
71
|
def test_equal_same_instance
|
71
|
-
xml = %Q(<Object><TextNode>text</TextNode></Object>)
|
72
|
+
xml = %Q(<Object ref="http"><TextNode>text</TextNode></Object>)
|
72
73
|
r1 = r2 = rest_object(xml)
|
73
74
|
assert(r1 == r2)
|
74
75
|
end
|
75
76
|
|
76
77
|
def test_equal_with_nil
|
77
|
-
xml = %Q(<Object><TextNode>text</TextNode></Object>)
|
78
|
+
xml = %Q(<Object ref="http"><TextNode>text</TextNode></Object>)
|
78
79
|
r1 = rest_object(xml)
|
79
80
|
assert(r1 != nil)
|
80
81
|
end
|
@@ -87,23 +88,23 @@ class RestObjectTestCase < Test::Unit::TestCase
|
|
87
88
|
|
88
89
|
|
89
90
|
def test_basic_text_node
|
90
|
-
xml = %Q(<Object><TextNode>text</TextNode></Object>)
|
91
|
+
xml = %Q(<Object ref="bla"><TextNode>text</TextNode></Object>)
|
91
92
|
assert_equal("text", rest_object(xml).text_node)
|
92
93
|
end
|
93
94
|
|
94
95
|
def test_nested_text_node
|
95
|
-
xml = %Q(<Object><Nested><TextNode>text</TextNode></Nested></Object>)
|
96
|
+
xml = %Q(<Object ref="bla"><Nested ref="bla/nested"><TextNode>text</TextNode></Nested></Object>)
|
96
97
|
assert_equal("text", rest_object(xml).nested.text_node)
|
97
98
|
end
|
98
99
|
|
99
100
|
# make sure RestObject are being created
|
100
101
|
def test_ref_node
|
101
|
-
xml = %Q(<Object><
|
102
|
-
assert_equal(RestObject, rest_object(xml).
|
102
|
+
xml = %Q(<Object ref="http"><RefElement ref="http" refObjectName="name1"/></Object>)
|
103
|
+
assert_equal(RestObject, rest_object(xml).class)
|
103
104
|
end
|
104
105
|
|
105
106
|
def test_ref_node_reading
|
106
|
-
xml = %Q(<Object><Top><RefElement ref="http" refObjectName="name1"/></Top></Object>)
|
107
|
+
xml = %Q(<Object ref="bla"><Top ref="blabla"><RefElement ref="http" refObjectName="name1"/></Top></Object>)
|
107
108
|
# This will be the xml returned from read_rest
|
108
109
|
class << self
|
109
110
|
def read_xml
|
@@ -111,11 +112,11 @@ class RestObjectTestCase < Test::Unit::TestCase
|
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
114
|
-
assert_equal("foo", rest_object(xml).top
|
115
|
+
assert_equal("foo", rest_object(xml).top.ref_element.foo)
|
115
116
|
end
|
116
117
|
|
117
118
|
def test_ref_node_collection_reading
|
118
|
-
xml = %Q(<Object><Top><RefElements><RefElement ref="http1" refObjectName="name1"/><RefElement ref="http2" refObjectName="name2"/></RefElements></Top></Object>)
|
119
|
+
xml = %Q(<Object ref="bla"><Top ref="bla"><RefElements><RefElement ref="http1" refObjectName="name1"/><RefElement ref="http2" refObjectName="name2"/></RefElements></Top></Object>)
|
119
120
|
# This will be the xml returned from read_rest
|
120
121
|
class << self
|
121
122
|
def read_xml
|
@@ -124,7 +125,7 @@ class RestObjectTestCase < Test::Unit::TestCase
|
|
124
125
|
end
|
125
126
|
|
126
127
|
assert_equal(2, rest_object(xml).top.ref_elements.length)
|
127
|
-
ref_element = rest_object(xml).top.ref_elements[
|
128
|
+
ref_element = rest_object(xml).top.ref_elements[0]
|
128
129
|
|
129
130
|
assert_equal("http1", ref_element.ref)
|
130
131
|
assert_equal("Desc", ref_element.description) # Force a read
|
@@ -132,7 +133,7 @@ class RestObjectTestCase < Test::Unit::TestCase
|
|
132
133
|
end
|
133
134
|
|
134
135
|
def test_ref_collection_with_dups_is_array
|
135
|
-
xml = %Q(<Object><Top><RefElements><RefElement ref="http1" refObjectName="name1"/><RefElement ref="http2" refObjectName="name2"/><RefElement ref="http3" refObjectName="name2"/><RefElement ref="http3" refObjectName="name2"/></RefElements></Top></Object>)
|
136
|
+
xml = %Q(<Object ref="bla"><Top ref="bla"><RefElements><RefElement ref="http1" refObjectName="name1"/><RefElement ref="http2" refObjectName="name2"/><RefElement ref="http3" refObjectName="name2"/><RefElement ref="http3" refObjectName="name2"/></RefElements></Top></Object>)
|
136
137
|
# This will be the xml returned from read_rest
|
137
138
|
class << self
|
138
139
|
def read_xml
|
@@ -140,24 +141,22 @@ class RestObjectTestCase < Test::Unit::TestCase
|
|
140
141
|
end
|
141
142
|
end
|
142
143
|
|
143
|
-
assert_equal(
|
144
|
-
assert_equal(Array, rest_object(xml).top.ref_elements["name2"].class)
|
145
|
-
assert_equal(3, rest_object(xml).top.ref_elements["name2"].length)
|
144
|
+
assert_equal(4, rest_object(xml).top.ref_elements.length)
|
146
145
|
end
|
147
146
|
|
148
147
|
def test_named_collection_reading
|
149
|
-
xml = %Q(<Object><Top><NamedElements><NamedElement ref="http1" refObjectName="name1"><Name>name1</Name></NamedElement><NamedElement ref="http2" refObjectName="name2"><Name>name2</Name></NamedElement></NamedElements></Top></Object>)
|
148
|
+
xml = %Q(<Object ref="bla"><Top ref="bla"><NamedElements><NamedElement ref="http1" refObjectName="name1"><Name>name1</Name></NamedElement><NamedElement ref="http2" refObjectName="name2"><Name>name2</Name></NamedElement></NamedElements></Top></Object>)
|
150
149
|
|
151
150
|
assert_equal(2, rest_object(xml).top.named_elements.length)
|
152
|
-
named_element1 = rest_object(xml).top.named_elements[
|
151
|
+
named_element1 = rest_object(xml).top.named_elements[0]
|
153
152
|
assert_equal("name1", named_element1.name)
|
154
153
|
|
155
|
-
named_element2 = rest_object(xml).top.named_elements[
|
154
|
+
named_element2 = rest_object(xml).top.named_elements[1]
|
156
155
|
assert_equal("name2", named_element2.name)
|
157
156
|
end
|
158
157
|
|
159
158
|
def test_unnamed_collection_reading
|
160
|
-
xml = %Q(<Object><Top><NamedElements><NamedElement ref="http1"><Name>name1</Name></NamedElement><NamedElement ref="http2"><Name>name2</Name></NamedElement></NamedElements></Top></Object>)
|
159
|
+
xml = %Q(<Object ref="bla"><Top ref="bla"><NamedElements><NamedElement ref="http1"><Name>name1</Name></NamedElement><NamedElement ref="http2"><Name>name2</Name></NamedElement></NamedElements></Top></Object>)
|
161
160
|
|
162
161
|
assert_equal(2, rest_object(xml).top.named_elements.length)
|
163
162
|
assert_equal("name1", rest_object(xml).top.named_elements[0].name)
|
data/test/tc_rest_query.rb
CHANGED
@@ -20,6 +20,10 @@ class TestRestQuery < Test::Unit::TestCase
|
|
20
20
|
def test_name_with_spaces
|
21
21
|
assert_equal("(Name = \"name name\")", RestQuery.query { equal :name, "name name"} )
|
22
22
|
end
|
23
|
+
|
24
|
+
def test_null_parameter
|
25
|
+
assert_equal("(Name = null)", RestQuery.query { equal :name, nil} )
|
26
|
+
end
|
23
27
|
|
24
28
|
def test_attribute_camelized
|
25
29
|
assert_equal("(IterationName != iteration)",
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rally_rest_api
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.6.
|
7
|
-
date:
|
6
|
+
version: 0.6.3
|
7
|
+
date: 2007-01-03 00:00:00 -07:00
|
8
8
|
summary: A ruby-ized interface to Rally's REST webservices API
|
9
9
|
require_paths:
|
10
10
|
- lib
|