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.
@@ -72,4 +72,10 @@ class QueryResult < RestObject
72
72
  return false if start_index == 0
73
73
  (self.start_index + self.page_length) -1 < self.total_result_count
74
74
  end
75
+
76
+ protected
77
+ def parse_collections_as_hash?
78
+ false
79
+ end
80
+
75
81
  end
@@ -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
- puts "RestBuilder#create_rest artifact_type = #{type}" if DEBUG
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
- puts "RestBuilder#update_rest url = #{url}" if DEBUG
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
- puts "RestBuilder#read_rest ref_url = #{ref_url} username = #{ username } pass = #{ password }" if DEBUG
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
- puts "RestBuilder#delete_rest ref_url = #{ref_url} username = #{ username } pass = #{ password }" if DEBUG
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
- puts "RestBuilder#post_xml xml = #{xml} as user #{ self.username } pass = #{ self.password }" if DEBUG
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
- puts "RestBuilder#send_request req = #{req.inspect}" if DEBUG
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
- puts "RestBuilder#send_request result = #{body}" if DEBUG
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
- puts "parse self = #{self.object_id} node = #{ node.to_s }" if DEBUG
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
- puts "Returning RestObject for #{ node.to_s}" if DEBUG
44
+ debug "Returning RestObject for #{ node.to_s}"
47
45
  return RestObject.new(@rally_rest, node.to_s)
48
46
  else
49
- puts "Returning text #{ node.text }" if DEBUG
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
- puts "Looking at name = #{ name }" if DEBUG
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
- puts "NilClass name = #{ name }" if DEBUG
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
- puts "Named collection #{ name }" if DEBUG
75
- elements[name] = {} # We might want to decorate {} here to handle scoping
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 unnamed_collection?(e)
86
- puts "UnNamed collection #{ name }" if DEBUG
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
- puts "Fully Dressed object, without a name #{ name }" if DEBUG
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
- puts "Array name = #{ name }" if DEBUG
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
- puts "creating and wrapping #{elements[name]}with an array name = #{ name }" if DEBUG
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
- mangle_type_definitions(workspace.type_definitions)
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,7 +2,7 @@ module RallyRestVersion #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 6
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  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
@@ -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
@@ -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.should == 1
73
- @typedef.custom_dropdown_attributes.size.should == 1
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
@@ -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.use_case(:name_name => "name")
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.use_case(:name => nil)
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.use_case(:time => time)
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.feature(:use_case => rest_object)
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.feature(:dependents => uc1)
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.feature(:dependents => [uc1, uc2])
95
+ @api.create(:feature, :dependents => [uc1, uc2])
96
96
  assert_equal(xml, @xml)
97
97
  end
98
98
 
@@ -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><Top><RefElement ref="http" refObjectName="name1"/></Top></Object>)
102
- assert_equal(RestObject, rest_object(xml).top['name1'].class)
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['name1'].foo)
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["name1"]
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(2, rest_object(xml).top.ref_elements.length)
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["name1"]
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["name2"]
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)
@@ -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.2
7
- date: 2006-12-18 00:00:00 -07:00
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