PageRenderTime 83ms CodeModel.GetById 16ms app.highlight 63ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/update-engine/externals/gdata-objectivec-client/Source/Tests/GDataXMLSupportTest.m

http://macfuse.googlecode.com/
Objective C | 304 lines | 186 code | 63 blank | 55 comment | 6 complexity | d0130072d59f87ecb439b14904b9ddf5 MD5 | raw file
  1/* Copyright (c) 2008 Google Inc.
  2*
  3* Licensed under the Apache License, Version 2.0 (the "License");
  4* you may not use this file except in compliance with the License.
  5* You may obtain a copy of the License at
  6*
  7*     http://www.apache.org/licenses/LICENSE-2.0
  8*
  9* Unless required by applicable law or agreed to in writing, software
 10* distributed under the License is distributed on an "AS IS" BASIS,
 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12* See the License for the specific language governing permissions and
 13* limitations under the License.
 14*/
 15
 16//
 17//  GDataXMLSupportTest.m
 18//
 19
 20#import <SenTestingKit/SenTestingKit.h>
 21
 22#import "GData/GData.h"
 23
 24#import "GDataXMLNode.h"
 25
 26@interface GDataXMLSupportTest : SenTestCase
 27@end
 28
 29@implementation GDataXMLSupportTest
 30
 31- (void)runNodesAndNamespacesTestUsingShim:(BOOL)shouldUseShim {
 32
 33  NSLog(@"Nodes and ns test %@ shim", shouldUseShim ? @"with" : @"without");
 34
 35  // since we don't want the GDataDefines macros to replace NSXMLNode
 36  // with GDataXMLNode, we'll use strings to make the classes
 37  Class cXMLNode = NSClassFromString(shouldUseShim ?
 38                                     @"GDataXMLNode" : @"NSXMLNode");
 39  Class cXMLElement = NSClassFromString(shouldUseShim ?
 40                                        @"GDataXMLElement" : @"NSXMLElement");
 41
 42  // create elements and attributes
 43
 44  // create with URI and local name
 45  NSXMLElement *attr1 = [cXMLElement attributeWithName:@"foo"
 46                                                   URI:kGDataNamespaceGData
 47                                           stringValue:@"baz"];
 48  NSXMLElement *child1 = [cXMLElement elementWithName:@"chyld"
 49                                                  URI:kGDataNamespaceGData];
 50  [child1 setStringValue:@"fuzz"];
 51
 52  // create with URI and prefix
 53  NSXMLElement *attr2 = [cXMLElement attributeWithName:@"openSearch:foo"
 54                                           stringValue:@"baz2"];
 55  NSXMLElement *child2 = [cXMLElement elementWithName:@"openSearch:chyld"];
 56  [child2 setStringValue:@"fuzz2"];
 57
 58  // create with unqualified local name
 59  NSXMLElement *child3 = [cXMLElement elementWithName:@"chyld"];
 60  [child3 setStringValue:@"fuzz3"];
 61
 62  NSXMLElement *child3temp = nil;
 63  if (shouldUseShim) {
 64    // create a child we'll later remove (GDataXMLElement API only)
 65    child3temp = [cXMLElement elementWithName:@"childTemp"];
 66    [child3temp setStringValue:@"scorch"];
 67  }
 68
 69  // create with a missing namespace URI that we'll never actually add,
 70  // so we can test searches based on our faked use of {uri}: as
 71  // a prefix for the local name
 72  NSXMLElement *attr4 = [cXMLElement attributeWithName:@"zorgbot"
 73                                                   URI:kGDataNamespaceBatch
 74                                           stringValue:@"gollyfum"];
 75  NSXMLElement *child4 = [cXMLElement elementWithName:@"zorgtree"
 76                                                  URI:kGDataNamespaceBatch];
 77  [child4 setStringValue:@"gollyfoo"];
 78
 79  // create an element with a local namespace not defined in the parent level
 80  NSString *lonerURI = @"http://loner.ns";
 81  NSXMLElement *child5 = [cXMLElement elementWithName:@"ln:loner"
 82                                                  URI:lonerURI];
 83  NSXMLNode *ns5 = [cXMLNode namespaceWithName:@"ln"
 84                                   stringValue:lonerURI];
 85  [child5 addNamespace:ns5];
 86
 87  // add these to a parent element, along with namespaces
 88  NSXMLElement *parent = [cXMLElement elementWithName:@"dad"];
 89  [parent setStringValue:@"buzz"];
 90
 91  // atom is the default namespace
 92  NSXMLNode *nsAtom = [cXMLNode namespaceWithName:@""
 93                                      stringValue:kGDataNamespaceAtom];
 94  [parent addNamespace:nsAtom];
 95
 96  NSXMLNode *nsGD = [cXMLNode namespaceWithName:@"gd"
 97                                    stringValue:kGDataNamespaceGData];
 98  [parent addNamespace:nsGD];
 99
100  NSXMLNode *nsOpenSearch = [cXMLNode namespaceWithName:@"openSearch"
101                                            stringValue:kGDataNamespaceOpenSearch];
102  [parent addNamespace:nsOpenSearch];
103
104  [parent addChild:child1];
105  [parent addAttribute:attr1];
106  [parent addChild:child2];
107  [parent addAttribute:attr2];
108  [parent addChild:child3];
109  if (shouldUseShim) {
110    [parent addChild:child3temp];
111  }
112
113  [parent addChild:child4];
114  [parent addAttribute:attr4];
115  [parent addChild:child5];
116
117  if (shouldUseShim) {
118    // remove the temp child; we must obtain it from the tree, not use
119    // the copy we added above
120    NSArray *childrenToRemove = [parent elementsForName:@"childTemp"];
121    STAssertEquals((int)[childrenToRemove count], 1, @"childTemp not found");
122
123    GDataXMLNode *childToRemove = [childrenToRemove objectAtIndex:0];
124    [(GDataXMLElement *)parent removeChild:childToRemove];
125
126    childrenToRemove = [parent elementsForName:@"childTemp"];
127    STAssertEquals((int)[childrenToRemove count], 0, @"childTemp still found");
128  }
129
130  // search for attr1 and child1 by qualified name, since they were
131  // created by URI
132  NSXMLNode *attr1Found = [parent attributeForName:@"gd:foo"];
133  STAssertEqualObjects([attr1Found stringValue], @"baz", @"attribute gd:foo");
134
135  NSArray *elements = [parent elementsForName:@"gd:chyld"];
136  STAssertEquals((int)[elements count], 1, @"getting gd:chyld");
137  NSXMLNode *child1Found = [elements objectAtIndex:0];
138  STAssertEqualObjects([child1Found stringValue], @"fuzz", @"child gd:chyld");
139
140  // search for attr2 and child2 by local name and URI, since they were
141  // created by qualified names
142  NSXMLNode *attr2Found = [parent attributeForLocalName:@"foo"
143                                                    URI:kGDataNamespaceOpenSearch];
144  STAssertEqualObjects([attr2Found stringValue], @"baz2", @"attribute openSearch:foo");
145
146  NSArray *elements2 = [parent elementsForLocalName:@"chyld"
147                                                URI:kGDataNamespaceOpenSearch];
148
149  STAssertEquals((int)[elements2 count], 1, @"getting openSearch:chyld");
150  NSXMLNode *child2Found = [elements2 objectAtIndex:0];
151  STAssertEqualObjects([child2Found stringValue], @"fuzz2", @"child openSearch:chyld");
152
153  // search for child3 by local name
154  NSArray *elements3 = [parent elementsForName:@"chyld"];
155  STAssertEquals((int)[elements3 count], 1, @"getting chyld");
156  NSXMLNode *child3Found = [elements3 objectAtIndex:0];
157  STAssertEqualObjects([child3Found stringValue], @"fuzz3", @"child chyld");
158
159  // search for child3 by URI
160  NSArray *elements3a = [parent elementsForLocalName:@"chyld"
161                                                 URI:kGDataNamespaceAtom];
162  STAssertEquals((int)[elements3a count], 1, @"getting chyld (URI");
163  NSXMLNode *child3aFound = [elements3 objectAtIndex:0];
164  STAssertEqualObjects([child3aFound stringValue], @"fuzz3", @"child chyld");
165
166  // search for attr4 and child4 by local name and URI, since they were
167  // created by URI and never bound to a prefix by a namespace declaration
168  NSXMLNode *attr4Found = [parent attributeForLocalName:@"zorgbot"
169                                                    URI:kGDataNamespaceBatch];
170  STAssertEqualObjects([attr4Found stringValue], @"gollyfum", @"in test batch zorgbot");
171
172  NSArray *elements4 = [parent elementsForLocalName:@"zorgtree"
173                                                URI:kGDataNamespaceBatch];
174  STAssertEquals((int)[elements4 count], 1, @"getting batch zorgtree");
175  NSXMLNode *child4Found = [elements4 objectAtIndex:0];
176  STAssertEqualObjects([child4Found stringValue], @"gollyfoo", @"in test batch zorgtree");
177
178  // search for child 5 by local name and URI, since it has a locally-defined
179  // namespace
180  NSArray *elements5 = [parent elementsForLocalName:@"loner"
181                                                URI:lonerURI];
182  STAssertEquals((int)[elements5 count], 1, @"getting loner");
183
184  // test output
185  NSString *expectedXML;
186  if (shouldUseShim) {
187    expectedXML = @"<dad xmlns=\"http://www.w3.org/2005/Atom\" "
188    "xmlns:gd=\"http://schemas.google.com/g/2005\" "
189    "xmlns:openSearch=\"http://a9.com/-/spec/opensearch/1.1/\" "
190    "gd:foo=\"baz\" openSearch:foo=\"baz2\" "
191    "{http://schemas.google.com/gdata/batch}:zorgbot=\"gollyfum\">"
192    "buzz<gd:chyld>fuzz</gd:chyld><openSearch:chyld>fuzz2</openSearch:chyld>"
193    "<chyld>fuzz3</chyld><{http://schemas.google.com/gdata/batch}:zorgtree>"
194    "gollyfoo</{http://schemas.google.com/gdata/batch}:zorgtree>"
195    "<ln:loner xmlns:ln=\"http://loner.ns\"/></dad>";
196  } else {
197    expectedXML = @"<dad xmlns=\"http://www.w3.org/2005/Atom\" "
198    "xmlns:gd=\"http://schemas.google.com/g/2005\" "
199    "xmlns:openSearch=\"http://a9.com/-/spec/opensearch/1.1/\" "
200    "foo=\"baz\" openSearch:foo=\"baz2\" zorgbot=\"gollyfum\">"
201    "buzz<chyld>fuzz</chyld><openSearch:chyld>fuzz2</openSearch:chyld>"
202    "<chyld>fuzz3</chyld><zorgtree>gollyfoo</zorgtree>"
203    "<ln:loner xmlns:ln=\"http://loner.ns\"></ln:loner></dad>";
204  }
205
206  NSString *actualXML = [parent XMLString];
207  STAssertEqualObjects(actualXML, expectedXML, @"unexpected xml output");
208}
209
210
211- (void)testNodesAndNamespaces {
212  [self runNodesAndNamespacesTestUsingShim:NO];
213  [self runNodesAndNamespacesTestUsingShim:YES];
214}
215
216- (void)runXPathTestUsingShim:(BOOL)shouldUseShim {
217
218  NSLog(@"XPath test %@ shim", shouldUseShim ? @"with" : @"without");
219
220  // since we don't want the GDataDefines macros to replace NSXMLDocument
221  // with GDataXMLDocument, we'll use strings to make the classes
222  Class cXMLDocument = NSClassFromString(shouldUseShim ?
223                                       @"GDataXMLDocument" : @"NSXMLDocument");
224
225  // read in a big feed
226  NSError *error = nil;
227  NSStringEncoding encoding = 0;
228
229  NSString *contactFeedXML = [NSString stringWithContentsOfFile:@"Tests/FeedContactTest1.xml"
230                                                   usedEncoding:&encoding
231                                                          error:&error];
232  NSData *data = [contactFeedXML dataUsingEncoding:NSUTF8StringEncoding];
233
234  NSXMLDocument *xmlDocument;
235
236  xmlDocument = [[(NSXMLDocument *)[cXMLDocument alloc] initWithData:data
237                                                              options:0
238                                                                error:&error] autorelease];
239  STAssertNotNil(xmlDocument, @"could not allocate feed from xml");
240  STAssertNil(error, @"error allocating feed from xml");
241
242  // I'd like to test namespace-uri here, too, but that fails in NSXML's XPath
243  NSXMLElement *root = [xmlDocument rootElement];
244  NSString *path = @"*[local-name()='category']";
245
246  NSArray *nodes = [root nodesForXPath:path error:&error];
247  STAssertEquals((int)[nodes count], 1, @"XPath count");
248  STAssertNil(error, @"XPath error");
249
250  if (shouldUseShim) {
251    // NSXML's XPath doesn't seem to deal with URI's properly
252
253    // find elements with the default namespace URI
254    path = @"*[namespace-uri()='http://www.w3.org/2005/Atom']";
255
256    nodes = [root nodesForXPath:path error:&error];
257
258    STAssertEquals((int)[nodes count], 10, @"XPath count for default ns");
259    STAssertNil(error, @"XPath error");
260
261    // find elements with a non-default namespace URI
262    path = @"*[namespace-uri()='http://a9.com/-/spec/opensearch/1.1/']";
263
264    // find the opensearch nodes
265    nodes = [root nodesForXPath:path error:&error];
266
267    STAssertEquals((int)[nodes count], 3, @"XPath count for opensearch ns");
268    STAssertNil(error, @"XPath error");
269
270    // find nodes with the default atom namespace
271    path = @"_def_ns:entry/_def_ns:link"; // four entry link nodes
272    nodes = [root nodesForXPath:path error:&error];
273
274    STAssertEquals((int)[nodes count], 4, @"XPath count for default ns nodes");
275    STAssertNil(error, @"XPath error");
276
277    // find nodes with an explicit atom namespace
278    path = @"atom:entry/atom:link"; // four entry link nodes
279    NSDictionary *nsDict = [NSDictionary dictionaryWithObject:kGDataNamespaceAtom
280                                                       forKey:kGDataNamespaceAtomPrefix];
281    nodes = [(GDataXMLNode *)root nodesForXPath:path
282                                     namespaces:nsDict
283                                          error:&error];
284
285    STAssertEquals((int)[nodes count], 4, @"XPath count for atom ns nodes");
286    STAssertNil(error, @"XPath error");
287
288    // test an illegal path string
289    GDataXMLNode *emptyNode = [GDataXMLElement elementWithName:@"Abcde"];
290    nodes = [emptyNode nodesForXPath:@""
291                          namespaces:nsDict
292                               error:&error];
293    // libxml provides error code 1207 for this
294    STAssertEquals([error code], (NSInteger)1207, @"error on invalid XPath: %@", error);
295  }
296}
297
298- (void)testXPath {
299  [self runXPathTestUsingShim:NO];
300  [self runXPathTestUsingShim:YES];
301}
302
303@end
304