1 // Copyright 2007 The Android Open Source Project 2 package com.android.providers.calendar; 3 4 import com.android.calendarcommon2.ICalendar; 5 6 import android.test.suitebuilder.annotation.SmallTest; 7 import junit.framework.TestCase; 8 9 import java.util.List; 10 11 public class ICalendarTest extends TestCase { 12 13 @SmallTest testAddParameter()14 public void testAddParameter() throws Exception { 15 ICalendar.Property prop = new ICalendar.Property("prop1", "value1"); 16 assertEquals(0, prop.getParameterNames().size()); 17 prop.addParameter(new ICalendar.Parameter("param1", "foo")); 18 assertEquals(1, prop.getParameterNames().size()); 19 prop.addParameter(new ICalendar.Parameter("param1", "bar")); 20 assertEquals(1, prop.getParameterNames().size()); 21 prop.addParameter(new ICalendar.Parameter("param2", "baaz")); 22 assertEquals(2, prop.getParameterNames().size()); 23 prop.addParameter(new ICalendar.Parameter("param1", "quux")); 24 assertEquals(2, prop.getParameterNames().size()); 25 prop.addParameter(new ICalendar.Parameter("param3", "accent")); 26 assertEquals(3, prop.getParameterNames().size()); 27 assertEquals("prop1;param1=foo;param1=bar;param1=quux;" 28 + "param2=baaz;param3=accent:value1", prop.toString()); 29 } 30 31 @SmallTest testAddProperty()32 public void testAddProperty() throws Exception { 33 String text = "BEGIN:DUMMY\n" + 34 "prop2:value3\n" + 35 "prop1:value1\n" + 36 "prop1:value2\n" + 37 "END:DUMMY\n"; 38 39 ICalendar.Component component = new ICalendar.Component("DUMMY", null); 40 // properties should be listed in insertion order, by property name. 41 component.addProperty(new ICalendar.Property("prop2", "value3")); 42 component.addProperty(new ICalendar.Property("prop1", "value1")); 43 component.addProperty(new ICalendar.Property("prop1", "value2")); 44 assertEquals(text, component.toString()); 45 } 46 47 @SmallTest testAddComponent()48 public void testAddComponent() throws Exception { 49 String text = "BEGIN:DUMMY\n" + 50 "prop1:value1\n" + 51 "prop1:value12\n" + 52 "BEGIN:DUMMY2\n" + 53 "prop2:value2\n" + 54 "END:DUMMY2\n" + 55 "END:DUMMY\n"; 56 57 ICalendar.Component parent = new ICalendar.Component("DUMMY", null); 58 // properties should precede components 59 ICalendar.Component child = new ICalendar.Component("DUMMY2", parent); 60 child.addProperty(new ICalendar.Property("prop2", "value2")); 61 parent.addChild(child); 62 parent.addProperty(new ICalendar.Property("prop1", "value1")); 63 parent.addProperty(new ICalendar.Property("prop1", "value12")); 64 assertEquals(text, parent.toString()); 65 } 66 67 @SmallTest testParseBasicComponent()68 public void testParseBasicComponent() throws Exception { 69 String text = "BEGIN:DUMMY\n" + 70 "PROP1;PARAM1=foo;PARAM2=bar:VALUE1\n" + 71 "PROP1;PARAM1=baaz;PARAM1=quux:VALUE2\n" + 72 "PROP2:VALUE3\n" + 73 "END:DUMMY\n"; 74 75 ICalendar.Component component = ICalendar.parseComponent(text); 76 77 assertEquals("DUMMY", component.getName()); 78 assertNull(component.getComponents()); 79 assertEquals(2, component.getPropertyNames().size()); 80 ICalendar.Property prop1 = component.getFirstProperty("PROP1"); 81 assertEquals(2, prop1.getParameterNames().size()); 82 assertEquals("foo", prop1.getFirstParameter("PARAM1").value); 83 assertEquals("bar", prop1.getFirstParameter("PARAM2").value); 84 List<ICalendar.Property> props = component.getProperties("PROP1"); 85 assertEquals(2, props.size()); 86 List<ICalendar.Parameter> params = props.get(1).getParameters("PARAM1"); 87 assertEquals("baaz", params.get(0).value); 88 assertEquals("quux", params.get(1).value); 89 } 90 91 @SmallTest testParseQuotedParam()92 public void testParseQuotedParam() throws Exception { 93 ICalendar.Component component 94 = new ICalendar.Component("DUMMY", null /* parent */); 95 ICalendar.parseComponent( 96 component, 97 "DTSTART;TZID=\"GMT+03:00\";TEST=test1;TEST=\"test2\":20101221T090000"); 98 ICalendar.Property property = component.getFirstProperty("DTSTART"); 99 assertEquals(2, property.getParameterNames().size()); 100 assertEquals("GMT+03:00", property.getFirstParameter("TZID").value); 101 final List<ICalendar.Parameter> testParameters = property.getParameters("TEST"); 102 assertEquals(2, testParameters.size()); 103 assertEquals("test1", testParameters.get(0).value); 104 assertEquals("test2", testParameters.get(1).value); 105 assertEquals("20101221T090000", component.getFirstProperty("DTSTART").getValue()); 106 } 107 108 @SmallTest testParseBadQuotedParam()109 public void testParseBadQuotedParam() throws Exception { 110 ICalendar.Component component 111 = new ICalendar.Component("DUMMY", null /* parent */); 112 113 ICalendar.parseComponent( 114 component, 115 "FOO;PARAM1=\"param1\"\";PARAM=quote-before-param:value"); 116 assertNull("Invalid quote before param value", component.getFirstProperty("FOO")); 117 118 ICalendar.parseComponent( 119 component, 120 "FOO;PARAM\"=expected-equal:value"); 121 assertNull("Expected equal in param", component.getFirstProperty("FOO")); 122 123 ICalendar.parseComponent( 124 component, 125 "FOO;PARAM=text-not-allowed\"before-quote:value"); 126 assertNull("Invalid quote in param value", component.getFirstProperty("FOO")); 127 128 ICalendar.parseComponent( 129 component, 130 "FOO;PARAM=\"missing-end-quote:value"); 131 assertNull("missing-end-quote", component.getFirstProperty("FOO")); 132 } 133 134 @SmallTest testParseChildComponent()135 public void testParseChildComponent() throws Exception { 136 String childText = "BEGIN:CHILD\n" + 137 "PROP1;PARAM1=foo;PARAM2=bar:VALUE1\n" + 138 "PROP1;PARAM1=baaz;PARAM1=quux:VALUE2\n" + 139 "PROP2:VALUE3\n" + 140 "END:CHILD\n"; 141 142 String completeText = "BEGIN:DUMMY\n" + 143 childText + 144 "END:DUMMY\n"; 145 146 ICalendar.Component component = new ICalendar.Component("DUMMY", null); 147 component = ICalendar.parseComponent(component, childText); 148 assertEquals("DUMMY", component.getName()); 149 assertEquals(1, component.getComponents().size()); 150 assertEquals(completeText, component.toString()); 151 } 152 153 @SmallTest testParseBareEvent()154 public void testParseBareEvent() throws Exception { 155 String text = "BEGIN:VEVENT\nEND:VEVENT\n"; 156 ICalendar.Component event = ICalendar.parseEvent(text); 157 158 assertEquals("VEVENT", event.getName()); 159 assertNull(event.getComponents()); 160 assertEquals(0, event.getPropertyNames().size()); 161 } 162 163 @SmallTest testParseEvent1()164 public void testParseEvent1() throws Exception { 165 String text = "BEGIN:VEVENT\n" + 166 "DTSTART:19970714T170000Z\n" + 167 "DTEND:19970715T035959Z\n" + 168 "SUMMARY:Bastille Day Party\n" + 169 "END:VEVENT\n"; 170 171 ICalendar.Component event = ICalendar.parseEvent(text); 172 173 assertEquals("VEVENT", event.getName()); 174 assertNull(event.getComponents()); 175 assertEquals(3, event.getPropertyNames().size()); 176 assertEquals(1, event.getProperties("DTSTART").size()); 177 assertEquals("19970714T170000Z", event.getFirstProperty("DTSTART").getValue()); 178 assertEquals(0, event.getFirstProperty("DTSTART").getParameterNames().size()); 179 assertEquals(1, event.getProperties("DTEND").size()); 180 assertEquals(0, event.getFirstProperty("DTEND").getParameterNames().size()); 181 assertEquals("19970715T035959Z", event.getFirstProperty("DTEND").getValue()); 182 assertEquals(1, event.getProperties("SUMMARY").size()); 183 assertEquals(0, event.getFirstProperty("SUMMARY").getParameterNames().size()); 184 assertEquals("Bastille Day Party", event.getFirstProperty("SUMMARY").getValue()); 185 } 186 187 @SmallTest testParseEvent2()188 public void testParseEvent2() throws Exception { 189 String text = "BEGIN:VEVENT\n" + 190 "DTSTART;TZID=America/Los_Angeles:19970714T170000\n" + 191 "DURATION:+P3600S\n" + 192 "SUMMARY;FOO=1;BAR=2:Bastille Day Party\n" + 193 "END:VEVENT\n"; 194 195 ICalendar.Component event = ICalendar.parseEvent(text); 196 197 assertEquals("VEVENT", event.getName()); 198 assertNull(event.getComponents()); 199 assertEquals(3, event.getPropertyNames().size()); 200 assertEquals(1, event.getProperties("DTSTART").size()); 201 assertEquals("19970714T170000", event.getFirstProperty("DTSTART").getValue()); 202 assertEquals(1, event.getFirstProperty("DTSTART").getParameterNames().size()); 203 assertEquals(1, event.getProperties("SUMMARY").size()); 204 } 205 206 @SmallTest testParseInvalidProperty()207 public void testParseInvalidProperty() throws Exception { 208 String text = "BEGIN:VEVENT\n" + 209 "FOO;BAR\n" + // invalid line 210 "END:VEVENT\n"; 211 212 ICalendar.Component event = ICalendar.parseEvent(text); 213 214 assertEquals("VEVENT", event.getName()); 215 assertNull(event.getComponents()); 216 assertEquals(0, event.getPropertyNames().size()); 217 } 218 219 @SmallTest testParseEventDoesNotStartWithBegin()220 public void testParseEventDoesNotStartWithBegin() throws Exception { 221 String text = "NOTBEGIN:DUMMY\n" + 222 "END:DUMMY\n"; 223 224 try { 225 ICalendar.parseEvent(text); 226 fail("expected exception not thrown"); 227 } catch (ICalendar.FormatException e) { 228 assertEquals("Expected " + ICalendar.Component.VEVENT, e.getMessage()); 229 } 230 } 231 232 @SmallTest testParseCalendarDoesNotStartWithBegin()233 public void testParseCalendarDoesNotStartWithBegin() throws Exception { 234 String text = "NOTBEGIN:DUMMY\n" + 235 "END:DUMMY\n"; 236 237 try { 238 ICalendar.parseCalendar(text); 239 fail("expected exception not thrown"); 240 } catch (ICalendar.FormatException e) { 241 assertEquals("Expected " + ICalendar.Component.VCALENDAR, e.getMessage()); 242 } 243 } 244 245 @SmallTest testParseComponentDoesNotStartWithBegin()246 public void testParseComponentDoesNotStartWithBegin() throws Exception { 247 String text = "NOTBEGIN:DUMMY\n" + 248 "END:DUMMY\n"; 249 250 ICalendar.Component component = ICalendar.parseComponent(text); 251 assertNull(component); 252 } 253 254 @SmallTest testParseUnexpectedEndComponent()255 public void testParseUnexpectedEndComponent() throws Exception { 256 String text = "BEGIN:PARENT\n" + 257 "END:BADPARENT\n"; 258 259 ICalendar.Component component = ICalendar.parseComponent(text); 260 assertNotNull(component); 261 } 262 263 @SmallTest testParseNoEndComponent()264 public void testParseNoEndComponent() throws Exception { 265 String text = "BEGIN:DUMMY\n" + 266 "END:\n"; 267 268 ICalendar.Component component = ICalendar.parseComponent(text); 269 assertNotNull(component); 270 } 271 272 @SmallTest testNormalize()273 public void testNormalize() throws Exception { 274 String text = "BEGIN:VEVENT\n" + 275 "RRULE:FREQ=SECONDLY;BYSECOND=0,1,2,\r\n 3,4,5\r\n ,6,7,8\r\n" + 276 "END:VEVENT\n"; 277 278 ICalendar.Component event = ICalendar.parseEvent(text); 279 280 assertEquals("VEVENT", event.getName()); 281 assertNull(event.getComponents()); 282 assertEquals(1, event.getPropertyNames().size()); 283 assertEquals(1, event.getProperties("RRULE").size()); 284 assertEquals("FREQ=SECONDLY;BYSECOND=0,1,2,3,4,5,6,7,8", event.getFirstProperty("RRULE").getValue()); 285 286 } 287 288 @SmallTest testNormalizeBadSep()289 public void testNormalizeBadSep() throws Exception { 290 String text = "BEGIN:VEVENT\n" + 291 "RRULE:FREQ=SECONDLY;BYSECOND=0,1,2,\n 3,4,5\n ,6,7,8\n" + 292 "END:VEVENT\n"; 293 294 ICalendar.Component event = ICalendar.parseEvent(text); 295 296 assertEquals("VEVENT", event.getName()); 297 assertNull(event.getComponents()); 298 assertEquals(1, event.getPropertyNames().size()); 299 assertEquals(1, event.getProperties("RRULE").size()); 300 assertEquals("FREQ=SECONDLY;BYSECOND=0,1,2,3,4,5,6,7,8", event.getFirstProperty("RRULE").getValue()); 301 } 302 303 304 @SmallTest testBad()305 public void testBad() throws Exception { 306 String text = "BEGIN:VEVENT\n" + 307 "RRULE=foo\n" + 308 "END:VEVENT\n"; 309 310 ICalendar.Component event = ICalendar.parseEvent(text); 311 312 // Note that parseEvent doesn't throw the FormatException you might expect because 313 // ICalendar.parseComponentImpl catches the exception due to misformatted GData. 314 // TODO: update this test after cleaning up the ICalendar behavior 315 } 316 } 317